aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2008-09-26 03:30:47 -0400
committerAvi Kivity <avi@redhat.com>2008-12-31 09:51:40 -0500
commit60637aacfd95c368e1fbc2157275d1b621b5dcdd (patch)
tree53abd0c0eaece938af0bd0f24715716a49f8d4e2 /arch/x86/kvm
parente4a41889ece6c95f390a7fa3a94255ab62470968 (diff)
KVM: VMX: Support for NMI task gates
Properly set GUEST_INTR_STATE_NMI and reset nmi_injected when a task-switch vmexit happened due to a task gate being used for handling NMIs. Also avoid the false warning about valid vectoring info in kvm_handle_exit. Based on original patch by Gleb Natapov. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/vmx.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 81cf12b8d12a..8d0fc68fd4ec 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2832,6 +2832,7 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2832 2832
2833static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 2833static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2834{ 2834{
2835 struct vcpu_vmx *vmx = to_vmx(vcpu);
2835 unsigned long exit_qualification; 2836 unsigned long exit_qualification;
2836 u16 tss_selector; 2837 u16 tss_selector;
2837 int reason; 2838 int reason;
@@ -2839,6 +2840,15 @@ static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2839 exit_qualification = vmcs_readl(EXIT_QUALIFICATION); 2840 exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
2840 2841
2841 reason = (u32)exit_qualification >> 30; 2842 reason = (u32)exit_qualification >> 30;
2843 if (reason == TASK_SWITCH_GATE && vmx->vcpu.arch.nmi_injected &&
2844 (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) &&
2845 (vmx->idt_vectoring_info & VECTORING_INFO_TYPE_MASK)
2846 == INTR_TYPE_NMI_INTR) {
2847 vcpu->arch.nmi_injected = false;
2848 if (cpu_has_virtual_nmis())
2849 vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
2850 GUEST_INTR_STATE_NMI);
2851 }
2842 tss_selector = exit_qualification; 2852 tss_selector = exit_qualification;
2843 2853
2844 return kvm_task_switch(vcpu, tss_selector, reason); 2854 return kvm_task_switch(vcpu, tss_selector, reason);
@@ -3012,9 +3022,11 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
3012 3022
3013 if ((vectoring_info & VECTORING_INFO_VALID_MASK) && 3023 if ((vectoring_info & VECTORING_INFO_VALID_MASK) &&
3014 (exit_reason != EXIT_REASON_EXCEPTION_NMI && 3024 (exit_reason != EXIT_REASON_EXCEPTION_NMI &&
3015 exit_reason != EXIT_REASON_EPT_VIOLATION)) 3025 exit_reason != EXIT_REASON_EPT_VIOLATION &&
3016 printk(KERN_WARNING "%s: unexpected, valid vectoring info and " 3026 exit_reason != EXIT_REASON_TASK_SWITCH))
3017 "exit reason is 0x%x\n", __func__, exit_reason); 3027 printk(KERN_WARNING "%s: unexpected, valid vectoring info "
3028 "(0x%x) and exit reason is 0x%x\n",
3029 __func__, vectoring_info, exit_reason);
3018 if (exit_reason < kvm_vmx_max_exit_handlers 3030 if (exit_reason < kvm_vmx_max_exit_handlers
3019 && kvm_vmx_exit_handlers[exit_reason]) 3031 && kvm_vmx_exit_handlers[exit_reason])
3020 return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run); 3032 return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run);