diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-02-19 10:23:01 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-04-25 05:38:11 -0400 |
commit | 8fe546547cf6857a9d984bfe2f2194910f3fc5d0 (patch) | |
tree | de627a861eecd58bbc183f88819e9ba2a41a11b0 /arch | |
parent | 112592da0dc2460c95e8a89d0c5657c6a30286aa (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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/svm.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a8ec53fe74f5..294bbca34173 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 | ||
1435 | static inline int nested_svm_intr(struct vcpu_svm *svm) | 1435 | /* This function returns true if it is save to enable the irq window */ |
1436 | static 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 | ||
1463 | static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page) | 1464 | static 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 | } |