mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/6] iommu/qcom: Misc Fixes
@ 2026-07-17 14:46 Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 1/6] iommu/qcom: Fix inverted fault report check in qcom_iommu_fault() Mukesh Ojha
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha

Series to address fixes in legacy qcom_iommu driver, it is based on top
of  https://lore.kernel.org/lkml/20260623071245.1985938-1-haoxiang_li2024@163.com/

Changes in v1: https://lore.kernel.org/lkml/20260623122034.1166295-1-mukesh.ojha@oss.qualcomm.com/
 - Used devm_pm_runtime_enable in 2/6 as per comment.
 - Dropped 6/8 and 8/8 from the last series.
 - Added R-b  and fixes tag.

Mukesh Ojha (6):
  iommu/qcom: Fix inverted fault report check in qcom_iommu_fault()
  iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe()
  iommu/qcom: Check pm_runtime_resume_and_get() return in probe
  iommu/qcom: Fix pgtbl_ops leak in qcom_iommu_init_domain() error path
  iommu/qcom: Publish pgtbl_ops before releasing init_mutex
  iommu/qcom: Enable clocks before hardware access in
    qcom_iommu_ctx_probe()

 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 31 ++++++++++++++++---------
 1 file changed, 20 insertions(+), 11 deletions(-)

-- 
2.53.0


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

* [PATCH v2 1/6] iommu/qcom: Fix inverted fault report check in qcom_iommu_fault()
  2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
@ 2026-07-17 14:46 ` Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 2/6] iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe() Mukesh Ojha
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha, Konrad Dybcio

report_iommu_fault() returns 0 when a fault handler successfully handles
the fault, and -ENOSYS when no handler is installed. The condition
'!report_iommu_fault()' evaluates to true (printing "Unhandled context
fault") precisely when the fault *was* handled, and stays silent when no
handler is present — the opposite of what is intended.

Remove the '!' so the driver logs unhandled faults correctly.

Fixes: 049541e178d5 ("iommu: qcom: wire up fault handler")
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 32efef69e72d..09f2ee6be988 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -200,7 +200,7 @@ static irqreturn_t qcom_iommu_fault(int irq, void *dev)
 	fsynr = iommu_readl(ctx, ARM_SMMU_CB_FSYNR0);
 	iova = iommu_readq(ctx, ARM_SMMU_CB_FAR);
 
-	if (!report_iommu_fault(ctx->domain, ctx->dev, iova, 0)) {
+	if (report_iommu_fault(ctx->domain, ctx->dev, iova, 0)) {
 		dev_err_ratelimited(ctx->dev,
 				    "Unhandled context fault: fsr=0x%x, "
 				    "iova=0x%016llx, fsynr=0x%x, cb=%d\n",
-- 
2.53.0


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

* [PATCH v2 2/6] iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe()
  2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 1/6] iommu/qcom: Fix inverted fault report check in qcom_iommu_fault() Mukesh Ojha
@ 2026-07-17 14:46 ` Mukesh Ojha
  2026-07-17 15:23   ` Konrad Dybcio
  2026-07-17 14:46 ` [PATCH v2 3/6] iommu/qcom: Check pm_runtime_resume_and_get() return in probe Mukesh Ojha
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha

Switch from pm_runtime_enable() to devm_pm_runtime_enable() so that
the matching pm_runtime_disable() is handled automatically via devres,
both on probe failure and on device removal.

This removes the err_pm_disable error label from the probe function and
the explicit pm_runtime_disable() call from qcom_iommu_device_remove().

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 09f2ee6be988..71251aecc292 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -836,20 +836,22 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, qcom_iommu);
 
-	pm_runtime_enable(dev);
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
 
 	/* register context bank devices, which are child nodes: */
 	ret = devm_of_platform_populate(dev);
 	if (ret) {
 		dev_err(dev, "Failed to populate iommu contexts\n");
-		goto err_pm_disable;
+		return ret;
 	}
 
 	ret = iommu_device_sysfs_add(&qcom_iommu->iommu, dev, NULL,
 				     dev_name(dev));
 	if (ret) {
 		dev_err(dev, "Failed to register iommu in sysfs\n");
-		goto err_pm_disable;
+		return ret;
 	}
 
 	ret = iommu_device_register(&qcom_iommu->iommu, &qcom_iommu_ops, dev);
@@ -868,8 +870,6 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 
 err_sysfs_remove:
 	iommu_device_sysfs_remove(&qcom_iommu->iommu);
