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: GICv3: Avoid broadcast kick on CPUs lacking TDIR

CPUs lacking TDIR always trap ICV_DIR_EL1, no matter what, since
we have ICH_HCR_EL2.TC set permanently. For these CPUs, it is
useless to use a broadcast kick on SPI injection, as the sole
purpose of this is to set TDIR.

We can therefore skip this on these CPUs, which are challenged
enough not to be burdened by extra IPIs. As a consequence,
permanently set the TDIR bit in the shadow state to notify the
fast-path emulation code of the exit reason.

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-34-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>

authored by

Marc Zyngier and committed by
Oliver Upton
84792050 ca3c34da

+13 -6
+5 -1
arch/arm64/kvm/vgic/vgic-v3.c
··· 53 53 * need to deal with SPIs that can be deactivated on another 54 54 * CPU. 55 55 * 56 + * On systems that do not implement TDIR, force the bit in the 57 + * shadow state anyway to avoid IPI-ing on these poor sods. 58 + * 56 59 * Note that we set the trap irrespective of EOIMode, as that 57 60 * can change behind our back without any warning... 58 61 */ 59 - if (irqs_active_outside_lrs(als) || 62 + if (!cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR) || 63 + irqs_active_outside_lrs(als) || 60 64 atomic_read(&vcpu->kvm->arch.vgic.active_spis)) 61 65 cpuif->vgic_hcr |= ICH_HCR_EL2_TDIR; 62 66 }
+8 -5
arch/arm64/kvm/vgic/vgic.c
··· 370 370 static bool vgic_model_needs_bcst_kick(struct kvm *kvm) 371 371 { 372 372 /* 373 - * A GICv3 (or GICv3-like) system exposing a GICv3 to the 374 - * guest needs a broadcast kick to set TDIR globally, even if 375 - * the bit doesn't really exist (we still need to check for 376 - * the shadow bit in the DIR emulation fast-path). 373 + * A GICv3 (or GICv3-like) system exposing a GICv3 to the guest 374 + * needs a broadcast kick to set TDIR globally. 375 + * 376 + * For systems that do not have TDIR (ARM's own v8.0 CPUs), the 377 + * shadow TDIR bit is always set, and so is the register's TC bit, 378 + * so no need to kick the CPUs. 377 379 */ 378 - return (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3); 380 + return (cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR) && 381 + kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3); 379 382 } 380 383 381 384 /*