Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F142361789
D24525.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D24525.diff
View Options
Index: head/lib/libvmmapi/vmmapi.h
===================================================================
--- head/lib/libvmmapi/vmmapi.h
+++ head/lib/libvmmapi/vmmapi.h
@@ -35,6 +35,8 @@
#include <sys/cpuset.h>
#include <machine/vmm_dev.h>
+#include <stdbool.h>
+
/*
* API version for out-of-tree consumers like grub-bhyve for making compile
* time decisions.
@@ -156,6 +158,8 @@
int vm_ioapic_deassert_irq(struct vmctx *ctx, int irq);
int vm_ioapic_pulse_irq(struct vmctx *ctx, int irq);
int vm_ioapic_pincount(struct vmctx *ctx, int *pincount);
+int vm_readwrite_kernemu_device(struct vmctx *ctx, int vcpu,
+ vm_paddr_t gpa, bool write, int size, uint64_t *value);
int vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq);
int vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq);
int vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq);
Index: head/lib/libvmmapi/vmmapi.c
===================================================================
--- head/lib/libvmmapi/vmmapi.c
+++ head/lib/libvmmapi/vmmapi.c
@@ -799,6 +799,25 @@
}
int
+vm_readwrite_kernemu_device(struct vmctx *ctx, int vcpu, vm_paddr_t gpa,
+ bool write, int size, uint64_t *value)
+{
+ struct vm_readwrite_kernemu_device irp = {
+ .vcpuid = vcpu,
+ .access_width = fls(size) - 1,
+ .gpa = gpa,
+ .value = write ? *value : ~0ul,
+ };
+ long cmd = (write ? VM_SET_KERNEMU_DEV : VM_GET_KERNEMU_DEV);
+ int rc;
+
+ rc = ioctl(ctx->fd, cmd, &irp);
+ if (rc == 0 && !write)
+ *value = irp.value;
+ return (rc);
+}
+
+int
vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq)
{
struct vm_isa_irq isa_irq;
@@ -1615,6 +1634,7 @@
VM_MMAP_GETNEXT, VM_SET_REGISTER, VM_GET_REGISTER,
VM_SET_SEGMENT_DESCRIPTOR, VM_GET_SEGMENT_DESCRIPTOR,
VM_SET_REGISTER_SET, VM_GET_REGISTER_SET,
+ VM_SET_KERNEMU_DEV, VM_GET_KERNEMU_DEV,
VM_INJECT_EXCEPTION, VM_LAPIC_IRQ, VM_LAPIC_LOCAL_IRQ,
VM_LAPIC_MSI, VM_IOAPIC_ASSERT_IRQ, VM_IOAPIC_DEASSERT_IRQ,
VM_IOAPIC_PULSE_IRQ, VM_IOAPIC_PINCOUNT, VM_ISA_ASSERT_IRQ,
Index: head/sys/amd64/include/vmm_dev.h
===================================================================
--- head/sys/amd64/include/vmm_dev.h
+++ head/sys/amd64/include/vmm_dev.h
@@ -235,6 +235,15 @@
uint16_t maxcpus;
};
+struct vm_readwrite_kernemu_device {
+ int vcpuid;
+ unsigned access_width : 3;
+ unsigned _unused : 29;
+ uint64_t gpa;
+ uint64_t value;
+};
+_Static_assert(sizeof(struct vm_readwrite_kernemu_device) == 24, "ABI");
+
enum {
/* general routines */
IOCNUM_ABIVERS = 0,
@@ -262,6 +271,8 @@
IOCNUM_GET_SEGMENT_DESCRIPTOR = 23,
IOCNUM_SET_REGISTER_SET = 24,
IOCNUM_GET_REGISTER_SET = 25,
+ IOCNUM_GET_KERNEMU_DEV = 26,
+ IOCNUM_SET_KERNEMU_DEV = 27,
/* interrupt injection */
IOCNUM_GET_INTINFO = 28,
@@ -347,6 +358,12 @@
_IOW('v', IOCNUM_SET_REGISTER_SET, struct vm_register_set)
#define VM_GET_REGISTER_SET \
_IOWR('v', IOCNUM_GET_REGISTER_SET, struct vm_register_set)
+#define VM_SET_KERNEMU_DEV \
+ _IOW('v', IOCNUM_SET_KERNEMU_DEV, \
+ struct vm_readwrite_kernemu_device)
+#define VM_GET_KERNEMU_DEV \
+ _IOWR('v', IOCNUM_GET_KERNEMU_DEV, \
+ struct vm_readwrite_kernemu_device)
#define VM_INJECT_EXCEPTION \
_IOW('v', IOCNUM_INJECT_EXCEPTION, struct vm_exception)
#define VM_LAPIC_IRQ \
Index: head/sys/amd64/vmm/vmm_dev.c
===================================================================
--- head/sys/amd64/vmm/vmm_dev.c
+++ head/sys/amd64/vmm/vmm_dev.c
@@ -58,6 +58,7 @@
#include <machine/vmm_dev.h>
#include <machine/vmm_instruction_emul.h>
#include <machine/vmm_snapshot.h>
+#include <x86/apicreg.h>
#include "vmm_lapic.h"
#include "vmm_stat.h"
@@ -382,6 +383,7 @@
struct vm_rtc_data *rtcdata;
struct vm_memmap *mm;
struct vm_cpu_topology *topology;
+ struct vm_readwrite_kernemu_device *kernemu;
uint64_t *regvals;
int *regnums;
#ifdef BHYVE_SNAPSHOT
@@ -561,6 +563,41 @@
case VM_IOAPIC_PINCOUNT:
*(int *)data = vioapic_pincount(sc->vm);
break;
+ case VM_SET_KERNEMU_DEV:
+ case VM_GET_KERNEMU_DEV: {
+ mem_region_write_t mwrite;
+ mem_region_read_t mread;
+ bool arg;
+
+ kernemu = (void *)data;
+
+ if (kernemu->access_width > 0)
+ size = (1u << kernemu->access_width);
+ else
+ size = 1;
+
+ if (kernemu->gpa >= DEFAULT_APIC_BASE && kernemu->gpa < DEFAULT_APIC_BASE + PAGE_SIZE) {
+ mread = lapic_mmio_read;
+ mwrite = lapic_mmio_write;
+ } else if (kernemu->gpa >= VIOAPIC_BASE && kernemu->gpa < VIOAPIC_BASE + VIOAPIC_SIZE) {
+ mread = vioapic_mmio_read;
+ mwrite = vioapic_mmio_write;
+ } else if (kernemu->gpa >= VHPET_BASE && kernemu->gpa < VHPET_BASE + VHPET_SIZE) {
+ mread = vhpet_mmio_read;
+ mwrite = vhpet_mmio_write;
+ } else {
+ error = EINVAL;
+ break;
+ }
+
+ if (cmd == VM_SET_KERNEMU_DEV)
+ error = mwrite(sc->vm, kernemu->vcpuid, kernemu->gpa,
+ kernemu->value, size, &arg);
+ else
+ error = mread(sc->vm, kernemu->vcpuid, kernemu->gpa,
+ &kernemu->value, size, &arg);
+ break;
+ }
case VM_ISA_ASSERT_IRQ:
isa_irq = (struct vm_isa_irq *)data;
error = vatpic_assert_irq(sc->vm, isa_irq->atpic_irq);
Index: head/usr.sbin/bhyve/Makefile
===================================================================
--- head/usr.sbin/bhyve/Makefile
+++ head/usr.sbin/bhyve/Makefile
@@ -31,6 +31,7 @@
hda_codec.c \
inout.c \
ioapic.c \
+ kernemu_dev.c \
mem.c \
mevent.c \
mptbl.c \
@@ -75,6 +76,8 @@
.if ${MK_BHYVE_SNAPSHOT} != "no"
SRCS+= snapshot.c
.endif
+
+CFLAGS.kernemu_dev.c+= -I${SRCTOP}/sys/amd64
.PATH: ${BHYVE_SYSDIR}/sys/amd64/vmm
SRCS+= vmm_instruction_emul.c
Index: head/usr.sbin/bhyve/bhyverun.c
===================================================================
--- head/usr.sbin/bhyve/bhyverun.c
+++ head/usr.sbin/bhyve/bhyverun.c
@@ -92,6 +92,7 @@
#include "fwctl.h"
#include "gdb.h"
#include "ioapic.h"
+#include "kernemu_dev.h"
#include "mem.h"
#include "mevent.h"
#include "mptbl.h"
@@ -1268,6 +1269,7 @@
init_mem();
init_inout();
+ kernemu_dev_init();
init_bootrom(ctx);
atkbdc_init(ctx);
pci_irq_init(ctx);
Index: head/usr.sbin/bhyve/kernemu_dev.h
===================================================================
--- head/usr.sbin/bhyve/kernemu_dev.h
+++ head/usr.sbin/bhyve/kernemu_dev.h
@@ -0,0 +1,32 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright 2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#pragma once
+
+void kernemu_dev_init(void);
Index: head/usr.sbin/bhyve/kernemu_dev.c
===================================================================
--- head/usr.sbin/bhyve/kernemu_dev.c
+++ head/usr.sbin/bhyve/kernemu_dev.c
@@ -0,0 +1,98 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright 2020 Conrad Meyer <cem@FreeBSD.org>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/tree.h>
+
+#include <amd64/include/vmm.h>
+#include <x86/include/apicreg.h>
+struct vm;
+struct vm_hpet_cap;
+#include <vmm/io/vioapic.h>
+#include <vmm/io/vhpet.h>
+
+#include <err.h>
+#include <errno.h>
+#include <vmmapi.h>
+
+#include "kernemu_dev.h"
+#include "mem.h"
+
+static int
+apic_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, int size,
+ uint64_t *val, void *arg1 __unused, long arg2 __unused)
+{
+ if (vm_readwrite_kernemu_device(ctx, vcpu, addr, (dir == MEM_F_WRITE),
+ size, val) != 0)
+ return (errno);
+ return (0);
+}
+
+static struct mem_range lapic_mmio = {
+ .name = "kern-lapic-mmio",
+ .base = DEFAULT_APIC_BASE,
+ .size = PAGE_SIZE,
+ .flags = MEM_F_RW | MEM_F_IMMUTABLE,
+ .handler = apic_handler,
+
+};
+static struct mem_range ioapic_mmio = {
+ .name = "kern-ioapic-mmio",
+ .base = VIOAPIC_BASE,
+ .size = VIOAPIC_SIZE,
+ .flags = MEM_F_RW | MEM_F_IMMUTABLE,
+ .handler = apic_handler,
+};
+static struct mem_range hpet_mmio = {
+ .name = "kern-hpet-mmio",
+ .base = VHPET_BASE,
+ .size = VHPET_SIZE,
+ .flags = MEM_F_RW | MEM_F_IMMUTABLE,
+ .handler = apic_handler,
+};
+
+void
+kernemu_dev_init(void)
+{
+ int rc;
+
+ rc = register_mem(&lapic_mmio);
+ if (rc != 0)
+ errc(4, rc, "register_mem: LAPIC (0x%08x)",
+ (unsigned)lapic_mmio.base);
+ rc = register_mem(&ioapic_mmio);
+ if (rc != 0)
+ errc(4, rc, "register_mem: IOAPIC (0x%08x)",
+ (unsigned)ioapic_mmio.base);
+ rc = register_mem(&hpet_mmio);
+ if (rc != 0)
+ errc(4, rc, "register_mem: HPET (0x%08x)",
+ (unsigned)hpet_mmio.base);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 20, 2:11 AM (9 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27757749
Default Alt Text
D24525.diff (10 KB)
Attached To
Mode
D24525: vmm(4), bhyve(8): Expose kernel-emulated special devices to userspace
Attached
Detach File
Event Timeline
Log In to Comment