drivers/iommu/rockchip-iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
When two masters share an IOMMU, calling ops->of_xlate during
the second master's driver init may overwrite iommu->domain set
by the first. This causes the check if (iommu->domain == domain)
in rk_iommu_attach_device() to fail, resulting in the same
iommu->node being added twice to &rk_domain->iommus, which can
lead to an infinite loop in subsequent &rk_domain->iommus operations.
Signed-off-by: Simon Xue <xxm@rock-chips.com>
---
drivers/iommu/rockchip-iommu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 22f74ba33a0e..e6bb3c784017 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1157,7 +1157,6 @@ static int rk_iommu_of_xlate(struct device *dev,
return -ENOMEM;
data->iommu = platform_get_drvdata(iommu_dev);
- data->iommu->domain = &rk_identity_domain;
dev_iommu_priv_set(dev, data);
platform_device_put(iommu_dev);
@@ -1195,6 +1194,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
if (!iommu)
return -ENOMEM;
+ iommu->domain = &rk_identity_domain;
+
platform_set_drvdata(pdev, iommu);
iommu->dev = dev;
iommu->num_mmu = 0;
--
2.34.1
On 2025-06-20 8:39 am, Simon Xue wrote: > When two masters share an IOMMU, calling ops->of_xlate during > the second master's driver init may overwrite iommu->domain set > by the first. This causes the check if (iommu->domain == domain) > in rk_iommu_attach_device() to fail, resulting in the same > iommu->node being added twice to &rk_domain->iommus, which can > lead to an infinite loop in subsequent &rk_domain->iommus operations. Indeed this is a property of the IOMMU instance itself so it really should be initialised before registration, irrespective of client devices. FWIW, if it's possible to take an unexpected RK_MMU_IRQ_PAGE_FAULT immediately after requesting the IRQ (e.g. in a kdump kernel after a crash with the hardware still running) then I think the current code could probably end up dereferencing NULL in report_iommu_fault() as well. Reviewed-by: Robin Murphy <robin.murphy@arm.com> And probably also: Cc: stable@vger.kernel.org Fixes: 25c2325575cc ("iommu/rockchip: Add missing set_platform_dma_ops callback") Thanks, Robin. > Signed-off-by: Simon Xue <xxm@rock-chips.com> > --- > drivers/iommu/rockchip-iommu.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c > index 22f74ba33a0e..e6bb3c784017 100644 > --- a/drivers/iommu/rockchip-iommu.c > +++ b/drivers/iommu/rockchip-iommu.c > @@ -1157,7 +1157,6 @@ static int rk_iommu_of_xlate(struct device *dev, > return -ENOMEM; > > data->iommu = platform_get_drvdata(iommu_dev); > - data->iommu->domain = &rk_identity_domain; > dev_iommu_priv_set(dev, data); > > platform_device_put(iommu_dev); > @@ -1195,6 +1194,8 @@ static int rk_iommu_probe(struct platform_device *pdev) > if (!iommu) > return -ENOMEM; > > + iommu->domain = &rk_identity_domain; > + > platform_set_drvdata(pdev, iommu); > iommu->dev = dev; > iommu->num_mmu = 0;
Hi Robin, >On 2025-06-20 8:39 am, Simon Xue wrote: >> When two masters share an IOMMU, calling ops->of_xlate during >> the second master's driver init may overwrite iommu->domain set >> by the first. This causes the check if (iommu->domain == domain) >> in rk_iommu_attach_device() to fail, resulting in the same >> iommu->node being added twice to &rk_domain->iommus, which can >> lead to an infinite loop in subsequent &rk_domain->iommus operations. > >Indeed this is a property of the IOMMU instance itself so it really >should be initialised before registration, irrespective of client >devices. FWIW, if it's possible to take an unexpected >RK_MMU_IRQ_PAGE_FAULT immediately after requesting the IRQ (e.g. in a >kdump kernel after a crash with the hardware still running) then I think >the current code could probably end up dereferencing NULL in >report_iommu_fault() as well. Thanks for your review and clear explanation, I will add the information as you suggested. Simon Xue > >Reviewed-by: Robin Murphy <robin.murphy@arm.com> > >And probably also: > >Cc: stable@vger.kernel.org >Fixes: 25c2325575cc ("iommu/rockchip: Add missing set_platform_dma_ops >callback") > >Thanks, >Robin. > >> Signed-off-by: Simon Xue <xxm@rock-chips.com> >> --- >> drivers/iommu/rockchip-iommu.c | 3 ++- >> 1 file changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c >> index 22f74ba33a0e..e6bb3c784017 100644 >> --- a/drivers/iommu/rockchip-iommu.c >> +++ b/drivers/iommu/rockchip-iommu.c >> @@ -1157,7 +1157,6 @@ static int rk_iommu_of_xlate(struct device *dev, >> return -ENOMEM; >> >> data->iommu = platform_get_drvdata(iommu_dev); >> - data->iommu->domain = &rk_identity_domain; >> dev_iommu_priv_set(dev, data); >> >> platform_device_put(iommu_dev); >> @@ -1195,6 +1194,8 @@ static int rk_iommu_probe(struct platform_device *pdev) >> if (!iommu) >> return -ENOMEM; >> >> + iommu->domain = &rk_identity_domain; >> + >> platform_set_drvdata(pdev, iommu); >> iommu->dev = dev; >> iommu->num_mmu = 0; > >
When two masters share an IOMMU, calling ops->of_xlate during
the second master's driver init may overwrite iommu->domain set
by the first. This causes the check if (iommu->domain == domain)
in rk_iommu_attach_device() to fail, resulting in the same
iommu->node being added twice to &rk_domain->iommus, which can
lead to an infinite loop in subsequent &rk_domain->iommus operations.
Fixes: 25c2325575cc ("iommu/rockchip: Add missing set_platform_dma_ops callback")
Signed-off-by: Simon Xue <xxm@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
v2:
No functional changes.
---
drivers/iommu/rockchip-iommu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 22f74ba33a0e..e6bb3c784017 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1157,7 +1157,6 @@ static int rk_iommu_of_xlate(struct device *dev,
return -ENOMEM;
data->iommu = platform_get_drvdata(iommu_dev);
- data->iommu->domain = &rk_identity_domain;
dev_iommu_priv_set(dev, data);
platform_device_put(iommu_dev);
@@ -1195,6 +1194,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
if (!iommu)
return -ENOMEM;
+ iommu->domain = &rk_identity_domain;
+
platform_set_drvdata(pdev, iommu);
iommu->dev = dev;
iommu->num_mmu = 0;
--
2.34.1
When two masters share an IOMMU, calling ops->of_xlate during
the second master's driver init may overwrite iommu->domain set
by the first. This causes the check if (iommu->domain == domain)
in rk_iommu_attach_device() to fail, resulting in the same
iommu->node being added twice to &rk_domain->iommus, which can
lead to an infinite loop in subsequent &rk_domain->iommus operations.
Cc: <stable@vger.kernel.org>
Fixes: 25c2325575cc ("iommu/rockchip: Add missing set_platform_dma_ops callback")
Signed-off-by: Simon Xue <xxm@rock-chips.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
v3:
Add missing `Cc: stable@vger.kernel.org` in commit message.
No functional changes.
v2:
No functional changes.
---
drivers/iommu/rockchip-iommu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
index 22f74ba33a0e..e6bb3c784017 100644
--- a/drivers/iommu/rockchip-iommu.c
+++ b/drivers/iommu/rockchip-iommu.c
@@ -1157,7 +1157,6 @@ static int rk_iommu_of_xlate(struct device *dev,
return -ENOMEM;
data->iommu = platform_get_drvdata(iommu_dev);
- data->iommu->domain = &rk_identity_domain;
dev_iommu_priv_set(dev, data);
platform_device_put(iommu_dev);
@@ -1195,6 +1194,8 @@ static int rk_iommu_probe(struct platform_device *pdev)
if (!iommu)
return -ENOMEM;
+ iommu->domain = &rk_identity_domain;
+
platform_set_drvdata(pdev, iommu);
iommu->dev = dev;
iommu->num_mmu = 0;
--
2.34.1
On Mon, Jun 23, 2025 at 10:00:18AM +0800, Simon Xue wrote: > When two masters share an IOMMU, calling ops->of_xlate during > the second master's driver init may overwrite iommu->domain set > by the first. This causes the check if (iommu->domain == domain) > in rk_iommu_attach_device() to fail, resulting in the same > iommu->node being added twice to &rk_domain->iommus, which can > lead to an infinite loop in subsequent &rk_domain->iommus operations. > > Cc: <stable@vger.kernel.org> > Fixes: 25c2325575cc ("iommu/rockchip: Add missing set_platform_dma_ops callback") > Signed-off-by: Simon Xue <xxm@rock-chips.com> > Reviewed-by: Robin Murphy <robin.murphy@arm.com> > > v3: > Add missing `Cc: stable@vger.kernel.org` in commit message. > No functional changes. > v2: > No functional changes. > --- > drivers/iommu/rockchip-iommu.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) Applied for -rc, thanks.
© 2016 - 2025 Red Hat, Inc.