diff options
author | neel <neel@FreeBSD.org> | 2014-09-17 18:46:51 +0000 |
---|---|---|
committer | neel <neel@FreeBSD.org> | 2014-09-17 18:46:51 +0000 |
commit | c9b7ad126a69df6d747aa31e822ad6ae3ea9c900 (patch) | |
tree | c99380d1a0386a2472762670318cd92cfcb5b65a /sys/amd64/vmm/intel | |
parent | eefb10a1843c72b46fee9c11a6cde4146031ea4d (diff) | |
parent | 65bccd5b546490ed3e9ef43ce93d5a573d366801 (diff) | |
download | FreeBSD-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.c | 46 |
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); |