socsvn commit: r289681 - in soc2015/stefano/ptnetmap/stable/10/sys/amd64: include vmm
stefano at FreeBSD.org
stefano at FreeBSD.org
Thu Aug 13 09:47:14 UTC 2015
Author: stefano
Date: Thu Aug 13 09:47:12 2015
New Revision: 289681
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=289681
Log:
vmm-ptnetmap: cleanup and documentation
Modified:
soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h
soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.c
soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.h
soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c
Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h
==============================================================================
--- soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h Thu Aug 13 09:37:29 2015 (r289680)
+++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h Thu Aug 13 09:47:12 2015 (r289681)
@@ -118,13 +118,13 @@
};
struct vm_io_reg_handler {
- uint16_t port;
- uint16_t in;
- uint32_t mask_data; /* 0 means match anything */
- uint32_t data;
- enum vm_io_regh_type type;
- void *arg;
-};
+ 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 */
+};a specific value that mathces
struct vm_pptdev_msi {
int vcpu;
Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.c
==============================================================================
--- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.c Thu Aug 13 09:37:29 2015 (r289680)
+++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.c Thu Aug 13 09:47:12 2015 (r289681)
@@ -114,16 +114,26 @@
#define IOPORT_MAX_REG_HANDLER 12
-typedef int (*ioport_reg_handler_func_t)(struct vm *vm, struct ioport_reg_handler *regh,
- uint32_t *val);
+/*
+ * 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;
- uint16_t in;
- uint32_t mask_data;
- uint32_t data;
- ioport_reg_handler_func_t handler;
- void *handler_arg;
+ uint16_t port;i /* 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 {
@@ -134,7 +144,12 @@
/* ----- I/O reg handlers ----- */
-/* VM_IO_REGH_KWEVENTS handler */
+/*
+ * 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)
{
@@ -142,9 +157,17 @@
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)
+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;
@@ -183,8 +206,8 @@
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)
+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;
@@ -196,7 +219,8 @@
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",
+ 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;
@@ -222,7 +246,8 @@
}
static int
-vmm_ioport_del_handler(struct vm *vm, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data)
+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;
@@ -245,9 +270,12 @@
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)
+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;
@@ -256,7 +284,8 @@
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);
+ 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__);
@@ -267,8 +296,12 @@
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)
+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;
@@ -278,13 +311,12 @@
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);
+ 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);
}
- /* XXX: maybe is better to use refcount and lock only find */
*error = (*(regh->handler))(vm, regh, val);
IOREGH_UNLOCK(ioregh);
return (1);
Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.h
==============================================================================
--- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.h Thu Aug 13 09:37:29 2015 (r289680)
+++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_ioport.h Thu Aug 13 09:47:12 2015 (r289681)
@@ -30,7 +30,6 @@
#define _VMM_IOPORT_H_
#define VMM_IOPORT_REG_HANDLER
-
#ifdef VMM_IOPORT_REG_HANDLER
struct ioport_reg_handler;
struct ioregh;
@@ -38,9 +37,8 @@
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);
+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)
Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c
==============================================================================
--- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c Thu Aug 13 09:37:29 2015 (r289680)
+++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c Thu Aug 13 09:47:12 2015 (r289681)
@@ -50,11 +50,20 @@
#include "vmm_mem.h"
#include "vmm_usermem.h"
+/*
+ * usermem functions allow us to map an host userspace buffer (eg. from bhyve)
+ * in the guest VM.
+ *
+ * This feature is used to implement ptnetmap on bhyve, mapping the netmap memory
+ * (returned by the mmap() in the byvhe userspace application) in the guest VM.
+ */
+
+/* TODO: we can create a dynamical list of usermem */
#define MAX_USERMEMS 64
static struct usermem {
- struct vmspace *vmspace; /* guest address space */
- vm_paddr_t gpa;
+ struct vmspace *vmspace; /* guest address space */
+ vm_paddr_t gpa; /* guest physical address */
size_t len;
} usermems[MAX_USERMEMS];
@@ -128,7 +137,6 @@
error = vm_map_lookup(&map, (unsigned long)buf, VM_PROT_RW, &entry,
&obj, &index, &prot, &wired);
- printf("---- guest MAP vm_object_t: %p vm_pindex: %ld ----\n", obj, index);
/* map th vm_object in the vmspace */
if (obj != NULL) {
error = vm_map_find(&vmspace->vm_map, obj, index, &gpa, len, 0,
More information about the svn-soc-all
mailing list