summaryrefslogtreecommitdiffstats
path: root/lib/libvmmapi
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-05-24 23:12:30 +0000
committerneel <neel@FreeBSD.org>2014-05-24 23:12:30 +0000
commit51a05acc08355b84ae16b193ccb7037691f8ba90 (patch)
tree6d3c6dd2e08177b036c0a323543c552eea67411c /lib/libvmmapi
parent75eadcdacf2b5f0dc80b3adb8f91fc71cb1c62cc (diff)
downloadFreeBSD-src-51a05acc08355b84ae16b193ccb7037691f8ba90.zip
FreeBSD-src-51a05acc08355b84ae16b193ccb7037691f8ba90.tar.gz
Add libvmmapi functions vm_copyin() and vm_copyout() to copy into and out
of the guest linear address space. These APIs in turn use a new ioctl 'VM_GLA2GPA' to convert the guest linear address to guest physical. Use the new copyin/copyout APIs when emulating ins/outs instruction in bhyve(8).
Diffstat (limited to 'lib/libvmmapi')
-rw-r--r--lib/libvmmapi/vmmapi.c86
-rw-r--r--lib/libvmmapi/vmmapi.h5
2 files changed, 91 insertions, 0 deletions
diff --git a/lib/libvmmapi/vmmapi.c b/lib/libvmmapi/vmmapi.c
index 5e630f8..45fffcf 100644
--- a/lib/libvmmapi/vmmapi.c
+++ b/lib/libvmmapi/vmmapi.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mman.h>
#include <machine/specialreg.h>
+#include <machine/param.h>
#include <stdio.h>
#include <stdlib.h>
@@ -937,3 +938,88 @@ vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities)
*capabilities = cap.capabilities;
return (error);
}
+
+static int
+vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
+ uint64_t gla, int prot, int *fault, uint64_t *gpa)
+{
+ struct vm_gla2gpa gg;
+ int error;
+
+ bzero(&gg, sizeof(struct vm_gla2gpa));
+ gg.vcpuid = vcpu;
+ gg.prot = prot;
+ gg.gla = gla;
+ gg.paging = *paging;
+
+ error = ioctl(ctx->fd, VM_GLA2GPA, &gg);
+ if (error == 0) {
+ *fault = gg.fault;
+ *gpa = gg.gpa;
+ }
+ return (error);
+}
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+int
+vm_copyin(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
+ uint64_t gla, void *vp, size_t len)
+{
+ char *dst;
+ const char *src;
+ uint64_t gpa;
+ int error, fault, n, off;
+
+ dst = vp;
+ while (len) {
+ error = vm_gla2gpa(ctx, vcpu, paging, gla, PROT_READ,
+ &fault, &gpa);
+ if (error)
+ return (-1);
+ if (fault)
+ return (1);
+
+ off = gpa & PAGE_MASK;
+ n = min(len, PAGE_SIZE - off);
+ src = vm_map_gpa(ctx, gpa, n);
+ bcopy(src, dst, n);
+
+ gla += n;
+ dst += n;
+ len -= n;
+ }
+ return (0);
+}
+
+int
+vm_copyout(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
+ const void *vp, uint64_t gla, size_t len)
+{
+ uint64_t gpa;
+ char *dst;
+ const char *src;
+ int error, fault, n, off;
+
+ src = vp;
+ while (len) {
+ error = vm_gla2gpa(ctx, vcpu, paging, gla, PROT_WRITE,
+ &fault, &gpa);
+ if (error)
+ return (-1);
+ if (fault)
+ return (1);
+
+ off = gpa & PAGE_MASK;
+ n = min(len, PAGE_SIZE - off);
+ dst = vm_map_gpa(ctx, gpa, n);
+ bcopy(src, dst, n);
+
+ gla += n;
+ src += n;
+ len -= n;
+ }
+ return (0);
+}
diff --git a/lib/libvmmapi/vmmapi.h b/lib/libvmmapi/vmmapi.h
index 88e9947..cad41c8 100644
--- a/lib/libvmmapi/vmmapi.h
+++ b/lib/libvmmapi/vmmapi.h
@@ -109,6 +109,11 @@ int vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state s);
int vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities);
+int vm_copyin(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
+ uint64_t gla_src, void *dst, size_t len);
+int vm_copyout(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging,
+ const void *src, uint64_t gla_dst, size_t len);
+
/* Reset vcpu register state */
int vcpu_reset(struct vmctx *ctx, int vcpu);
OpenPOWER on IntegriCloud