[PATCH 1/2] KVM: nVMX: don't check PIR.ON when processing nested posted interrupts
From: Maxim Levitsky
Date: Fri Oct 09 2026 - 16:54:48 EST
Despite the suggestion to test and set the PIR.ON and avoid sending
a posted interrupt if it is already set, there is no requirement
for this bit to be set for posted interrupt processing to happen
when the target CPU receives the posted notification vector.
See section 30.6 POSTED-INTERRUPT PROCESSING:
"The processor clears the outstanding-notification bit in
the posted-interrupt descriptor. This is done atomically so as to leave
the remainder of the descriptor unmodified
(e.g., with a locked AND operation)."
Apparently Windows' implementation of APICv does exactly this:
it sets bits in PIR, without bothering to also set the PIR.ON.
Signed-off-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx>
---
arch/x86/kvm/vmx/nested.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 151873407abd..2142e25c9b6c 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -4041,8 +4041,11 @@ static int vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
vmx->nested.pi_pending = false;
- if (!pi_test_and_clear_on(vmx->nested.pi_desc))
- return 0;
+ /*
+ * Don't test the value of PID.ON.
+ * It is valid to trigger a posted interrupt without setting this bit
+ */
+ pi_clear_on(vmx->nested.pi_desc);
max_irr = pi_find_highest_vector(vmx->nested.pi_desc);
if (max_irr > 0) {
@@ -4209,8 +4212,7 @@ static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection)
if ((max_irr & 0xf0) > (vppr & 0xf0))
return true;
- if (vmx->nested.pi_pending && vmx->nested.pi_desc &&
- pi_test_on(vmx->nested.pi_desc)) {
+ if (vmx->nested.pi_pending && 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;
--
2.54.0