mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-13 04:39:36 +02:00
KVM: nVMX: Check for pending posted interrupts when looking for nested events
[ Upstream commit27c4fa42b1
] Check for pending (and notified!) posted interrupts when checking if L2 has a pending wake event, as fully posted/notified virtual interrupt is a valid wake event for HLT. Note that KVM must check vmx->nested.pi_pending to avoid prematurely waking L2, e.g. even if KVM sees a non-zero PID.PIR and PID.0N=1, the virtual interrupt won't actually be recognized until a notification IRQ is received by the vCPU or the vCPU does (nested) VM-Enter. Fixes:26844fee6a
("KVM: x86: never write to memory from kvm_vcpu_check_block()") Cc: stable@vger.kernel.org Cc: Maxim Levitsky <mlevitsk@redhat.com> Reported-by: Jim Mattson <jmattson@google.com> Closes: https://lore.kernel.org/all/20231207010302.2240506-1-jmattson@google.com Link: https://lore.kernel.org/r/20240607172609.3205077-5-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
459403bc66
commit
43e73206cf
|
@ -3965,8 +3965,40 @@ static bool nested_vmx_preemption_timer_pending(struct kvm_vcpu *vcpu)
|
||||||
|
|
||||||
static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection)
|
static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection)
|
||||||
{
|
{
|
||||||
return nested_vmx_preemption_timer_pending(vcpu) ||
|
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
||||||
to_vmx(vcpu)->nested.mtf_pending;
|
void *vapic = vmx->nested.virtual_apic_map.hva;
|
||||||
|
int max_irr, vppr;
|
||||||
|
|
||||||
|
if (nested_vmx_preemption_timer_pending(vcpu) ||
|
||||||
|
vmx->nested.mtf_pending)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Virtual Interrupt Delivery doesn't require manual injection. Either
|
||||||
|
* the interrupt is already in GUEST_RVI and will be recognized by CPU
|
||||||
|
* at VM-Entry, or there is a KVM_REQ_EVENT pending and KVM will move
|
||||||
|
* the interrupt from the PIR to RVI prior to entering the guest.
|
||||||
|
*/
|
||||||
|
if (for_injection)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!nested_cpu_has_vid(get_vmcs12(vcpu)) ||
|
||||||
|
__vmx_interrupt_blocked(vcpu))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!vapic)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
vppr = *((u32 *)(vapic + APIC_PROCPRI));
|
||||||
|
|
||||||
|
if (vmx->nested.pi_pending && vmx->nested.pi_desc &&
|
||||||
|
pi_test_on(vmx->nested.pi_desc)) {
|
||||||
|
max_irr = pi_find_highest_vector(vmx->nested.pi_desc);
|
||||||
|
if (max_irr > 0 && (max_irr & 0xf0) > (vppr & 0xf0))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user