Skip to content

Commit 78a0055

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: Ensure vgic_ready() is ordered against MMIO registration
kvm_vgic_map_resources() prematurely marks the distributor as 'ready', potentially allowing vCPUs to enter the guest before the distributor's MMIO registration has been made visible. Plug the race by marking the distributor as ready only after MMIO registration is completed. Rely on the implied ordering of synchronize_srcu() to ensure the MMIO registration is visible before vgic_dist::ready. This also means that writers to vgic_dist::ready are now serialized by the slots_lock, which was effectively the case already as all writers held the slots_lock in addition to the config_lock. Fixes: 59112e9 ("KVM: arm64: vgic: Fix a circular locking issue") Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20241017001947.2707312-3-oliver.upton@linux.dev Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 5978d4e commit 78a0055

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,14 +544,23 @@ int kvm_vgic_map_resources(struct kvm *kvm)
544544
if (ret)
545545
goto out;
546546

547-
dist->ready = true;
548547
dist_base = dist->vgic_dist_base;
549548
mutex_unlock(&kvm->arch.config_lock);
550549

551550
ret = vgic_register_dist_iodev(kvm, dist_base, type);
552-
if (ret)
551+
if (ret) {
553552
kvm_err("Unable to register VGIC dist MMIO regions\n");
553+
goto out_slots;
554+
}
554555

556+
/*
557+
* kvm_io_bus_register_dev() guarantees all readers see the new MMIO
558+
* registration before returning through synchronize_srcu(), which also
559+
* implies a full memory barrier. As such, marking the distributor as
560+
* 'ready' here is guaranteed to be ordered after all vCPUs having seen
561+
* a completely configured distributor.
562+
*/
563+
dist->ready = true;
555564
goto out_slots;
556565
out:
557566
mutex_unlock(&kvm->arch.config_lock);

0 commit comments

Comments
 (0)