-err_pm_disable:
-	pm_runtime_disable(dev);
 	return ret;
 }
 
-- 
2.53.0


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

* [PATCH v2 3/6] iommu/qcom: Check pm_runtime_resume_and_get() return in probe
  2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 1/6] iommu/qcom: Fix inverted fault report check in qcom_iommu_fault() Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 2/6] iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe() Mukesh Ojha
@ 2026-07-17 14:46 ` Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 4/6] iommu/qcom: Fix pgtbl_ops leak in qcom_iommu_init_domain() error path Mukesh Ojha
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha, Konrad Dybcio

The SMMU_INTR_SEL_NS register write in qcom_iommu_device_probe() uses
pm_runtime_get_sync() without checking the return value. If runtime
resume fails the subsequent writel_relaxed() would access hardware with
clocks potentially disabled.

Switch to pm_runtime_resume_and_get() which handles the usage-count
cleanup on failure, check the return value, and unwind the already
registered iommu device on error.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 71251aecc292..1d04f0a19124 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -861,13 +861,17 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 	}
 
 	if (qcom_iommu->local_base) {
-		pm_runtime_get_sync(dev);
+		ret = pm_runtime_resume_and_get(dev);
+		if (ret)
+			goto err_iommu_unregister;
 		writel_relaxed(0xffffffff, qcom_iommu->local_base + SMMU_INTR_SEL_NS);
 		pm_runtime_put_sync(dev);
 	}
 
 	return 0;
 
+err_iommu_unregister:
+	iommu_device_unregister(&qcom_iommu->iommu);
 err_sysfs_remove:
 	iommu_device_sysfs_remove(&qcom_iommu->iommu);
 	return ret;
-- 
2.53.0


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

* [PATCH v2 4/6] iommu/qcom: Fix pgtbl_ops leak in qcom_iommu_init_domain() error path
  2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
                   ` (2 preceding siblings ...)
  2026-07-17 14:46 ` [PATCH v2 3/6] iommu/qcom: Check pm_runtime_resume_and_get() return in probe Mukesh Ojha
@ 2026-07-17 14:46 ` Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 5/6] iommu/qcom: Publish pgtbl_ops before releasing init_mutex Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 6/6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe() Mukesh Ojha
  5 siblings, 0 replies; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha, Konrad Dybcio

alloc_io_pgtable_ops() can succeed and then qcom_scm_restore_sec_cfg()
can fail for one of the context banks. The goto out_clear_iommu path
only cleared qcom_domain->iommu; the locally allocated pgtbl_ops was
never freed, leaking it permanently since qcom_domain->pgtbl_ops is only
assigned on the success path.

free_io_pgtable_ops() safely handles a NULL argument (covers the case
where alloc_io_pgtable_ops() itself failed), so add it unconditionally in
the out_clear_iommu handler.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 1d04f0a19124..222bb7febd03 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -314,6 +314,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 	return 0;
 
 out_clear_iommu:
+	free_io_pgtable_ops(pgtbl_ops);
 	qcom_domain->iommu = NULL;
 out_unlock:
 	mutex_unlock(&qcom_domain->init_mutex);
-- 
2.53.0


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

* [PATCH v2 5/6] iommu/qcom: Publish pgtbl_ops before releasing init_mutex
  2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
                   ` (3 preceding siblings ...)
  2026-07-17 14:46 ` [PATCH v2 4/6] iommu/qcom: Fix pgtbl_ops leak in qcom_iommu_init_domain() error path Mukesh Ojha
@ 2026-07-17 14:46 ` Mukesh Ojha
  2026-07-17 14:46 ` [PATCH v2 6/6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe() Mukesh Ojha
  5 siblings, 0 replies; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha, Konrad Dybcio

qcom_domain->pgtbl_ops was assigned after mutex_unlock(). Another thread
calling qcom_iommu_init_domain() would see qcom_domain->iommu already set
(domain fully initialized) and skip re-initialization under the mutex.
If it then called qcom_iommu_map() before the first thread set pgtbl_ops,
it would observe a NULL ops pointer and return -ENODEV for valid mappings.

Move the assignment to before mutex_unlock() so that once the mutex is
released the domain is fully visible to concurrent operations.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 222bb7febd03..ecde5ca2d476 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -306,13 +306,12 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 		ctx->domain = domain;
 	}
 
