summaryrefslogtreecommitdiffstats
path: root/sys/amd64/vmm/intel
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-09-17 18:46:51 +0000
committerneel <neel@FreeBSD.org>2014-09-17 18:46:51 +0000
commitc9b7ad126a69df6d747aa31e822ad6ae3ea9c900 (patch)
treec99380d1a0386a2472762670318cd92cfcb5b65a /sys/amd64/vmm/intel
parenteefb10a1843c72b46fee9c11a6cde4146031ea4d (diff)
parent65bccd5b546490ed3e9ef43ce93d5a573d366801 (diff)
downloadFreeBSD-src-c9b7ad126a69df6d747aa31e822ad6ae3ea9c900.zip
FreeBSD-src-c9b7ad126a69df6d747aa31e822ad6ae3ea9c900.tar.gz
IFC @r271694
Diffstat (limited to 'sys/amd64/vmm/intel')
-rw-r--r--sys/amd64/vmm/intel/vmx.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 8e35781..5e42679 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -2711,6 +2711,46 @@ vmxctx_setreg(struct vmxctx *vmxctx, int reg, uint64_t val)
}
static int
+vmx_get_intr_shadow(struct vmx *vmx, int vcpu, int running, uint64_t *retval)
+{
+ uint64_t gi;
+ int error;
+
+ error = vmcs_getreg(&vmx->vmcs[vcpu], running,
+ VMCS_IDENT(VMCS_GUEST_INTERRUPTIBILITY), &gi);
+ *retval = (gi & HWINTR_BLOCKING) ? 1 : 0;
+ return (error);
+}
+
+static int
+vmx_modify_intr_shadow(struct vmx *vmx, int vcpu, int running, uint64_t val)
+{
+ struct vmcs *vmcs;
+ uint64_t gi;
+ int error, ident;
+
+ /*
+ * Forcing the vcpu into an interrupt shadow is not supported.
+ */
+ if (val) {
+ error = EINVAL;
+ goto done;
+ }
+
+ vmcs = &vmx->vmcs[vcpu];
+ ident = VMCS_IDENT(VMCS_GUEST_INTERRUPTIBILITY);
+ error = vmcs_getreg(vmcs, running, ident, &gi);
+ if (error == 0) {
+ gi &= ~HWINTR_BLOCKING;
+ error = vmcs_setreg(vmcs, running, ident, gi);
+ }
+done:
+ VCPU_CTR2(vmx->vm, vcpu, "Setting intr_shadow to %#lx %s", val,
+ error ? "failed" : "succeeded");
+ return (error);
+}
+
+static int
vmx_shadow_reg(int reg)
{
int shreg;
@@ -2741,6 +2781,9 @@ vmx_getreg(void *arg, int vcpu, int reg, uint64_t *retval)
if (running && hostcpu != curcpu)
panic("vmx_getreg: %s%d is running", vm_name(vmx->vm), vcpu);
+ if (reg == VM_REG_GUEST_INTR_SHADOW)
+ return (vmx_get_intr_shadow(vmx, vcpu, running, retval));
+
if (vmxctx_getreg(&vmx->ctx[vcpu], reg, retval) == 0)
return (0);
@@ -2759,6 +2802,9 @@ vmx_setreg(void *arg, int vcpu, int reg, uint64_t val)
if (running && hostcpu != curcpu)
panic("vmx_setreg: %s%d is running", vm_name(vmx->vm), vcpu);
+ if (reg == VM_REG_GUEST_INTR_SHADOW)
+ return (vmx_modify_intr_shadow(vmx, vcpu, running, val));
+
if (vmxctx_setreg(&vmx->ctx[vcpu], reg, val) == 0)
return (0);
OpenPOWER on IntegriCloud