[PATCH 4/5] KVM: arm64: vgic-v3: Don't propagate LPI active state from LRs into the distributor

Marc Zyngier maz at kernel.org
Fri Sep 24 01:25:41 PDT 2021


Christoffer reported that while LPIs to not have an active state,
the pseudocode for the vGIC clearly indicates that LPIs injected
in the LRs do transition via an active state just like any other
interrupt, and that it is only at the priority drop stage that
the active state gets cleared. This is probably done for the sake
of simplicity in the HW, and to trip every single SW developer.

So as it turns out, we can observe an active LPI if the guest
exits between the read of IAR and the write to EOI. This isn't a
big deal and nothing breaks (the active LPI is made inactive on
the next EOI).

However, this active LPI will occupy a LR at the next entry, which
is pointless. We could instead ignore this active state and keep
the distributor blissfully unaware of this oddity. Just do that.

Reported-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/vgic/vgic-v3.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index ae59e2580bf5..d281c6a533ee 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -69,9 +69,10 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
 
 		raw_spin_lock(&irq->irq_lock);
 
-		/* Always preserve the active bit, note deactivation */
+		/* Preserve the active bit for non-LPI, note deactivation */
 		deactivated = irq->active && !(val & ICH_LR_ACTIVE_BIT);
 		irq->active = !!(val & ICH_LR_ACTIVE_BIT);
+		irq->active &= irq->intid <= VGIC_MAX_SPI;
 
 		if (irq->active && is_v2_sgi)
 			irq->active_source = cpuid;
-- 
2.30.2




More information about the linux-arm-kernel mailing list