[PATCH 1/3] iommu/qcom: Invalidate the TLB in flush_iotlb_all

Dmitry Baryshkov dmitry.baryshkov at oss.qualcomm.com
Fri Oct 30 15:04:57 PDT 2026


qcom_iommu_flush_iotlb_all() only waits for a TLB sync and never
invalidates anything. iommu_unmap() users do not notice, since
io-pgtable invalidates each page through the gather, but drm/msm unmaps
with a NULL gather and relies on flush_iotlb_all. On db410c the GPU then
hangs on stale TLB entries as soon as another process reuses the IOVAs.

Invalidate the whole context, as arm-smmu does, and keep iotlb_sync a
plain sync.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov at oss.qualcomm.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index 21d18ce67b98..54130c32056a 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -479,14 +479,22 @@ static void qcom_iommu_flush_iotlb_all(struct iommu_domain *domain)
 		return;
 
 	pm_runtime_get_sync(qcom_domain->iommu->dev);
-	qcom_iommu_tlb_sync(pgtable->cookie);
+	qcom_iommu_tlb_inv_context(pgtable->cookie);
 	pm_runtime_put_sync(qcom_domain->iommu->dev);
 }
 
 static void qcom_iommu_iotlb_sync(struct iommu_domain *domain,
 				  struct iommu_iotlb_gather *gather)
 {
-	qcom_iommu_flush_iotlb_all(domain);
+	struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
+	struct io_pgtable *pgtable = container_of(qcom_domain->pgtbl_ops,
+						  struct io_pgtable, ops);
+	if (!qcom_domain->pgtbl_ops)
+		return;
+
+	pm_runtime_get_sync(qcom_domain->iommu->dev);
+	qcom_iommu_tlb_sync(pgtable->cookie);
+	pm_runtime_put_sync(qcom_domain->iommu->dev);
 }
 
 static phys_addr_t qcom_iommu_iova_to_phys(struct iommu_domain *domain,

-- 
2.47.3




More information about the linux-arm-kernel mailing list