Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: arm64: Invert ap_list sorting to push active interrupts out

Having established that pending interrupts should have priority
to be moved into the LRs over the active interrupts, implement this
in the ap_list sorting.

Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Link: https://msgid.link/20251120172540.2267180-25-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>

authored by

Marc Zyngier and committed by
Oliver Upton
05984ba6 76b2eda6

+12 -15
+12 -15
arch/arm64/kvm/vgic/vgic.c
··· 270 270 * well, the first items in the list being the first things populated in the 271 271 * LRs. 272 272 * 273 - * A hard rule is that active interrupts can never be pushed out of the LRs 274 - * (and therefore take priority) since we cannot reliably trap on deactivation 275 - * of IRQs and therefore they have to be present in the LRs. 276 - * 273 + * Pending, non-active interrupts must be placed at the head of the list. 277 274 * Otherwise things should be sorted by the priority field and the GIC 278 275 * hardware support will take care of preemption of priority groups etc. 279 276 * ··· 295 298 raw_spin_lock(&irqa->irq_lock); 296 299 raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING); 297 300 298 - if (irqa->active || irqb->active) { 299 - ret = (int)irqb->active - (int)irqa->active; 301 + penda = irqa->enabled && irq_is_pending(irqa) && !irqa->active; 302 + pendb = irqb->enabled && irq_is_pending(irqb) && !irqb->active; 303 + 304 + ret = (int)pendb - (int)penda; 305 + if (ret) 300 306 goto out; 301 - } 302 307 303 - penda = irqa->enabled && irq_is_pending(irqa); 304 - pendb = irqb->enabled && irq_is_pending(irqb); 305 - 306 - if (!penda || !pendb) { 307 - ret = (int)pendb - (int)penda; 308 + /* Both pending and enabled, sort by priority (lower number first) */ 309 + ret = (int)irqa->priority - (int)irqb->priority; 310 + if (ret) 308 311 goto out; 309 - } 310 312 311 - /* Both pending and enabled, sort by priority */ 312 - ret = irqa->priority - irqb->priority; 313 + /* Finally, HW bit active interrupts have priority over non-HW ones */ 314 + ret = (int)irqb->hw - (int)irqa->hw; 315 + 313 316 out: 314 317 raw_spin_unlock(&irqb->irq_lock); 315 318 raw_spin_unlock(&irqa->irq_lock);