Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Jul 2015 09:08:11 GMT
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
Message-ID:  <201507090908.t6998BZW076895@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/sglist.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#include <machine/md_var.h>
+
+#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		\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507090908.t6998BZW076895>