diff options
author | Avi Kivity <avi@redhat.com> | 2010-11-01 17:20:48 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-01-12 04:29:04 -0500 |
commit | 30bd0c4c6c5aecc338ebf32e3a6e01c98f0a0b43 (patch) | |
tree | ddac5485f0a57d25096ee94126d74fc10d3fe85a | |
parent | 64f638c7c44fa87e65f51eaf0f8302b9cba2d696 (diff) |
KVM: VMX: Disallow NMI while blocked by STI
While not mandated by the spec, Linux relies on NMI being blocked by an
IF-enabling STI. VMX also refuses to enter a guest in this state, at
least on some implementations.
Disallow NMI while blocked by STI by checking for the condition, and
requesting an interrupt window exit if it occurs.
Signed-off-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
-rw-r--r-- | arch/x86/kvm/vmx.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 12c30733e239..8087c4d1a136 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -2787,6 +2787,10 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu) | |||
2787 | return; | 2787 | return; |
2788 | } | 2788 | } |
2789 | 2789 | ||
2790 | if (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & GUEST_INTR_STATE_STI) { | ||
2791 | enable_irq_window(vcpu); | ||
2792 | return; | ||
2793 | } | ||
2790 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); | 2794 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); |
2791 | cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING; | 2795 | cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING; |
2792 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | 2796 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); |
@@ -2849,7 +2853,8 @@ static int vmx_nmi_allowed(struct kvm_vcpu *vcpu) | |||
2849 | return 0; | 2853 | return 0; |
2850 | 2854 | ||
2851 | return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & | 2855 | return !(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & |
2852 | (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_NMI)); | 2856 | (GUEST_INTR_STATE_MOV_SS | GUEST_INTR_STATE_STI |
2857 | | GUEST_INTR_STATE_NMI)); | ||
2853 | } | 2858 | } |
2854 | 2859 | ||
2855 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) | 2860 | static bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu) |