aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-04-23 10:03:48 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:51 -0400
commitfe8e7f83de3f0979f13f57992cb33e4a8041272d (patch)
treed300367996243453d9b2f407263f4f9fdec64538 /arch/x86/kvm/svm.c
parentb586eb0253083795e58dcbe76665410d4676dc08 (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.c23
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,