diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-04-23 10:03:48 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:51 -0400 |
commit | fe8e7f83de3f0979f13f57992cb33e4a8041272d (patch) | |
tree | d300367996243453d9b2f407263f4f9fdec64538 /arch/x86/kvm/svm.c | |
parent | b586eb0253083795e58dcbe76665410d4676dc08 (diff) |
KVM: SVM: Don't reinject event that caused a task switch
If a task switch caused by an event remove it from the event queue.
VMX already does that.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index e3ea98290f9b..f994c6df78be 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1811,6 +1811,10 @@ static int task_switch_interception(struct vcpu_svm *svm, | |||
1811 | int int_type = svm->vmcb->control.exit_int_info & | 1811 | int int_type = svm->vmcb->control.exit_int_info & |
1812 | SVM_EXITINTINFO_TYPE_MASK; | 1812 | SVM_EXITINTINFO_TYPE_MASK; |
1813 | int int_vec = svm->vmcb->control.exit_int_info & SVM_EVTINJ_VEC_MASK; | 1813 | int int_vec = svm->vmcb->control.exit_int_info & SVM_EVTINJ_VEC_MASK; |
1814 | uint32_t type = | ||
1815 | svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_TYPE_MASK; | ||
1816 | uint32_t idt_v = | ||
1817 | svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID; | ||
1814 | 1818 | ||
1815 | tss_selector = (u16)svm->vmcb->control.exit_info_1; | 1819 | tss_selector = (u16)svm->vmcb->control.exit_info_1; |
1816 | 1820 | ||
@@ -1820,11 +1824,26 @@ static int task_switch_interception(struct vcpu_svm *svm, | |||
1820 | else if (svm->vmcb->control.exit_info_2 & | 1824 | else if (svm->vmcb->control.exit_info_2 & |
1821 | (1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP)) | 1825 | (1ULL << SVM_EXITINFOSHIFT_TS_REASON_JMP)) |
1822 | reason = TASK_SWITCH_JMP; | 1826 | reason = TASK_SWITCH_JMP; |
1823 | else if (svm->vmcb->control.exit_int_info & SVM_EXITINTINFO_VALID) | 1827 | else if (idt_v) |
1824 | reason = TASK_SWITCH_GATE; | 1828 | reason = TASK_SWITCH_GATE; |
1825 | else | 1829 | else |
1826 | reason = TASK_SWITCH_CALL; | 1830 | reason = TASK_SWITCH_CALL; |
1827 | 1831 | ||
1832 | if (reason == TASK_SWITCH_GATE) { | ||
1833 | switch (type) { | ||
1834 | case SVM_EXITINTINFO_TYPE_NMI: | ||
1835 | svm->vcpu.arch.nmi_injected = false; | ||
1836 | break; | ||
1837 | case SVM_EXITINTINFO_TYPE_EXEPT: | ||
1838 | kvm_clear_exception_queue(&svm->vcpu); | ||
1839 | break; | ||
1840 | case SVM_EXITINTINFO_TYPE_INTR: | ||
1841 | kvm_clear_interrupt_queue(&svm->vcpu); | ||
1842 | break; | ||
1843 | default: | ||
1844 | break; | ||
1845 | } | ||
1846 | } | ||
1828 | 1847 | ||
1829 | if (reason != TASK_SWITCH_GATE || | 1848 | if (reason != TASK_SWITCH_GATE || |
1830 | int_type == SVM_EXITINTINFO_TYPE_SOFT || | 1849 | int_type == SVM_EXITINTINFO_TYPE_SOFT || |
@@ -2203,7 +2222,7 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
2203 | 2222 | ||
2204 | if (is_external_interrupt(svm->vmcb->control.exit_int_info) && | 2223 | if (is_external_interrupt(svm->vmcb->control.exit_int_info) && |
2205 | exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && | 2224 | exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && |
2206 | exit_code != SVM_EXIT_NPF) | 2225 | exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH) |
2207 | printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " | 2226 | printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " |
2208 | "exit_code 0x%x\n", | 2227 | "exit_code 0x%x\n", |
2209 | __func__, svm->vmcb->control.exit_int_info, | 2228 | __func__, svm->vmcb->control.exit_int_info, |