socsvn commit: r307050 - in soc2016/vincenzo/head: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/modules/vmm
vincenzo at FreeBSD.org
vincenzo at FreeBSD.org
Mon Aug 1 08:01:12 UTC 2016
Author: vincenzo
Date: Mon Aug 1 08:01:05 2016
New Revision: 307050
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307050
Log:
vmm: add support needed for ptnetmap
Modified:
soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c
soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h
soc2016/vincenzo/head/sys/amd64/include/vmm.h
soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h
soc2016/vincenzo/head/sys/amd64/vmm/vmm.c
soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c
soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c
soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h
soc2016/vincenzo/head/sys/modules/vmm/Makefile
Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c
==============================================================================
--- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 08:01:05 2016 (r307050)
@@ -883,6 +883,42 @@
}
int
+vm_get_fd(struct vmctx *ctx)
+{
+ return (ctx->fd);
+}
+
+int
+vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf)
+{
+ struct vm_user_buf user_buf;
+
+ bzero(&user_buf, sizeof(user_buf));
+ user_buf.gpa = gpa;
+ user_buf.len = len;
+ user_buf.addr = host_buf;
+
+ return (ioctl(ctx->fd, VM_MAP_USER_BUF, &user_buf));
+}
+
+int
+vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data,
+ enum vm_io_regh_type type, void *arg)
+{
+ struct vm_io_reg_handler ioregh;
+
+ bzero(&ioregh, sizeof(ioregh));
+ ioregh.port = port;
+ ioregh.in = in;
+ ioregh.mask_data = mask_data;
+ ioregh.data = data;
+ ioregh.type = type;
+ ioregh.arg = arg;
+
+ return (ioctl(ctx->fd, VM_IO_REG_HANDLER, &ioregh));
+}
+
+int
vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func,
uint64_t addr, uint64_t msg, int numvec)
{
Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h
==============================================================================
--- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 08:01:05 2016 (r307050)
@@ -161,7 +161,10 @@
int vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *i1, uint64_t *i2);
int vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t exit_intinfo);
-
+int vm_get_fd(struct vmctx *ctx);
+int vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf);
+int vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in,
+ uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg);
/*
* Return a pointer to the statistics buffer. Note that this is not MT-safe.
*/
Modified: soc2016/vincenzo/head/sys/amd64/include/vmm.h
==============================================================================
--- soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 08:01:05 2016 (r307050)
@@ -183,6 +183,7 @@
int vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem);
void vm_free_memseg(struct vm *vm, int ident);
int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa);
+int vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td);
int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len);
int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func);
int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func);
@@ -321,6 +322,7 @@
struct vatpit *vm_atpit(struct vm *vm);
struct vpmtmr *vm_pmtmr(struct vm *vm);
struct vrtc *vm_rtc(struct vm *vm);
+struct ioregh *vm_ioregh(struct vm *vm);
/*
* Inject exception 'vector' into the guest vcpu. This function returns 0 on
@@ -417,7 +419,13 @@
EDGE_TRIGGER,
LEVEL_TRIGGER
};
-
+
+enum vm_io_regh_type {
+ VM_IO_REGH_DELETE,
+ VM_IO_REGH_KWEVENTS, /* kernel wait events */
+ VM_IO_REGH_MAX
+};
+
/*
* The 'access' field has the format specified in Table 21-2 of the Intel
* Architecture Manual vol 3b.
Modified: soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h
==============================================================================
--- soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 08:01:05 2016 (r307050)
@@ -123,6 +123,21 @@
size_t len;
};
+struct vm_user_buf {
+ vm_paddr_t gpa;
+ void *addr;
+ size_t len;
+};
+
+struct vm_io_reg_handler {
+ uint16_t port; /* I/O address */
+ uint16_t in; /* 0 out, 1 in */
+ uint32_t mask_data; /* 0 means match anything */
+ uint32_t data; /* data to match */
+ enum vm_io_regh_type type; /* handler type */
+ void *arg; /* handler argument */
+};
+
struct vm_pptdev_msi {
int vcpu;
int bus;
@@ -286,6 +301,10 @@
IOCNUM_RTC_WRITE = 101,
IOCNUM_RTC_SETTIME = 102,
IOCNUM_RTC_GETTIME = 103,
+
+ /* host mmap and IO handler */
+ IOCNUM_MAP_USER_BUF = 104,
+ IOCNUM_IO_REG_HANDLER = 105,
};
#define VM_RUN \
@@ -344,6 +363,10 @@
_IOW('v', IOCNUM_UNBIND_PPTDEV, struct vm_pptdev)
#define VM_MAP_PPTDEV_MMIO \
_IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio)
+#define VM_MAP_USER_BUF \
+ _IOW('v', IOCNUM_MAP_USER_BUF, struct vm_user_buf)
+#define VM_IO_REG_HANDLER \
+ _IOW('v', IOCNUM_IO_REG_HANDLER, struct vm_io_reg_handler)
#define VM_PPTDEV_MSI \
_IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi)
#define VM_PPTDEV_MSIX \
Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm.c
==============================================================================
--- soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 08:01:05 2016 (r307050)
@@ -66,6 +66,7 @@
#include "vmm_ktr.h"
#include "vmm_host.h"
#include "vmm_mem.h"
+#include "vmm_usermem.h"
#include "vmm_util.h"
#include "vatpic.h"
#include "vatpit.h"
@@ -148,6 +149,7 @@
struct vatpit *vatpit; /* (i) virtual atpit */
struct vpmtmr *vpmtmr; /* (i) virtual ACPI PM timer */
struct vrtc *vrtc; /* (o) virtual RTC */
+ struct ioregh *ioregh; /* () I/O reg handler */
volatile cpuset_t active_cpus; /* (i) active vcpus */
int suspend; /* (i) stop VM execution */
volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */
@@ -419,6 +421,7 @@
vm->vpmtmr = vpmtmr_init(vm);
if (create)
vm->vrtc = vrtc_init(vm);
+ vm->ioregh = ioregh_init(vm);
CPU_ZERO(&vm->active_cpus);
@@ -475,11 +478,13 @@
vrtc_cleanup(vm->vrtc);
else
vrtc_reset(vm->vrtc);
+ ioregh_cleanup(vm->ioregh);
vpmtmr_cleanup(vm->vpmtmr);
vatpit_cleanup(vm->vatpit);
vhpet_cleanup(vm->vhpet);
vatpic_cleanup(vm->vatpic);
vioapic_cleanup(vm->vioapic);
+ vmm_usermem_cleanup(vm->vmspace);
for (i = 0; i < VM_MAXCPU; i++)
vcpu_cleanup(vm, i, destroy);
@@ -553,6 +558,17 @@
}
int
+vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td)
+{
+ vm_object_t obj;
+
+ if ((obj = vmm_usermem_alloc(vm->vmspace, gpa, len, buf, td)) == NULL)
+ return (ENOMEM);
+
+ return (0);
+}
+
+int
vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len)
{
@@ -588,6 +604,9 @@
if (ppt_is_mmio(vm, gpa))
return (true); /* 'gpa' is pci passthru mmio */
+ if (usermem_mapped(vm->vmspace, gpa))
+ return (true); /* 'gpa' is user-space buffer mapped */
+
return (false);
}
@@ -2457,6 +2476,12 @@
return (vm->vrtc);
}
+struct ioregh *
+vm_ioregh(struct vm *vm)
+{
+ return (vm->ioregh);
+}
+
enum vm_reg_name
vm_segment_name(int seg)
{
Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c
==============================================================================
--- soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 08:01:05 2016 (r307050)
@@ -55,6 +55,7 @@
#include "vmm_lapic.h"
#include "vmm_stat.h"
#include "vmm_mem.h"
+#include "vmm_ioport.h"
#include "io/ppt.h"
#include "io/vatpic.h"
#include "io/vioapic.h"
@@ -300,6 +301,8 @@
struct vm_pptdev_mmio *pptmmio;
struct vm_pptdev_msi *pptmsi;
struct vm_pptdev_msix *pptmsix;
+ struct vm_user_buf *usermem;
+ struct vm_io_reg_handler *ioregh;
struct vm_nmi *vmnmi;
struct vm_stats *vmstats;
struct vm_stat_desc *statdesc;
@@ -358,6 +361,7 @@
case VM_UNBIND_PPTDEV:
case VM_ALLOC_MEMSEG:
case VM_MMAP_MEMSEG:
+ case VM_MAP_USER_BUF:
case VM_REINIT:
/*
* ioctls that operate on the entire virtual machine must
@@ -433,6 +437,16 @@
pptmmio->func, pptmmio->gpa, pptmmio->len,
pptmmio->hpa);
break;
+ case VM_MAP_USER_BUF:
+ usermem = (struct vm_user_buf *)data;
+ error = vm_map_usermem(sc->vm, usermem->gpa, usermem->len,
+ usermem->addr, td);
+ break;
+ case VM_IO_REG_HANDLER:
+ ioregh = (struct vm_io_reg_handler *)data;
+ error = vmm_ioport_reg_handler(sc->vm, ioregh->port, ioregh->in, ioregh->mask_data,
+ ioregh->data, ioregh->type, ioregh->arg);
+ break;
case VM_BIND_PPTDEV:
pptdev = (struct vm_pptdev *)data;
error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot,
Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c
==============================================================================
--- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 08:01:05 2016 (r307050)
@@ -97,31 +97,278 @@
}
#endif /* KTR */
+#ifdef VMM_IOPORT_REG_HANDLER
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+static MALLOC_DEFINE(M_IOREGH, "ioregh", "bhyve ioport reg handlers");
+
+#define IOREGH_LOCK(ioregh) mtx_lock_spin(&((ioregh)->mtx))
+#define IOREGH_UNLOCK(ioregh) mtx_unlock_spin(&((ioregh)->mtx))
+
+#define IOPORT_MAX_REG_HANDLER 12
+
+/*
+ * ioport_reg_handler functions allows us to to catch VM write/read
+ * on specific I/O address and send notification.
+ *
+ * When the VM writes or reads a specific value on I/O address, if the address
+ * and the value matches with the info stored durign the handler registration,
+ * then we send a notification (we can have multiple type of notification,
+ * but for now is implemented only the VM_IO_REGH_KWEVENTS handler.
+ */
+
+typedef int (*ioport_reg_handler_func_t)(struct vm *vm,
+ struct ioport_reg_handler *regh, uint32_t *val);
+
+struct ioport_reg_handler {
+ uint16_t port; /* I/O address */
+ uint16_t in; /* 0 out, 1 in */
+ uint32_t mask_data; /* 0 means match anything */
+ uint32_t data; /* data to match */
+ ioport_reg_handler_func_t handler; /* handler pointer */
+ void *handler_arg; /* handler argument */
+};
+
+struct ioregh {
+ struct mtx mtx;
+ /* TODO: use hash table is better */
+ struct ioport_reg_handler handlers[IOPORT_MAX_REG_HANDLER];
+};
+
+/* ----- I/O reg handlers ----- */
+
+/*
+ * VM_IO_REGH_KWEVENTS handler
+ *
+ * wakeup() on specified address that uniquely identifies the event
+ *
+ */
+static int
+vmm_ioport_reg_wakeup(struct vm *vm, struct ioport_reg_handler *regh, uint32_t *val)
+{
+ wakeup(regh->handler_arg);
+ return (0);
+}
+
+/*
+ * TODO:
+ * - VM_IO_REGH_CONDSIGNAL: pthread_cond_signal
+ * - VM_IO_REGH_WRITEFD: write on fd
+ * - VM_IO_REGH_IOCTL: ioctl on fd
+ */
+
+/* call with ioregh->mtx held */
+static struct ioport_reg_handler *
+vmm_ioport_find_handler(struct ioregh *ioregh, uint16_t port, uint16_t in,
+ uint32_t mask_data, uint32_t data)
+{
+ struct ioport_reg_handler *regh;
+ uint32_t mask;
+ int i;
+
+ regh = ioregh->handlers;
+ for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) {
+ if (regh[i].handler != NULL) {
+ mask = regh[i].mask_data & mask_data;
+ if ((regh[i].port == port) && (regh[i].in == in)
+ && ((mask & regh[i].data) == (mask & data))) {
+ return ®h[i];
+ }
+ }
+ }
+
+ return (NULL);
+}
+
+/* call with ioregh->mtx held */
+static struct ioport_reg_handler *
+vmm_ioport_empty_handler(struct ioregh *ioregh)
+{
+ struct ioport_reg_handler *regh;
+ int i;
+
+ regh = ioregh->handlers;
+ for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) {
+ if (regh[i].handler == NULL) {
+ return ®h[i];
+ }
+ }
+
+ return (NULL);
+}
+
+
+static int
+vmm_ioport_add_handler(struct vm *vm, uint16_t port, uint16_t in, uint32_t mask_data,
+ uint32_t data, ioport_reg_handler_func_t handler, void *handler_arg)
+{
+ struct ioport_reg_handler *regh;
+ struct ioregh *ioregh;
+ int ret = 0;
+
+ ioregh = vm_ioregh(vm);
+
+ IOREGH_LOCK(ioregh);
+
+ regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data);
+ if (regh != NULL) {
+ printf("%s: handler for port %d in %d mask_data %d data %d \
+ already registered\n",
+ __FUNCTION__, port, in, mask_data, data);
+ ret = EEXIST;
+ goto err;
+ }
+
+ regh = vmm_ioport_empty_handler(ioregh);
+ if (regh == NULL) {
+ printf("%s: empty reg_handler slot not found\n", __FUNCTION__);
+ ret = ENOMEM;
+ goto err;
+ }
+
+ regh->port = port;
+ regh->in = in;
+ regh->mask_data = mask_data;
+ regh->data = data;
+ regh->handler = handler;
+ regh->handler_arg = handler_arg;
+
+err:
+ IOREGH_UNLOCK(ioregh);
+ return (ret);
+}
+
+static int
+vmm_ioport_del_handler(struct vm *vm, uint16_t port, uint16_t in,
+ uint32_t mask_data, uint32_t data)
+{
+ struct ioport_reg_handler *regh;
+ struct ioregh *ioregh;
+ int ret = 0;
+
+ ioregh = vm_ioregh(vm);
+
+ IOREGH_LOCK(ioregh);
+
+ regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data);
+
+ if (regh == NULL) {
+ ret = EINVAL;
+ goto err;
+ }
+
+ bzero(regh, sizeof(struct ioport_reg_handler));
+err:
+ IOREGH_UNLOCK(ioregh);
+ return (ret);
+}
+
+/*
+ * register or delete a new I/O event handler.
+ */
+int
+vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in,
+ uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg)
+{
+ int ret = 0;
+
+ switch (type) {
+ case VM_IO_REGH_DELETE:
+ ret = vmm_ioport_del_handler(vm, port, in, mask_data, data);
+ break;
+ case VM_IO_REGH_KWEVENTS:
+ ret = vmm_ioport_add_handler(vm, port, in, mask_data, data,
+ vmm_ioport_reg_wakeup, arg);
+ break;
+ default:
+ printf("%s: unknown reg_handler type\n", __FUNCTION__);
+ ret = EINVAL;
+ break;
+ }
+
+ return (ret);
+}
+
+/*
+ * Invoke an handler, if the data matches.
+ */
+static int
+invoke_reg_handler(struct vm *vm, int vcpuid, struct vm_exit *vmexit,
+ uint32_t *val, int *error)
+{
+ struct ioport_reg_handler *regh;
+ struct ioregh *ioregh;
+ uint32_t mask_data;
+
+ mask_data = vie_size2mask(vmexit->u.inout.bytes);
+ ioregh = vm_ioregh(vm);
+
+ IOREGH_LOCK(ioregh);
+ regh = vmm_ioport_find_handler(ioregh, vmexit->u.inout.port,
+ vmexit->u.inout.in, mask_data, vmexit->u.inout.eax);
+ if (regh == NULL) {
+ IOREGH_UNLOCK(ioregh);
+ return (0);
+ }
+ *error = (*(regh->handler))(vm, regh, val);
+ IOREGH_UNLOCK(ioregh);
+ return (1);
+}
+
+struct ioregh *
+ioregh_init(struct vm *vm)
+{
+ struct ioregh *ioregh;
+
+ ioregh = malloc(sizeof(struct ioregh), M_IOREGH, M_WAITOK | M_ZERO);
+
+ mtx_init(&ioregh->mtx, "ioregh lock", NULL, MTX_SPIN);
+
+ return (ioregh);
+}
+
+void
+ioregh_cleanup(struct ioregh *ioregh)
+{
+ free(ioregh, M_IOREGH);
+}
+#else /* !VMM_IOPORT_REG_HANDLER */
+#define invoke_reg_handler(_1, _2, _3, _4, _5) (0)
+#endif /* VMM_IOPORT_REG_HANDLER */
+
static int
emulate_inout_port(struct vm *vm, int vcpuid, struct vm_exit *vmexit,
bool *retu)
{
ioport_handler_func_t handler;
uint32_t mask, val;
- int error;
+ int regh = 0, error = 0;
/*
* If there is no handler for the I/O port then punt to userspace.
*/
- if (vmexit->u.inout.port >= MAX_IOPORTS ||
- (handler = ioport_handler[vmexit->u.inout.port]) == NULL) {
+ if ((vmexit->u.inout.port >= MAX_IOPORTS ||
+ (handler = ioport_handler[vmexit->u.inout.port]) == NULL) &&
+ (regh = invoke_reg_handler(vm, vcpuid, vmexit, &val, &error)) == 0) {
*retu = true;
return (0);
}
- mask = vie_size2mask(vmexit->u.inout.bytes);
+ if (!regh) {
+ mask = vie_size2mask(vmexit->u.inout.bytes);
+
+ if (!vmexit->u.inout.in) {
+ val = vmexit->u.inout.eax & mask;
+ }
- if (!vmexit->u.inout.in) {
- val = vmexit->u.inout.eax & mask;
+ error = (*handler)(vm, vcpuid, vmexit->u.inout.in,
+ vmexit->u.inout.port, vmexit->u.inout.bytes, &val);
}
- error = (*handler)(vm, vcpuid, vmexit->u.inout.in,
- vmexit->u.inout.port, vmexit->u.inout.bytes, &val);
if (error) {
/*
* The value returned by this function is also the return value
Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h
==============================================================================
--- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 08:01:05 2016 (r307050)
@@ -29,6 +29,22 @@
#ifndef _VMM_IOPORT_H_
#define _VMM_IOPORT_H_
+#define VMM_IOPORT_REG_HANDLER
+#ifdef VMM_IOPORT_REG_HANDLER
+struct ioport_reg_handler;
+struct ioregh;
+
+struct ioregh *ioregh_init(struct vm *vm);
+void ioregh_cleanup(struct ioregh *ioregh);
+
+int vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in,
+ uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg);
+#else /* !VMM_IOPORT_REG_HANDLER */
+#define ioregh_init(_1) (NULL)
+#define ioregh_cleanup(_1)
+#define vmm_ioport_reg_handler(_1, _2, _3, _4,_5, _6, _7) (EINVAL)
+#endif /* VMM_IOPORT_REG_HANDLER */
+
typedef int (*ioport_handler_func_t)(struct vm *vm, int vcpuid,
bool in, int port, int bytes, uint32_t *val);
Modified: soc2016/vincenzo/head/sys/modules/vmm/Makefile
==============================================================================
--- soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 06:59:35 2016 (r307049)
+++ soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 08:01:05 2016 (r307050)
@@ -21,6 +21,7 @@
vmm_ioport.c \
vmm_lapic.c \
vmm_mem.c \
+ vmm_usermem.c \
vmm_stat.c \
vmm_util.c \
x86.c
More information about the svn-soc-all
mailing list