Commit bdb19d4b authored by Joerg Roedel's avatar Joerg Roedel Committed by Greg Kroah-Hartman

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: default avatarJoerg Roedel <joerg.roedel@amd.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>

(Cherry-picked from commit 8fe54654)
parent d3994940
...@@ -1402,16 +1402,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, ...@@ -1402,16 +1402,17 @@ static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
return vmexit; 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)) if (!is_nested(svm))
return 0; return true;
if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK)) if (!(svm->vcpu.arch.hflags & HF_VINTR_MASK))
return 0; return true;
if (!(svm->vcpu.arch.hflags & HF_HIF_MASK)) if (!(svm->vcpu.arch.hflags & HF_HIF_MASK))
return 0; return false;
svm->vmcb->control.exit_code = SVM_EXIT_INTR; svm->vmcb->control.exit_code = SVM_EXIT_INTR;
...@@ -1424,10 +1425,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm) ...@@ -1424,10 +1425,10 @@ static inline int nested_svm_intr(struct vcpu_svm *svm)
*/ */
svm->nested.exit_required = true; svm->nested.exit_required = true;
trace_kvm_nested_intr_vmexit(svm->vmcb->save.rip); 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) 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) ...@@ -2591,13 +2592,11 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
{ {
struct vcpu_svm *svm = to_svm(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 /* 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. * GIF becomes 1, because that's a separate STGI/VMRUN intercept.
* The next time we get that intercept, this function will be * The next time we get that intercept, this function will be
* called again though and we'll get the vintr intercept. */ * 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_set_vintr(svm);
svm_inject_irq(svm, 0x0); svm_inject_irq(svm, 0x0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment