socsvn commit: r288138 - in soc2015/stefano/ptnetmap/stable/10: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/modules/vmm
stefano at FreeBSD.org
stefano at FreeBSD.org
Thu Jul 9 09:08:16 UTC 2015
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 at 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 at 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 \
More information about the svn-soc-all
mailing list