All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: Make kvm_io_bus_get_dev() filter devices by ops
@ 2026-06-26 11:13 Marc Zyngier
  2026-06-26 11:46 ` sashiko-bot
  2026-06-26 13:09 ` Will Deacon
  0 siblings, 2 replies; 5+ messages in thread
From: Marc Zyngier @ 2026-06-26 11:13 UTC (permalink / raw)
  To: kvm, kvmarm
  Cc: Steffen Eiden, Joey Gouly, Suzuki K Poulose, Oliver Upton,
	Zenghui Yu, Paolo Bonzini, Will Deacon, stable

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).

Add an kvm_io_device_ops pointer to the list of things that this
helper must check before dropping the lock and returning the pointer,
and update the sole user to pass its own ops.

Reported-by: Will Deacon <will@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Fixes: 8a39d00670f07 ("KVM: kvm_io_bus: Add kvm_io_bus_get_dev() call")
Cc: stable@vger.kernel.org
---
 arch/arm64/kvm/vgic/vgic-its.c | 5 +----
 include/linux/kvm_host.h       | 1 +
 virt/kvm/kvm_main.c            | 5 ++++-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 4477f870c7b36..1c1bdd420c40d 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -508,13 +508,10 @@ static struct vgic_its *__vgic_doorbell_to_its(struct kvm *kvm, gpa_t db)
 	struct kvm_io_device *kvm_io_dev;
 	struct vgic_io_device *iodev;
 
-	kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, db);
+	kvm_io_dev = kvm_io_bus_get_dev(kvm, KVM_MMIO_BUS, &kvm_io_gic_ops, db);
 	if (!kvm_io_dev)
 		return ERR_PTR(-EINVAL);
 
-	if (kvm_io_dev->ops != &kvm_io_gic_ops)
-		return ERR_PTR(-EINVAL);
-
 	iodev = container_of(kvm_io_dev, struct vgic_io_device, dev);
 	if (iodev->iodev_type != IODEV_ITS)
 		return ERR_PTR(-EINVAL);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4c14aee1fb063..4c195a8723c40 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -231,6 +231,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
 int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
 			      struct kvm_io_device *dev);
 struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+					 const struct kvm_io_device_ops *ops,
 					 gpa_t addr);
 
 #ifdef CONFIG_KVM_ASYNC_PF
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 881f92d7a469e..26c34d500ea18 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -6066,6 +6066,7 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
 }
 
 struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+					 const struct kvm_io_device_ops *ops,
 					 gpa_t addr)
 {
 	struct kvm_io_bus *bus;
@@ -6082,7 +6083,9 @@ struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
 	if (dev_idx < 0)
 		goto out_unlock;
 
-	iodev = bus->range[dev_idx].dev;
+	if (bus->range[dev_idx].dev &&
+	    bus->range[dev_idx].dev->ops == ops)
+		iodev = bus->range[dev_idx].dev;
 
 out_unlock:
 	srcu_read_unlock(&kvm->srcu, srcu_idx);
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-06-26 17:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-26 11:13 [PATCH] KVM: Make kvm_io_bus_get_dev() filter devices by ops Marc Zyngier
2026-06-26 11:46 ` sashiko-bot
2026-06-26 12:41   ` Marc Zyngier
2026-06-26 17:26     ` Oliver Upton
2026-06-26 13:09 ` Will Deacon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.