From owner-svn-soc-all@freebsd.org Thu Jul 9 09:08:16 2015 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B19FD995ED5 for ; Thu, 9 Jul 2015 09:08:16 +0000 (UTC) (envelope-from stefano@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9F9F41059 for ; Thu, 9 Jul 2015 09:08:16 +0000 (UTC) (envelope-from stefano@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id t6998GcC080672 for ; Thu, 9 Jul 2015 09:08:16 GMT (envelope-from stefano@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id t6998BZW076895 for svn-soc-all@FreeBSD.org; Thu, 9 Jul 2015 09:08:11 GMT (envelope-from stefano@FreeBSD.org) Date: Thu, 9 Jul 2015 09:08:11 GMT Message-Id: <201507090908.t6998BZW076895@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to stefano@FreeBSD.org using -f From: stefano@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r288138 - in soc2015/stefano/ptnetmap/stable/10: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/modules/vmm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jul 2015 09:08:16 -0000 Author: stefano Date: Thu Jul 9 09:08:11 2015 New Revision: 288138 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=288138 Log: dd new ioctl in the vmm module to map user buffer in the VM Added: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.h Modified: soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.c soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.h soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm.h soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm.c soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_dev.c soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.c soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.h soc2015/stefano/ptnetmap/stable/10/sys/modules/vmm/Makefile Modified: soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.c ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.c Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.c Thu Jul 9 09:08:11 2015 (r288138) @@ -685,6 +685,19 @@ } 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_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { Modified: soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.h ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.h Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/lib/libvmmapi/vmmapi.h Thu Jul 9 09:08:11 2015 (r288138) @@ -108,6 +108,7 @@ 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_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf); /* * Return a pointer to the statistics buffer. Note that this is not MT-safe. Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm.h ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm.h Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm.h Thu Jul 9 09:08:11 2015 (r288138) @@ -172,6 +172,7 @@ const char *vm_name(struct vm *vm); int vm_malloc(struct vm *vm, vm_paddr_t gpa, size_t len); int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_map_mmio_user(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); void *vm_gpa_hold(struct vm *, vm_paddr_t gpa, size_t len, int prot, void **cookie); Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/include/vmm_dev.h Thu Jul 9 09:08:11 2015 (r288138) @@ -111,6 +111,12 @@ size_t len; }; +struct vm_user_buf { + vm_paddr_t gpa; + void *addr; + size_t len; +}; + struct vm_pptdev_msi { int vcpu; int bus; @@ -254,6 +260,8 @@ /* vm_cpuset */ IOCNUM_ACTIVATE_CPU = 90, IOCNUM_GET_CPUSET = 91, + + IOCNUM_MAP_USER_BUF = 100, }; #define VM_RUN \ @@ -308,6 +316,8 @@ _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_PPTDEV_MSI \ _IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi) #define VM_PPTDEV_MSIX \ Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm.c ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm.c Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm.c Thu Jul 9 09:08:11 2015 (r288138) @@ -68,6 +68,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" @@ -503,6 +504,33 @@ return (0); } +static int vm_gpa_wire(struct vm *vm); +int +vm_map_mmio_user(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td) +{ + vm_object_t obj; + int error; + + if ((obj = vmm_mmio_alloc_user(vm->vmspace, gpa, len, buf, td)) == NULL) + return (ENOMEM); + + error = vm_gpa_wire(vm); /* XXX-ste: is needed? */ + + if (error) + goto err; + + + error = vmm_usermem_add(vm, gpa, len); + if (error) + goto err; + + return (0); + +err: + vmm_mmio_free(vm->vmspace, gpa, len); + return (error); +} + int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len) { @@ -527,6 +555,9 @@ if (ppt_is_mmio(vm, gpa)) return (TRUE); /* 'gpa' is pci passthru mmio */ + if (usermem_is_mmio(vm, gpa)) + return (TRUE); /* 'gpa' is user-space buffer mapped */ + return (FALSE); } Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_dev.c ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_dev.c Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_dev.c Thu Jul 9 09:08:11 2015 (r288138) @@ -164,6 +164,7 @@ struct vm_pptdev_mmio *pptmmio; struct vm_pptdev_msi *pptmsi; struct vm_pptdev_msix *pptmsix; + struct vm_user_buf *usermmio; struct vm_nmi *vmnmi; struct vm_stats *vmstats; struct vm_stat_desc *statdesc; @@ -223,6 +224,7 @@ case VM_BIND_PPTDEV: case VM_UNBIND_PPTDEV: case VM_MAP_MEMORY: + case VM_MAP_USER_BUF: case VM_REINIT: /* * ioctls that operate on the entire virtual machine must @@ -295,6 +297,11 @@ pptmmio->func, pptmmio->gpa, pptmmio->len, pptmmio->hpa); break; + case VM_MAP_USER_BUF: + usermmio = (struct vm_user_buf *)data; + error = vm_map_mmio_user(sc->vm, usermmio->gpa, usermmio->len, + usermmio->addr, td); + break; case VM_BIND_PPTDEV: pptdev = (struct vm_pptdev *)data; error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot, Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.c ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.c Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.c Thu Jul 9 09:08:11 2015 (r288138) @@ -55,34 +55,15 @@ return (0); } -vm_object_t -vmm_mmio_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, - vm_paddr_t hpa) +static vm_object_t +vmm_mmio_alloc_sg(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, + struct sglist *sg) { int error; vm_object_t obj; - struct sglist *sg; - - sg = sglist_alloc(1, M_WAITOK); - error = sglist_append_phys(sg, hpa, len); - KASSERT(error == 0, ("error %d appending physaddr to sglist", error)); obj = vm_pager_allocate(OBJT_SG, sg, len, VM_PROT_RW, 0, NULL); if (obj != NULL) { - /* - * VT-x ignores the MTRR settings when figuring out the - * memory type for translations obtained through EPT. - * - * Therefore we explicitly force the pages provided by - * this object to be mapped as uncacheable. - */ - VM_OBJECT_WLOCK(obj); - error = vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); - VM_OBJECT_WUNLOCK(obj); - if (error != KERN_SUCCESS) { - panic("vmm_mmio_alloc: vm_object_set_memattr error %d", - error); - } error = vm_map_find(&vmspace->vm_map, obj, 0, &gpa, len, 0, VMFS_NO_SPACE, VM_PROT_RW, VM_PROT_RW, 0); if (error != KERN_SUCCESS) { @@ -91,6 +72,67 @@ } } + return (obj); +} + +#define VMM_MEM_USER_NSEGS 100000 /* XXX-stefano: find a correct nsegs */ + +vm_object_t +vmm_mmio_alloc_user(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, + void *buf, struct thread *td) +{ + int error; + vm_object_t obj; + struct sglist *sg; + + sg = sglist_alloc(VMM_MEM_USER_NSEGS, M_WAITOK); + error = sglist_append_user(sg, buf, len, td); + KASSERT(error == 0, ("error %d appending user-space buffer to sglist", error)); + + obj = vmm_mmio_alloc_sg(vmspace, gpa, len, sg); + /* + * Drop the reference on the sglist. + * + * If the scatter/gather object was successfully allocated then it + * has incremented the reference count on the sglist. Dropping the + * initial reference count ensures that the sglist will be freed + * when the object is deallocated. + * + * If the object could not be allocated then we end up freeing the + * sglist. + */ + sglist_free(sg); + + return (obj); +} + +vm_object_t +vmm_mmio_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, + vm_paddr_t hpa) +{ + int error; + vm_object_t obj; + struct sglist *sg; + + sg = sglist_alloc(1, M_WAITOK); + error = sglist_append_phys(sg, hpa, len); + KASSERT(error == 0, ("error %d appending physaddr to sglist", error)); + + obj = vmm_mmio_alloc_sg(vmspace, gpa, len, sg); + /* + * VT-x ignores the MTRR settings when figuring out the + * memory type for translations obtained through EPT. + * + * Therefore we explicitly force the pages provided by + * this object to be mapped as uncacheable. + */ + VM_OBJECT_WLOCK(obj); + error = vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); + VM_OBJECT_WUNLOCK(obj); + if (error != KERN_SUCCESS) { + panic("vmm_mmio_alloc: vm_object_set_memattr error %d", + error); + } /* * Drop the reference on the sglist. * Modified: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.h ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.h Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_mem.h Thu Jul 9 09:08:11 2015 (r288138) @@ -36,6 +36,8 @@ struct vm_object *vmm_mem_alloc(struct vmspace *, vm_paddr_t gpa, size_t size); struct vm_object *vmm_mmio_alloc(struct vmspace *, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +struct vm_object *vmm_mmio_alloc_user(struct vmspace *, vm_paddr_t gpa, + size_t len, void *buf, struct thread *td); void vmm_mem_free(struct vmspace *, vm_paddr_t gpa, size_t size); void vmm_mmio_free(struct vmspace *, vm_paddr_t gpa, size_t size); vm_paddr_t vmm_mem_maxaddr(void); Added: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.c Thu Jul 9 09:08:11 2015 (r288138) @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2015 Stefano Garzarella (stefano.garzarella@gmail.com) + * 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$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "vmm_usermem.h" + +#define MAX_USERMEMS 64 + +static struct usermem { + struct vm *vm; /* owner of this device */ + vm_paddr_t gpa; + size_t len; +} usermems[MAX_USERMEMS]; + +int +vmm_usermem_add(struct vm *vm, vm_paddr_t gpa, size_t len) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].len == 0) { + usermems[i].vm = vm; + usermems[i].gpa = gpa; + usermems[i].len = len; + break; + } + } + + if (i == MAX_USERMEMS) { + printf("vmm_usermem_add: empty usermem slot not found\n"); + return (ENOMEM); + } + + return 0; +} + +void +vmm_usermem_del(struct vm *vm, vm_paddr_t gpa, size_t len) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].vm == vm && usermems[i].gpa == gpa + && usermems[i].len == len) { + bzero(&usermems[i], sizeof(struct usermem)); + } + } +} + +boolean_t +usermem_is_mmio(struct vm *vm, vm_paddr_t gpa) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].vm != vm || usermems[i].len == 0) + continue; + if (gpa >= usermems[i].gpa && + gpa < usermems[i].gpa + usermems[i].len) + return (TRUE); + } + return (FALSE); +} Added: soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2015/stefano/ptnetmap/stable/10/sys/amd64/vmm/vmm_usermem.h Thu Jul 9 09:08:11 2015 (r288138) @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Stefano Garzarella (stefano.garzarella@gmail.com) + * 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$ + */ + +#ifndef _VMM_USERMEM_H_ +#define _VMM_USERMEM_H_ + +struct vm; + +int vmm_usermem_add(struct vm *, vm_paddr_t gpa, + size_t len); +void vmm_usermem_del(struct vm *, vm_paddr_t gpa, + size_t len); +boolean_t usermem_is_mmio(struct vm *, vm_paddr_t gpa); + +#endif Modified: soc2015/stefano/ptnetmap/stable/10/sys/modules/vmm/Makefile ============================================================================== --- soc2015/stefano/ptnetmap/stable/10/sys/modules/vmm/Makefile Thu Jul 9 07:31:40 2015 (r288137) +++ soc2015/stefano/ptnetmap/stable/10/sys/modules/vmm/Makefile Thu Jul 9 09:08:11 2015 (r288138) @@ -22,6 +22,7 @@ vmm_ipi.c \ vmm_lapic.c \ vmm_mem.c \ + vmm_usermem.c \ vmm_stat.c \ vmm_util.c \ x86.c \