All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup
@ 2026-07-14  6:09 weimin xiong
  2026-07-14  6:09 ` [PATCH v1 1/4] iommu/arm-smmu: Fix fwnode lookup lifetime handling weimin xiong
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: weimin xiong @ 2026-07-14  6:09 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel
  Cc: Benjamin Gaignard, Rob Clark, linux-arm-kernel, iommu,
	linux-kernel, linux-arm-msm, weimin xiong

Fix a few IOMMU driver lifetime and error-path issues found while
auditing fwnode-based device lookup and probe cleanup paths.

The first three patches avoid deriving driver private data after
dropping the device reference returned by bus_find_device_by_fwnode().
They also make the ARM SMMU v2 and VSI probe paths fail cleanly when the
IOMMU lookup fails.

The last patch unwinds msm_iommu_probe() state if sysfs setup or
iommu_device_register() fails.

weimin xiong (4):
  iommu/arm-smmu: Fix fwnode lookup lifetime handling
  iommu/arm-smmu-v3: Fix fwnode lookup lifetime handling
  iommu/vsi: Fix fwnode lookup lifetime handling
  iommu/msm: Clean up probe state on registration failure

 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  8 +++++++-
 drivers/iommu/arm/arm-smmu/arm-smmu.c       | 12 +++++++++++-
 drivers/iommu/msm_iommu.c                   | 10 ++++++++--
 drivers/iommu/vsi-iommu.c                   | 10 +++++++++-
 4 files changed, 35 insertions(+), 5 deletions(-)

-- 
2.43.0



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

* [PATCH v1 1/4] iommu/arm-smmu: Fix fwnode lookup lifetime handling
  2026-07-14  6:09 [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup weimin xiong
@ 2026-07-14  6:09 ` weimin xiong
  2026-07-14  6:09 ` [PATCH v1 2/4] iommu/arm-smmu-v3: " weimin xiong
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: weimin xiong @ 2026-07-14  6:09 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel
  Cc: Benjamin Gaignard, Rob Clark, linux-arm-kernel, iommu,
	linux-kernel, linux-arm-msm, weimin xiong

bus_find_device_by_fwnode() returns a device with its reference count
incremented. arm_smmu_get_by_fwnode() drops that reference before
reading the driver data, which leaves the returned pointer derived from
a device after its reference has been released.

Read the driver data before put_device(). Also handle a failed lookup in
arm_smmu_probe_device() before dereferencing the returned SMMU pointer.

Signed-off-by: weimin xiong <xiongwm2026@163.com>
---
 drivers/iommu/arm/arm-smmu/arm-smmu.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 0bd21d206..b70c307b8 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -1426,9 +1426,15 @@ static
 struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
 {
 	struct device *dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
+	struct arm_smmu_device *smmu;
+
+	if (!dev)
+		return NULL;
 
+	smmu = dev_get_drvdata(dev);
 	put_device(dev);
-	return dev ? dev_get_drvdata(dev) : NULL;
+
+	return smmu;
 }
 
 static struct iommu_device *arm_smmu_probe_device(struct device *dev)
@@ -1451,6 +1457,10 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev)
 			goto out_free;
 	} else {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
+		if (!smmu) {
+			ret = -ENODEV;
+			goto out_free;
+		}
 	}
 
 	ret = -EINVAL;
-- 
2.43.0



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

* [PATCH v1 2/4] iommu/arm-smmu-v3: Fix fwnode lookup lifetime handling
  2026-07-14  6:09 [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup weimin xiong
  2026-07-14  6:09 ` [PATCH v1 1/4] iommu/arm-smmu: Fix fwnode lookup lifetime handling weimin xiong
@ 2026-07-14  6:09 ` weimin xiong
  2026-07-14  6:09 ` [PATCH v1 3/4] iommu/vsi: " weimin xiong
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: weimin xiong @ 2026-07-14  6:09 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel
  Cc: Benjamin Gaignard, Rob Clark, linux-arm-kernel, iommu,
	linux-kernel, linux-arm-msm, weimin xiong

bus_find_device_by_fwnode() returns a device with its reference count
incremented. arm_smmu_get_by_fwnode() drops that reference before
reading the driver data, which leaves the returned pointer derived from
a device after its reference has been released.

Read the driver data before put_device() and return NULL directly when
the lookup fails.

Signed-off-by: weimin xiong <xiongwm2026@163.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index a10affb48..ef53dd703 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -3980,9 +3980,15 @@ static
 struct arm_smmu_device *arm_smmu_get_by_fwnode(struct fwnode_handle *fwnode)
 {
 	struct device *dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
+	struct arm_smmu_device *smmu;
+
+	if (!dev)
+		return NULL;
 
+	smmu = dev_get_drvdata(dev);
 	put_device(dev);
-	return dev ? dev_get_drvdata(dev) : NULL;
+
+	return smmu;
 }
 
 static bool arm_smmu_sid_in_range(struct arm_smmu_device *smmu, u32 sid)
