aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorNeel Natu <neel@FreeBSD.org>2014-05-24 23:12:30 +0000
committerNeel Natu <neel@FreeBSD.org>2014-05-24 23:12:30 +0000
commitda11f4aa1da2ed00735a3ec0361d46dd3f8a8b4f (patch)
tree6d3c6dd2e08177b036c0a323543c552eea67411c /sys/amd64
parent94831f6d218d070aed9b6e2cb3ff1451ea710eea (diff)
downloadsrc-da11f4aa1da2ed00735a3ec0361d46dd3f8a8b4f.tar.gz
src-da11f4aa1da2ed00735a3ec0361d46dd3f8a8b4f.zip
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).
Notes
Notes: svn path=/head/; revision=266633
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/include/vmm.h1
-rw-r--r--sys/amd64/include/vmm_dev.h12
-rw-r--r--sys/amd64/vmm/vmm_dev.c24
-rw-r--r--sys/amd64/vmm/vmm_ioport.c16
4 files changed, 39 insertions, 14 deletions
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 021efafb1ae0..28e2808e89b7 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -427,7 +427,6 @@ struct vm_inout_str {
enum vm_reg_name seg_name;
struct seg_desc seg_desc;
uint64_t gla; /* may be set to VIE_INVALID_GLA */
- uint64_t gpa;
};
struct vm_exit {
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
index ecafa9ca5e31..f094d519a413 100644
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -168,6 +168,15 @@ struct vm_suspend {
enum vm_suspend_how how;
};
+struct vm_gla2gpa {
+ int vcpuid; /* inputs */
+ int prot; /* PROT_READ or PROT_WRITE */
+ uint64_t gla;
+ struct vm_guest_paging paging;
+ int fault; /* outputs */
+ uint64_t gpa;
+};
+
enum {
/* general routines */
IOCNUM_ABIVERS = 0,
@@ -180,6 +189,7 @@ enum {
IOCNUM_MAP_MEMORY = 10,
IOCNUM_GET_MEMORY_SEG = 11,
IOCNUM_GET_GPA_PMAP = 12,
+ IOCNUM_GLA2GPA = 13,
/* register/state accessors */
IOCNUM_SET_REGISTER = 20,
@@ -289,4 +299,6 @@ enum {
_IOR('v', IOCNUM_GET_HPET_CAPABILITIES, struct vm_hpet_cap)
#define VM_GET_GPA_PMAP \
_IOWR('v', IOCNUM_GET_GPA_PMAP, struct vm_gpa_pte)
+#define VM_GLA2GPA \
+ _IOWR('v', IOCNUM_GLA2GPA, struct vm_gla2gpa)
#endif
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index f1d57955767d..05617853641c 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <machine/vmparam.h>
#include <machine/vmm.h>
+#include <machine/vmm_instruction_emul.h>
#include <machine/vmm_dev.h>
#include "vmm_lapic.h"
@@ -168,6 +169,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
struct vm_x2apic *x2apic;
struct vm_gpa_pte *gpapte;
struct vm_suspend *vmsuspend;
+ struct vm_gla2gpa *gg;
sc = vmmdev_lookup2(cdev);
if (sc == NULL)
@@ -192,6 +194,7 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
case VM_PPTDEV_MSI:
case VM_PPTDEV_MSIX:
case VM_SET_X2APIC_STATE:
+ case VM_GLA2GPA:
/*
* XXX fragile, handle with care
* Assumes that the first field of the ioctl data is the vcpu.
@@ -415,6 +418,27 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
case VM_GET_HPET_CAPABILITIES:
error = vhpet_getcap((struct vm_hpet_cap *)data);
break;
+ case VM_GLA2GPA: {
+ CTASSERT(PROT_READ == VM_PROT_READ);
+ CTASSERT(PROT_WRITE == VM_PROT_WRITE);
+ CTASSERT(PROT_EXEC == VM_PROT_EXECUTE);
+ gg = (struct vm_gla2gpa *)data;
+ error = vmm_gla2gpa(sc->vm, gg->vcpuid, &gg->paging, gg->gla,
+ gg->prot, &gg->gpa);
+ KASSERT(error == 0 || error == 1 || error == -1,
+ ("%s: vmm_gla2gpa unknown error %d", __func__, error));
+ if (error >= 0) {
+ /*
+ * error = 0: the translation was successful
+ * error = 1: a fault was injected into the guest
+ */
+ gg->fault = error;
+ error = 0;
+ } else {
+ error = EFAULT;
+ }
+ break;
+ }
default:
error = ENOTTY;
break;
diff --git a/sys/amd64/vmm/vmm_ioport.c b/sys/amd64/vmm/vmm_ioport.c
index f9fda2d45402..96f2418a72b4 100644
--- a/sys/amd64/vmm/vmm_ioport.c
+++ b/sys/amd64/vmm/vmm_ioport.c
@@ -145,7 +145,7 @@ emulate_inout_str(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu)
{
struct vm_inout_str *vis;
uint64_t gla, index, segbase;
- int error, in;
+ int in;
vis = &vmexit->u.inout_str;
in = vis->inout.in;
@@ -197,18 +197,8 @@ emulate_inout_str(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu)
}
vis->gla = gla;
- error = vmm_gla2gpa(vm, vcpuid, &vis->paging, gla,
- in ? VM_PROT_WRITE : VM_PROT_READ, &vis->gpa);
- KASSERT(error == 0 || error == 1 || error == -1,
- ("%s: vmm_gla2gpa unexpected error %d", __func__, error));
- if (error == -1) {
- return (EFAULT);
- } else if (error == 1) {
- return (0); /* Resume guest to handle page fault */
- } else {
- *retu = true;
- return (0); /* Return to userspace to finish emulation */
- }
+ *retu = true;
+ return (0); /* Return to userspace to finish emulation */
}
int