Skip to content

Commit 3a07249

Browse files
author
Marc Zyngier
committed
KVM: Move kvm_io_bus_get_dev() locking responsibilities to callers
kvm_io_bus_get_dev() returns a device that is only matched by the address, and nothing else. This can cause a lifetime issue if the matched device is not the expected type, as by the time the caller can introspect the object, it might be gone (the srcu lock having been dropped). Given that there is only a single user of this helper, the simplest option is to move the locking responsibility to the caller, which can keep the srcu lock held for as long as it wants. Note that this aligns with other kvm_io_bus*() helpers, which already require the srcu lock to be held by the callers. Reported-by: Will Deacon <will@kernel.org> Fixes: 8a39d00 ("KVM: kvm_io_bus: Add kvm_io_bus_get_dev() call") Link: https://lore.kernel.org/all/20260626111344.802555-1-maz@kernel.org Cc: stable@vger.kernel.org Reviewed-by: Oliver Upton <oupton@kernel.org> Link: https://patch.msgid.link/20260627105105.1005990-1-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent d098bb7 commit 3a07249

2 files changed

Lines changed: 7 additions & 11 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,8 @@ static struct vgic_its *__vgic_doorbell_to_its(struct kvm *kvm, gpa_t db)
508508
struct kvm_io_device *kvm_io_dev;
509509
struct vgic_io_device *iodev;
510510

511+
guard(srcu)(&kvm->srcu);
512+
511513
kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, db);
512514
if (!kvm_io_dev)
513515
return ERR_PTR(-EINVAL);

virt/kvm/kvm_main.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6068,25 +6068,19 @@ struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
60686068
gpa_t addr)
60696069
{
60706070
struct kvm_io_bus *bus;
6071-
int dev_idx, srcu_idx;
6072-
struct kvm_io_device *iodev = NULL;
6071+
int dev_idx;
60736072

6074-
srcu_idx = srcu_read_lock(&kvm->srcu);
6073+
lockdep_assert_held(&kvm->srcu);
60756074

60766075
bus = kvm_get_bus_srcu(kvm, bus_idx);
60776076
if (!bus)
6078-
goto out_unlock;
6077+
return NULL;
60796078

60806079
dev_idx = kvm_io_bus_get_first_dev(bus, addr, 1);
60816080
if (dev_idx < 0)
6082-
goto out_unlock;
6083-
6084-
iodev = bus->range[dev_idx].dev;
6085-
6086-
out_unlock:
6087-
srcu_read_unlock(&kvm->srcu, srcu_idx);
6081+
return NULL;
60886082

6089-
return iodev;
6083+
return bus->range[dev_idx].dev;
60906084
}
60916085
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_io_bus_get_dev);
60926086

0 commit comments

Comments
 (0)