-- 
2.43.0



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

* [PATCH v1 3/4] iommu/vsi: Fix fwnode lookup lifetime handling
  2026-07-14  6:09 [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup weimin xiong
  2026-07-14  6:09 ` [PATCH v1 1/4] iommu/arm-smmu: Fix fwnode lookup lifetime handling weimin xiong
  2026-07-14  6:09 ` [PATCH v1 2/4] iommu/arm-smmu-v3: " weimin xiong
@ 2026-07-14  6:09 ` weimin xiong
  2026-07-14  6:09 ` [PATCH v1 4/4] iommu/msm: Clean up probe state on registration failure weimin xiong
  2026-07-14 14:06 ` [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup Pranjal Shrivastava
  4 siblings, 0 replies; 7+ messages in thread
From: weimin xiong @ 2026-07-14  6:09 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel
  Cc: Benjamin Gaignard, Rob Clark, linux-arm-kernel, iommu,
	linux-kernel, linux-arm-msm, weimin xiong

bus_find_device_by_fwnode() returns a device with its reference count
incremented. vsi_iommu_get_from_dev() drops that reference before
reading the driver data, which leaves the returned pointer derived from
a device after its reference has been released.

Read the driver data before put_device(). Also make
vsi_iommu_probe_device() fail with -ENODEV when the IOMMU cannot be
found instead of dereferencing a NULL pointer.

Signed-off-by: weimin xiong <xiongwm2026@163.com>
---
 drivers/iommu/vsi-iommu.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/vsi-iommu.c b/drivers/iommu/vsi-iommu.c
index 42c424496..d19db561e 100644
--- a/drivers/iommu/vsi-iommu.c
+++ b/drivers/iommu/vsi-iommu.c
@@ -220,10 +220,15 @@ static struct vsi_iommu *vsi_iommu_get_from_dev(struct device *dev)
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct device *iommu_dev = bus_find_device_by_fwnode(&platform_bus_type,
 							     fwspec->iommu_fwnode);
+	struct vsi_iommu *iommu;
+
+	if (!iommu_dev)
+		return NULL;
 
+	iommu = dev_get_drvdata(iommu_dev);
 	put_device(iommu_dev);
 
-	return iommu_dev ? dev_get_drvdata(iommu_dev) : NULL;
+	return iommu;
 }
 
 static struct iommu_domain *vsi_iommu_domain_alloc_paging(struct device *dev)
@@ -619,6 +624,9 @@ static struct iommu_device *vsi_iommu_probe_device(struct device *dev)
 	struct vsi_iommu *iommu = vsi_iommu_get_from_dev(dev);
 	struct device_link *link;
 
+	if (!iommu)
+		return ERR_PTR(-ENODEV);
+
 	link = device_link_add(dev, iommu->dev,
 			       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
 	if (!link)
-- 
2.43.0



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

* [PATCH v1 4/4] iommu/msm: Clean up probe state on registration failure
  2026-07-14  6:09 [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup weimin xiong
                   ` (2 preceding siblings ...)
  2026-07-14  6:09 ` [PATCH v1 3/4] iommu/vsi: " weimin xiong
@ 2026-07-14  6:09 ` weimin xiong
  2026-07-14 14:06 ` [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup Pranjal Shrivastava
  4 siblings, 0 replies; 7+ messages in thread
From: weimin xiong @ 2026-07-14  6:09 UTC (permalink / raw)
  To: Will Deacon, Robin Murphy, Joerg Roedel
  Cc: Benjamin Gaignard, Rob Clark, linux-arm-kernel, iommu,
	linux-kernel, linux-arm-msm, weimin xiong

msm_iommu_probe() adds the IOMMU to qcom_iommu_devices before creating
the IOMMU sysfs device and registering the IOMMU. If either of those
later steps fails, the function returns without undoing the list
insertion. The iommu_device_register() failure path also leaves the
sysfs device behind.

Add shared error labels so the list entry and sysfs device are unwound
in the reverse order of setup.

Signed-off-by: weimin xiong <xiongwm2026@163.com>
---
 drivers/iommu/msm_iommu.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 0ad5ff431..d0d926be7 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -784,19 +784,25 @@ static int msm_iommu_probe(struct platform_device *pdev)
 				     "msm-smmu.%pa", &ioaddr);
 	if (ret) {
 		pr_err("Could not add msm-smmu at %pa to sysfs\n", &ioaddr);
-		return ret;
+		goto err_remove_list;
 	}
 
 	ret = iommu_device_register(&iommu->iommu, &msm_iommu_ops, &pdev->dev);
 	if (ret) {
 		pr_err("Could not register msm-smmu at %pa\n", &ioaddr);
-		return ret;
+		goto err_remove_sysfs;
 	}
 
 	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
 		iommu->base, iommu->irq, iommu->ncb);
 
 	return ret;
+
+err_remove_sysfs:
+	iommu_device_sysfs_remove(&iommu->iommu);
+err_remove_list:
+	list_del(&iommu->dev_node);
+	return ret;
 }
 
 static const struct of_device_id msm_iommu_dt_match[] = {
-- 
2.43.0



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

* Re: [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup
  2026-07-14  6:09 [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup weimin xiong
                   ` (3 preceding siblings ...)
  2026-07-14  6:09 ` [PATCH v1 4/4] iommu/msm: Clean up probe state on registration failure weimin xiong
@ 2026-07-14 14:06 ` Pranjal Shrivastava
  2026-07-14 15:56   ` Robin Murphy
  4 siblings, 1 reply; 7+ messages in thread
From: Pranjal Shrivastava @ 2026-07-14 14:06 UTC (permalink / raw)
  To: weimin xiong
  Cc: Will Deacon, Robin Murphy, Joerg Roedel, Benjamin Gaignard,
	Rob Clark, linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

On Tue, Jul 14, 2026 at 02:09:26PM +0800, weimin xiong wrote:
> Fix a few IOMMU driver lifetime and error-path issues found while
> auditing fwnode-based device lookup and probe cleanup paths.
> 
> The first three patches avoid deriving driver private data after
> dropping the device reference returned by bus_find_device_by_fwnode().
> They also make the ARM SMMU v2 and VSI probe paths fail cleanly when the
> IOMMU lookup fails.

I'm not sure if that's really needed? All these drivers are doing is
dropping the "extra" refcount (incremented by calling find_device)  back
to the state *before* the fwnode function call. If you find that this
put_device caused the count to drop to 0, I believe that's the real
problem/bug. These fwnode functions are usually called in probe and the
refcount shouldn't be 0 inside probe.

Could you share your observation / failing logs where this fails? Maybe
something else is wrong with the system?

Thanks,
Praan

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

* Re: [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup
  2026-07-14 14:06 ` [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup Pranjal Shrivastava
@ 2026-07-14 15:56   ` Robin Murphy
  0 siblings, 0 replies; 7+ messages in thread
From: Robin Murphy @ 2026-07-14 15:56 UTC (permalink / raw)
  To: Pranjal Shrivastava, weimin xiong
  Cc: Will Deacon, Joerg Roedel, Benjamin Gaignard, Rob Clark,
	linux-arm-kernel, iommu, linux-kernel, linux-arm-msm

On 14/07/2026 3:06 pm, Pranjal Shrivastava wrote:
> On Tue, Jul 14, 2026 at 02:09:26PM +0800, weimin xiong wrote:
>> Fix a few IOMMU driver lifetime and error-path issues found while
>> auditing fwnode-based device lookup and probe cleanup paths.
>>
>> The first three patches avoid deriving driver private data after
>> dropping the device reference returned by bus_find_device_by_fwnode().
>> They also make the ARM SMMU v2 and VSI probe paths fail cleanly when the
>> IOMMU lookup fails.
> 
> I'm not sure if that's really needed? All these drivers are doing is
> dropping the "extra" refcount (incremented by calling find_device)  back
> to the state *before* the fwnode function call. If you find that this
> put_device caused the count to drop to 0, I believe that's the real
> problem/bug. These fwnode functions are usually called in probe and the
> refcount shouldn't be 0 inside probe.
> 
> Could you share your observation / failing logs where this fails? Maybe
> something else is wrong with the system?

I don't have any trace of the original patches (thanks, Microsoft...) 
but looking on lore, yes these "lifetime" concerns are spurious; it's 
just a particular situation where due to the API, the drivers are taking 
a slightly roundabout route to look up their own valid device instance.

The IOMMU device must already have at least one held reference from way 
back in its device_initialise(), which will not be released unless and 
until device_unregister() is called (which is probably never for a 
non-hotpluggable platform device once it has been successfully created). 
If someone unregistered a platform device while it still had a driver 
bound, or the IOMMU driver could be unbound without unregistering the 
iommu_device through which its ->of_xlate or ->probe_device could be 
called, so many other things would be blowing up already that this would 
still be irrelevant.

Since 17de3f5fdd35 ("iommu: Retire bus ops") these lookups should also 
never return NULL for the same reasons, so do feel free to clean up 
those redundant checks if it helps make things a bit clearer.

Thanks,
Robin.

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

end of thread, other threads:[~2026-07-14 15:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14  6:09 [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup weimin xiong
2026-07-14  6:09 ` [PATCH v1 1/4] iommu/arm-smmu: Fix fwnode lookup lifetime handling weimin xiong
2026-07-14  6:09 ` [PATCH v1 2/4] iommu/arm-smmu-v3: " weimin xiong
2026-07-14  6:09 ` [PATCH v1 3/4] iommu/vsi: " weimin xiong
2026-07-14  6:09 ` [PATCH v1 4/4] iommu/msm: Clean up probe state on registration failure weimin xiong
2026-07-14 14:06 ` [PATCH v1 0/4] iommu: Fix device lookup lifetime and probe cleanup Pranjal Shrivastava
2026-07-14 15:56   ` Robin Murphy

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.