]> git.hungrycats.org Git - linux/commitdiff
KVM: SVM: Fix wrong interrupt injection in enable_irq_windows
authorJoerg Roedel <joerg.roedel@amd.com>
Fri, 19 Feb 2010 15:23:01 +0000 (16:23 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 5 Jul 2010 18:22:59 +0000 (11:22 -0700)
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
(Cherry-picked from commit 8fe546547cf6857a9d984bfe2f2194910f3fc5d0)

arch/x86/kvm/svm.c

index 09fd20e2f521d796238b44cbf241382eb2426ebc..5b915df0d36f17ec3cfc63ab5830293e9298efb4 100644 (file)
@@ -1402,16 +1402,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
        return vmexit;
 }
 
-static inline int nested_svm_intr(struct vcpu_svm *svm)
+/* This function returns true if it is save to enable the irq window */
+static inline bool nested_svm_intr(struct vcpu_svm *svm)
 {
        if (!is_nested(svm))
-               return 0;
+               return true;
 
        if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
-               return 0;
+               return true;
 
        if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
-               return 0;
+               return false;
 
        svm->vmcb->control.exit_code = SVM_EXIT_INTR;
 
@@ -1424,10 +1425,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
                 */
                svm->nested.exit_required = true;
                trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip);
-               return 1;
+               return false;
        }
 
-       return 0;
+       return true;
 }
 
 static void *nested_svm_map(struct vcpu_svm *svm, u64 gpa, struct page **_page)
@@ -2591,13 +2592,11 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       nested_svm_intr(svm);
-
        /* In case GIF=0 we can't rely on the CPU to tell us when
         * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
         * The next time we get that intercept, this function will be
         * called again though and we'll get the vintr intercept. */
-       if (gif_set(svm)) {
+       if (gif_set(svm) && nested_svm_intr(svm)) {
                svm_set_vintr(svm);
                svm_inject_irq(svm, 0x0);
        }