summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2026-04-01 13:36:01 +0300
committerMarc Zyngier <maz@kernel.org>2026-04-01 17:42:26 +0300
commite63d0a32e7368f3eb935755db87add1bf000ea90 (patch)
tree6c549bcbd6927e50ef56ad989749abce2637a943
parentd70d4323dd9636e35696639f6b4c2b2735291516 (diff)
downloadlinux-e63d0a32e7368f3eb935755db87add1bf000ea90.tar.xz
KVM: arm64: vgic-v5: Hold config_lock while finalizing GICv5 PPIs
Finalizing the PPI state is done without holding any lock, which means that two vcpus can race against each other and have one zeroing the state while another one is setting it, or even maybe using it. Fixing this is done by: - holding the config lock while performing the initialisation - checking if SW_PPI has already been advertised, meaning that we have already completed the initialisation once Reviewed-by: Sascha Bischoff <sascha.bischoff@arm.com> Fixes: 8f1fbe2fd2792 ("KVM: arm64: gic-v5: Finalize GICv5 PPIs and generate mask") Link: https://sashiko.dev/#/patchset/20260319154937.3619520-1-sascha.bischoff%40arm.com Link: https://patch.msgid.link/20260401103611.357092-7-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
-rw-r--r--arch/arm64/kvm/vgic/vgic-v5.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c
index 2b6cd5c3f9c2..119d7d01d0e7 100644
--- a/arch/arm64/kvm/vgic/vgic-v5.c
+++ b/arch/arm64/kvm/vgic/vgic-v5.c
@@ -172,6 +172,16 @@ int vgic_v5_finalize_ppi_state(struct kvm *kvm)
if (!vgic_is_v5(kvm))
return 0;
+ guard(mutex)(&kvm->arch.config_lock);
+
+ /*
+ * If SW_PPI has been advertised, then we know we already
+ * initialised the whole thing, and we can return early. Yes,
+ * this is pretty hackish as far as state tracking goes...
+ */
+ if (test_bit(GICV5_ARCH_PPI_SW_PPI, kvm->arch.vgic.gicv5_vm.vgic_ppi_mask))
+ return 0;
+
/* The PPI state for all VCPUs should be the same. Pick the first. */
vcpu0 = kvm_get_vcpu(kvm, 0);