Date: Thu, 13 Aug 2015 09:47:12 GMT From: stefano@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r289681 - in soc2015/stefano/ptnetmap/stable/10/sys/amd64: include vmm Message-ID: <201508130947.t7D9lCoQ040502@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508130947.t7D9lCoQ040502>