-	mutex_unlock(&qcom_domain->init_mutex);
-
 	/* Publish page table ops for map/unmap */
 	qcom_domain->pgtbl_ops = pgtbl_ops;
 
-	return 0;
+	mutex_unlock(&qcom_domain->init_mutex);
 
+	return 0;
 out_clear_iommu:
 	free_io_pgtable_ops(pgtbl_ops);
 	qcom_domain->iommu = NULL;
-- 
2.53.0


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

* [PATCH v2 6/6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe()
  2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
                   ` (4 preceding siblings ...)
  2026-07-17 14:46 ` [PATCH v2 5/6] iommu/qcom: Publish pgtbl_ops before releasing init_mutex Mukesh Ojha
@ 2026-07-17 14:46 ` Mukesh Ojha
  5 siblings, 0 replies; 8+ messages in thread
From: Mukesh Ojha @ 2026-07-17 14:46 UTC (permalink / raw)
  To: Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel,
	linux-kernel, Mukesh Ojha, Konrad Dybcio

qcom_iommu_ctx_probe() reads and writes the CB_FSR register to clear any
stale IRQ left by the bootloader. This happens during
devm_of_platform_populate() which is called from the parent device's
probe before any pm_runtime_get(). The parent's clocks (iface, bus, tbu)
are therefore not guaranteed to be on, making the register access
unreliable on rebind or after a suspend cycle.

Use pm_runtime_resume_and_get() on the parent device to ensure clocks
are enabled before the register access, and release the reference
immediately after.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index ecde5ca2d476..5a9f8b39a99c 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -704,8 +704,13 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
 	/* clear IRQs before registering fault handler, just in case the
 	 * boot-loader left us a surprise:
 	 */
-	if (!ctx->secured_ctx)
+	if (!ctx->secured_ctx) {
+		ret = pm_runtime_resume_and_get(dev->parent);
+		if (ret)
+			return ret;
 		iommu_writel(ctx, ARM_SMMU_CB_FSR, iommu_readl(ctx, ARM_SMMU_CB_FSR));
+		pm_runtime_put_sync(dev->parent);
+	}
 
 	ret = devm_request_irq(dev, irq,
 			       qcom_iommu_fault,
-- 
2.53.0


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

* Re: [PATCH v2 2/6] iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe()
  2026-07-17 14:46 ` [PATCH v2 2/6] iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe() Mukesh Ojha
@ 2026-07-17 15:23   ` Konrad Dybcio
  0 siblings, 0 replies; 8+ messages in thread
From: Konrad Dybcio @ 2026-07-17 15:23 UTC (permalink / raw)
  To: Mukesh Ojha, Rob Clark, Will Deacon, Joerg Roedel (AMD), Alex Williamson
  Cc: Robin Murphy, iommu, linux-arm-msm, linux-arm-kernel, linux-kernel

On 7/17/26 4:46 PM, Mukesh Ojha wrote:
> Switch from pm_runtime_enable() to devm_pm_runtime_enable() so that
> the matching pm_runtime_disable() is handled automatically via devres,
> both on probe failure and on device removal.
> 
> This removes the err_pm_disable error label from the probe function and
> the explicit pm_runtime_disable() call from qcom_iommu_device_remove().
> 
> Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> ---

the single-use goto could be inlined now, but anyway

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>

Konrad

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

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

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-17 14:46 [PATCH v2 0/6] iommu/qcom: Misc Fixes Mukesh Ojha
2026-07-17 14:46 ` [PATCH v2 1/6] iommu/qcom: Fix inverted fault report check in qcom_iommu_fault() Mukesh Ojha
2026-07-17 14:46 ` [PATCH v2 2/6] iommu/qcom: Use devm_pm_runtime_enable() in qcom_iommu_device_probe() Mukesh Ojha
2026-07-17 15:23   ` Konrad Dybcio
2026-07-17 14:46 ` [PATCH v2 3/6] iommu/qcom: Check pm_runtime_resume_and_get() return in probe Mukesh Ojha
2026-07-17 14:46 ` [PATCH v2 4/6] iommu/qcom: Fix pgtbl_ops leak in qcom_iommu_init_domain() error path Mukesh Ojha
2026-07-17 14:46 ` [PATCH v2 5/6] iommu/qcom: Publish pgtbl_ops before releasing init_mutex Mukesh Ojha
2026-07-17 14:46 ` [PATCH v2 6/6] iommu/qcom: Enable clocks before hardware access in qcom_iommu_ctx_probe() Mukesh Ojha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox