[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