diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2008-09-26 03:30:47 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:51:40 -0500 |
commit | 60637aacfd95c368e1fbc2157275d1b621b5dcdd (patch) | |
tree | 53abd0c0eaece938af0bd0f24715716a49f8d4e2 /arch/x86/kvm | |
parent | e4a41889ece6c95f390a7fa3a94255ab62470968 (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.c | 18 |
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 | ||
2833 | static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 2833 | static 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); |