[PATCH] iommu/virtio: Fix probe error handling and driver state initialization

Xiong Weimin <[email protected]> Fri, 24 Jul 2026 10:42:19 +0800 (CST)
Newsgroups dev.linux.lists.iommu
Message-ID <[email protected]>
Hi Will,

Thank you for your patience and I'm really sorry for the email mess earlier.

The previous emails had issues with my sending script, which caused:
1. Cover letter sent without patch content
2. Duplicate v2 patches that should have been marked obsolete

I've now fixed the script and combined the two probe fixes into a single
patch. Here's what the new patch does:

1. Store vdev->priv before creating virtqueues so the event callback
   always sees initialized driver state

2. Check the return value of iommu_device_register() and clean up sysfs
   entries on failure

3. As you suggested, pass vdev instead of viommu to viommu_init_vqs()

I've also dropped the "Reject short event buffers" patch since Xu Rao
independently submitted an identical fix.

The patch is attached below. Could you please take another look?

Sorry again for the confusion.

Best regards,
Xiong Weimin

---

From: Xiong Weimin <[email protected]>
Subject: [PATCH] iommu/virtio: Fix probe error handling and driver state initialization
To: [email protected]
Cc: [email protected], [email protected], [email protected]

The event virtqueue callback retrieves the driver state through
vq->vdev->priv. viommu_probe() currently initializes that pointer only
after virtio_device_ready() and after the event queue is populated.

Store the driver data before creating the virtqueues so callbacks always
see initialized driver state once the device is made ready. Clear the
pointer again on probe failure.

Also check the return value of iommu_device_register() and properly
clean up sysfs entries on failure. This ensures that the device sysfs
directory is removed if registration fails.

As suggested by Will Deacon, pass vdev instead of viommu to
viommu_init_vqs(), since we already linked them together.

Note: The "Reject short event buffers" patch has been dropped as Xu Rao
independently submitted an identical fix.

Suggested-by: Will Deacon <[email protected]>
Signed-off-by: Xiong Weimin <[email protected]>
Reviewed-by: Will Deacon <[email protected]>
---
 drivers/iommu/virtio-iommu.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 587fc1319..288eea386 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1110,9 +1110,9 @@ static const struct iommu_ops viommu_ops = {
 	}
 };
 
-static int viommu_init_vqs(struct viommu_dev *viommu)
+static int viommu_init_vqs(struct virtio_device *vdev)
 {
-	struct virtio_device *vdev = dev_to_virtio(viommu->dev);
+	struct viommu_dev *viommu = vdev->priv;
 	struct virtqueue_info vqs_info[] = {
 		{ "request" },
 		{ "event", viommu_event_handler },
@@ -1169,11 +1169,12 @@ static int viommu_probe(struct virtio_device *vdev)
 	ida_init(&viommu->domain_ids);
 	viommu->dev = dev;
 	viommu->vdev = vdev;
+	vdev->priv = viommu;
 	INIT_LIST_HEAD(&viommu->requests);
 
-	ret = viommu_init_vqs(viommu);
+	ret = viommu_init_vqs(vdev);
 	if (ret)
-		return ret;
+		goto err_clear_priv;
 
 	virtio_cread_le(vdev, struct virtio_iommu_config, page_size_mask,
 			&viommu->pgsize_bitmap);
@@ -1236,7 +1237,9 @@ static int viommu_probe(struct virtio_device *vdev)
 
 	vdev->priv = viommu;
 
-	iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev);
+	ret = iommu_device_register(&viommu->iommu, &viommu_ops, parent_dev);
+	if (ret)
+		goto err_free_sysfs;
 
 	dev_info(dev, "input address: %u bits\n",
 		 order_base_2(viommu->geometry.aperture_end));
@@ -1244,8 +1247,12 @@ static int viommu_probe(struct virtio_device *vdev)
 
 	return 0;
 
+err_free_sysfs:
+	iommu_device_sysfs_remove(&viommu->iommu);
 err_free_vqs:
 	vdev->config->del_vqs(vdev);
+err_clear_priv:
+	vdev->priv = NULL;
 
 	return ret;
 }
-- 
2.43.0