aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Roedel <joerg.roedel@amd.com>2010-02-19 10:23:01 -0500
committerAvi Kivity <avi@redhat.com>2010-04-25 05:38:11 -0400
commit8fe546547cf6857a9d984bfe2f2194910f3fc5d0 (patch)
treede627a861eecd58bbc183f88819e9ba2a41a11b0
parent112592da0dc2460c95e8a89d0c5657c6a30286aa (diff)
KVM: SVM: Fix wrong interrupt injection in enable_irq_windows
The nested_svm_intr() function does not execute the vmexit anymore. Therefore we may still be in the nested state after that function ran. This patch changes the nested_svm_intr() function to return wether the irq window could be enabled. Cc: stable@kernel.org Signed-off-by: Joerg Roedel <joerg.roedel@amd.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/x86/kvm/svm.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index a8ec53fe74f..294bbca3417 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1432,16 +1432,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
1432 return vmexit; 1432 return vmexit;
1433} 1433}
1434 1434
1435static inline int nested_svm_intr(struct vcpu_svm *svm) 1435/* This function returns true if it is save to enable the irq window */
1436static inline bool nested_svm_intr(struct vcpu_svm *svm)
1436{ 1437{
1437 if (!is_nested(svm)) 1438 if (!is_nested(svm))
1438 return 0; 1439 return true;
1439 1440
1440 if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) 1441 if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
1441 return 0; 1442 return true;
1442 1443
1443 if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) 1444 if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
1444 return 0; 1445 return false;
1445 1446
1446 svm->vmcb->control.exit_code = SVM_EXIT_INTR; 1447 svm->vmcb->control.exit_code = SVM_EXIT_INTR;
1447 1448
@@ -1454,10 +1455,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
1454 */ 1455 */
1455 svm->nested.exit_required = true; 1456 svm->nested.exit_required = true;
1456 trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip); 1457 trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip);
1457 return 1; 1458 return false;
1458 } 1459 }
1459 1460
1460 return 0; 1461 return true;
1461} 1462}
1462 1463
1463static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) 1464static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
@@ -2629,13 +2630,11 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
2629{ 2630{
2630 struct vcpu_svm *svm = to_svm(vcpu); 2631 struct vcpu_svm *svm = to_svm(vcpu);
2631 2632
2632 nested_svm_intr(svm);
2633
2634 /* In case GIF=0 we can't rely on the CPU to tell us when 2633 /* In case GIF=0 we can't rely on the CPU to tell us when
2635 * GIF becomes 1, because that's a separate STGI/VMRUN intercept. 2634 * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
2636 * The next time we get that intercept, this function will be 2635 * The next time we get that intercept, this function will be
2637 * called again though and we'll get the vintr intercept. */ 2636 * called again though and we'll get the vintr intercept. */
2638 if (gif_set(svm)) { 2637 if (gif_set(svm) && nested_svm_intr(svm)) {
2639 svm_set_vintr(svm); 2638 svm_set_vintr(svm);
2640 svm_inject_irq(svm, 0x0); 2639 svm_inject_irq(svm, 0x0);
2641 } 2640 }