[PATCH 3/4] iommu/exynos: fix TLB invalidation for no-block SysMMUs

From: Markuss Broks via B4 Relay

Date: Thu Aug 20 2026 - 15:16:30 EST


From: Markuss Broks <markuss.broks@xxxxxxxxx>

sysmmu_block() polls MMU_STATUS for the blocked state, which no-block
hardware never reports, so on such SysMMUs it always fails, and both
sysmmu_tlb_invalidate_entry() and sysmmu_tlb_invalidate_flpdcache()
skip the invalidation entirely when blocking fails.

On no-block hardware the invalidation registers are written with the
MMU running; the vendor driver never blocks around invalidation. Do
the same and write the invalidation directly. In the FLPD cache path
no-block implies a v7+ SysMMU, hence the unconditional flush-all.

Signed-off-by: Markuss Broks <markuss.broks@xxxxxxxxx>
---
drivers/iommu/exynos-iommu.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index a3a59d8a4cf1..29b27c7e400a 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -685,7 +685,14 @@ static void sysmmu_tlb_invalidate_flpdcache(struct sysmmu_drvdata *data,
spin_lock_irqsave(&data->lock, flags);
if (data->active && data->version >= MAKE_MMU_VER(3, 3)) {
clk_enable(data->clk_master);
- if (sysmmu_block(data)) {
+ /*
+ * No-block hardware accepts invalidation writes while the
+ * MMU is running; it is also v7+, so flush-all covers the
+ * FLPD cache.
+ */
+ if (data->no_block) {
+ __sysmmu_tlb_invalidate(data);
+ } else if (sysmmu_block(data)) {
if (data->version >= MAKE_MMU_VER(5, 0))
__sysmmu_tlb_invalidate(data);
else
@@ -721,7 +728,9 @@ static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
if (MMU_MAJ_VER(data->version) == 2)
num_inv = min_t(unsigned int, size / SPAGE_SIZE, 64);

- if (sysmmu_block(data)) {
+ if (data->no_block) {
+ __sysmmu_tlb_invalidate_entry(data, iova, num_inv);
+ } else if (sysmmu_block(data)) {
__sysmmu_tlb_invalidate_entry(data, iova, num_inv);
sysmmu_unblock(data);
}

--
2.55.0