summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2017-09-11 23:32:35 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2017-09-11 23:32:35 +0000
commit233ec8fc888d117728fe67bd3c1736e381f72824 (patch)
tree91f1659c06df02a381579639529039f55165d20c /usr.sbin
parent672141bdbfb5418d600b9d52ca665b8a4813ad75 (diff)
add functions to provide direct access to guest memory as vmd addresses
iovec_mem() populates an iovec array based on guest physical addresses. this allows the use of things like readv and writev for moving data between the guest and a disk image file without having to bounce the memory. vaddr_mem() provides a vmd usable pointer based on a guests physical address. this makes it possible to directly reference things like virtio rings without having to bounce that memory either. however, it assumes that a contiguous range of guest physical memory will sit in a single vm memory range. mlarkin@ says this is right. ok mlarkin@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/vmd/vm.c62
-rw-r--r--usr.sbin/vmd/vmd.h6
2 files changed, 66 insertions, 2 deletions
diff --git a/usr.sbin/vmd/vm.c b/usr.sbin/vmd/vm.c
index 0199f77860a..25547127e1a 100644
--- a/usr.sbin/vmd/vm.c
+++ b/usr.sbin/vmd/vm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vm.c,v 1.24 2017/08/20 21:15:32 pd Exp $ */
+/* $OpenBSD: vm.c,v 1.25 2017/09/11 23:32:34 dlg Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -1561,6 +1561,29 @@ find_gpa_range(struct vm_create_params *vcp, paddr_t gpa, size_t len)
return (vmr);
}
+void *
+vaddr_mem(paddr_t gpa, size_t len)
+{
+ struct vm_create_params *vcp = &current_vm->vm_params.vmc_params;
+ size_t i;
+ struct vm_mem_range *vmr;
+ paddr_t gpend = gpa + len;
+
+ /* Find the first vm_mem_range that contains gpa */
+ for (i = 0; i < vcp->vcp_nmemranges; i++) {
+ vmr = &vcp->vcp_memranges[i];
+ if (gpa < vmr->vmr_gpa)
+ continue;
+
+ if (gpend >= vmr->vmr_gpa + vmr->vmr_size)
+ continue;
+
+ return ((char *)vmr->vmr_va + (gpa - vmr->vmr_gpa));
+ }
+
+ return (NULL);
+}
+
/*
* write_mem
*
@@ -1658,6 +1681,43 @@ read_mem(paddr_t src, void *buf, size_t len)
return (0);
}
+int
+iovec_mem(paddr_t src, size_t len, struct iovec *iov, int iovcnt)
+{
+ size_t n, off;
+ struct vm_mem_range *vmr;
+ int niov = 0;
+
+ vmr = find_gpa_range(&current_vm->vm_params.vmc_params, src, len);
+ if (vmr == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ off = src - vmr->vmr_gpa;
+ while (len > 0) {
+ if (niov == iovcnt) {
+ errno = ENOMEM;
+ return (-1);
+ }
+
+ n = vmr->vmr_size - off;
+ if (len < n)
+ n = len;
+
+ iov[niov].iov_base = (char *)vmr->vmr_va + off;
+ iov[niov].iov_len = n;
+
+ niov++;
+
+ len -= n;
+ off = 0;
+ vmr++;
+ }
+
+ return (niov);
+}
+
/*
* vcpu_assert_pic_irq
*
diff --git a/usr.sbin/vmd/vmd.h b/usr.sbin/vmd/vmd.h
index 02f05c32603..4b7b5f70495 100644
--- a/usr.sbin/vmd/vmd.h
+++ b/usr.sbin/vmd/vmd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.h,v 1.63 2017/09/11 23:25:05 dlg Exp $ */
+/* $OpenBSD: vmd.h,v 1.64 2017/09/11 23:32:34 dlg Exp $ */
/*
* Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org>
@@ -326,10 +326,14 @@ int vm_priv_brconfig(struct privsep *, struct vmd_switch *);
uint32_t vm_priv_addr(struct address *, uint32_t, int, int);
/* vmm.c */
+struct iovec;
+
void vmm(struct privsep *, struct privsep_proc *);
void vmm_shutdown(void);
+void *vaddr_mem(paddr_t, size_t);
int write_mem(paddr_t, const void *buf, size_t);
int read_mem(paddr_t, void *buf, size_t);
+int iovec_mem(paddr_t, size_t, struct iovec *, int);
int opentap(char *);
int fd_hasdata(int);
void mutex_lock(pthread_mutex_t *);