summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2014-01-23 06:06:50 +0000
committerneel <neel@FreeBSD.org>2014-01-23 06:06:50 +0000
commit232e34343e20609036a1e02ada5ff5666abca5f7 (patch)
treeac8dac50defc770fadce188f0b7fe1277e2e1f8e /sys/amd64
parent53ba94e7762873aba9fc8ba91fa4d82d09de6ae4 (diff)
downloadFreeBSD-src-232e34343e20609036a1e02ada5ff5666abca5f7.zip
FreeBSD-src-232e34343e20609036a1e02ada5ff5666abca5f7.tar.gz
Set "Interrupt Window Exiting" in the case where there is a vector to be
injected into the vcpu but the VM-entry interruption information field already has the valid bit set. Pointed out by: David Reed (david.reed@tidalscale.com)
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/vmm/intel/vmx.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index 1bc13b0..68d940b 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -1121,15 +1121,15 @@ vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic)
}
/*
- * If there is already an interrupt pending then just return. This
- * could happen for multiple reasons:
- * - A vectoring VM-entry was aborted due to astpending or rendezvous.
- * - A VM-exit happened during event injection.
- * - A NMI was injected above or after "NMI window exiting" VM-exit.
+ * If interrupt-window exiting is already in effect then don't bother
+ * checking for pending interrupts. This is just an optimization and
+ * not needed for correctness.
*/
- info = vmcs_read(VMCS_ENTRY_INTR_INFO);
- if (info & VMCS_INTR_VALID)
+ if ((vmx->cap[vcpu].proc_ctls & PROCBASED_INT_WINDOW_EXITING) != 0) {
+ VCPU_CTR0(vmx->vm, vcpu, "Skip interrupt injection due to "
+ "pending int_window_exiting");
return;
+ }
/* Ask the local apic for a vector to inject */
if (!vlapic_pending_intr(vlapic, &vector))
@@ -1139,12 +1139,31 @@ vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic)
/* Check RFLAGS.IF and the interruptibility state of the guest */
rflags = vmcs_read(VMCS_GUEST_RFLAGS);
- if ((rflags & PSL_I) == 0)
+ if ((rflags & PSL_I) == 0) {
+ VCPU_CTR2(vmx->vm, vcpu, "Cannot inject vector %d due to "
+ "rflags %#lx", vector, rflags);
goto cantinject;
+ }
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
- if (gi & HWINTR_BLOCKING)
+ if (gi & HWINTR_BLOCKING) {
+ VCPU_CTR2(vmx->vm, vcpu, "Cannot inject vector %d due to "
+ "Guest Interruptibility-state %#x", vector, gi);
goto cantinject;
+ }
+
+ info = vmcs_read(VMCS_ENTRY_INTR_INFO);
+ if (info & VMCS_INTR_VALID) {
+ /*
+ * This is expected and could happen for multiple reasons:
+ * - A vectoring VM-entry was aborted due to astpending
+ * - A VM-exit happened during event injection.
+ * - An NMI was injected above or after "NMI window exiting"
+ */
+ VCPU_CTR2(vmx->vm, vcpu, "Cannot inject vector %d due to "
+ "VM-entry intr info %#x", vector, info);
+ goto cantinject;
+ }
/* Inject the interrupt */
info = VMCS_INTR_T_HWINTR | VMCS_INTR_VALID;
OpenPOWER on IntegriCloud