From: Sibi Sankar <sibi.sankar@oss.qualcomm.com>
To: robin.clark@oss.qualcomm.com, will@kernel.org, robin.murphy@arm.com
Cc: joro@8bytes.org, kees+treewide@kernel.org,
gregkh@linuxfoundation.org, dakr@kernel.org, panchuang@vivo.com,
prakash.gupta@oss.qualcomm.com, akaieurus@gmail.com,
iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH] iommu/arm-smmu: Work around Qualcomm SMMU-500 TLBIVAL granule issue
Date: Tue, 10 Nov 2026 03:52:14 +0530 [thread overview]
Message-ID: <20261109222214.3988154-1-sibi.sankar@oss.qualcomm.com> (raw)
From: Prakash Gupta <prakash.gupta@oss.qualcomm.com>
Qualcomm SMMU-500 has an issue with TLBIVA/TLBIVAL where only the
base-page-size entry at the base IOVA is invalidated, leaving stale
TLB entries for the rest of the range.
This causes use-after-free: after dma_free_coherent() unmaps a large
buffer, the device can still access freed physical memory through stale
TLB entries. On FastRPC workloads this manifests as ADSP crashes when
the ELF loader writes to a freed PA that has been reallocated.
Force the TLB invalidation step granule to the minimum page size for
all Qualcomm SMMU-500 domains, ensuring each page in the range is
individually invalidated. The minimum page size from pgsize_bitmap is
used rather than hardcoded 4K to correctly handle 16K and 64K granule
configurations.
This increases the number of TLB invalidation operations for large
ranges, but correctness takes precedence.
Signed-off-by: Prakash Gupta <prakash.gupta@oss.qualcomm.com>
Co-developed-by: Sibi Sankar <sibi.sankar@oss.qualcomm.com>
Signed-off-by: Sibi Sankar <sibi.sankar@oss.qualcomm.com>
---
drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 28 ++++++++++++++++++++++
drivers/iommu/arm/arm-smmu/arm-smmu.c | 3 +++
drivers/iommu/arm/arm-smmu/arm-smmu.h | 1 +
3 files changed, 32 insertions(+)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
index 795e8ec7e8fa..a51152b4e24b 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -430,6 +430,24 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = {
{ }
};
+static const char * const qcom_smmu_500_tlbival_errata[] = {
+ "qcom,eliza-smmu-500",
+ "qcom,glymur-smmu-500",
+ "qcom,hawi-smmu-500",
+ "qcom,ipq9650-smmu-500",
+ "qcom,kaanapali-smmu-500",
+ "qcom,maili-smmu-500",
+ "qcom,milos-smmu-500",
+ "qcom,nord-smmu-500",
+ "qcom,sdx75-smmu-500",
+ "qcom,shikra-smmu-500",
+ "qcom,sm8550-smmu-500",
+ "qcom,sm8650-smmu-500",
+ "qcom,sm8750-smmu-500",
+ "qcom,x1e80100-smmu-500",
+ NULL,
+};
+
static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
{
@@ -440,6 +458,16 @@ static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
+ /*
+ * Qualcomm SMMU-500 has an issue with TLBIVA/TLBIVAL where only
+ * the base-page-size entry at the base IOVA is invalidated. Force
+ * the minimum page granule on affected SoCs to ensure the full range
+ * is covered.
+ */
+ if (of_device_compatible_match(smmu->dev->of_node,
+ qcom_smmu_500_tlbival_errata))
+ smmu_domain->cfg.force_min_tlbival_granule = true;
+
client_match = qsmmu->data->client_match;
if (client_match)
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 8d50a4ad221d..92251536e9b0 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -286,6 +286,9 @@ static void arm_smmu_tlb_inv_range_s1(unsigned long iova, size_t size,
struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
int idx = cfg->cbndx;
+ if (cfg->force_min_tlbival_granule)
+ granule = 1UL << __ffs(smmu_domain->domain.pgsize_bitmap);
+
if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
wmb();
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.h b/drivers/iommu/arm/arm-smmu/arm-smmu.h
index 26d2e33cd328..85d1f2d7ec50 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -359,6 +359,7 @@ struct arm_smmu_cfg {
enum arm_smmu_cbar_type cbar;
enum arm_smmu_context_fmt fmt;
bool flush_walk_prefer_tlbiasid;
+ bool force_min_tlbival_granule;
};
#define ARM_SMMU_INVALID_IRPTNDX 0xff
base-commit: 630059a5a632377b9b7b487baccde92b7ae1dd47
--
2.34.1
reply other threads:[~2026-11-09 22:22 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109222214.3988154-1-sibi.sankar@oss.qualcomm.com \
--to=sibi.sankar@oss.qualcomm.com \
--cc=akaieurus@gmail.com \
--cc=dakr@kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=kees+treewide@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=panchuang@vivo.com \
--cc=prakash.gupta@oss.qualcomm.com \
--cc=robin.clark@oss.qualcomm.com \
--cc=robin.murphy@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®