mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 14:56:44 +07:00
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>
This commit is contained in:
parent
112592da0d
commit
8fe546547c
@ -1432,16 +1432,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;
|
||||||
|
|
||||||
@ -1454,10 +1455,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)
|
||||||
@ -2629,13 +2630,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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user