[PATCH 07/11] iommu: Let 32-bit ARM drivers opt into a DMA API default domain
From: Mikko Perttunen
Date: Mon Sep 14 2026 - 22:17:27 EST
iommu_get_default_domain_type() unconditionally forces IDENTITY on
32-bit ARM as ARM_DMA_USE_IOMMU installs its own UNMANAGED domain on top
of whatever the group already had. Now that the ARM DMA API state is an
ordinary domain cookie, IOMMU drivers can ask for a real
IOMMU_DOMAIN_DMA default domain instead. Drop the override so that
->def_domain_type is honoured, and let a driver-requested DMA domain
through the !CONFIG_IOMMU_DMA guard when ARM_DMA_USE_IOMMU can back it.
IOMMU_DOMAIN_DMA stays strictly opt-in on 32-bit ARM and is never the
fallback to avoid unexpected changes, as drivers today return 0 from
->def_domain_type while expecting the legacy behaviour.
Behaviour is therefore unchanged for every existing 32-bit ARM IOMMU
driver:
- exynos-iommu, omap-iommu, rockchip-iommu, msm_iommu, ipmmu-vmsa,
mtk_iommu*, sun50i-iommu and qcom_iommu have no ->def_domain_type,
so iommu_get_def_domain_type() returns the unchanged cur_type of 0,
which is forced to IDENTITY as before.
- arm-smmu returns IDENTITY for legacy bindings and 0 otherwise, which
ends up in the same place.
- tegra-smmu returns IDENTITY explicitly, and keeps doing so until a
later patch.
Also move the static_assert on the two DMA API implementations being
mutually exclusive to drivers/iommu/dma-iommu.h, next to the
declarations that depend on it.
Signed-off-by: Mikko Perttunen <mperttunen@xxxxxxxxxx>
---
drivers/iommu/dma-iommu.h | 3 +++
drivers/iommu/iommu.c | 20 +++++---------------
2 files changed, 8 insertions(+), 15 deletions(-)
diff --git a/drivers/iommu/dma-iommu.h b/drivers/iommu/dma-iommu.h
index 71b23cb698c0..24fa4165450f 100644
--- a/drivers/iommu/dma-iommu.h
+++ b/drivers/iommu/dma-iommu.h
@@ -12,6 +12,9 @@
* IOMMU_DOMAIN_DMA default domains. Only one provider can be compiled in at a
* time.
*/
+static_assert(!(IS_ENABLED(CONFIG_IOMMU_DMA) &&
+ IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)));
+
#if defined(CONFIG_ARM_DMA_USE_IOMMU)
#include <asm/dma-iommu.h>
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 43dd69662fac..6b4c328852db 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1884,18 +1884,6 @@ static int iommu_get_default_domain_type(struct iommu_group *group,
lockdep_assert_held(&group->mutex);
- /*
- * ARM32 drivers supporting CONFIG_ARM_DMA_USE_IOMMU can declare an
- * identity_domain and it will automatically become their default
- * domain. Later on ARM_DMA_USE_IOMMU will install its UNMANAGED domain.
- * Override the selection to IDENTITY.
- */
- if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
- static_assert(!(IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) &&
- IS_ENABLED(CONFIG_IOMMU_DMA)));
- driver_type = IOMMU_DOMAIN_IDENTITY;
- }
-
for_each_group_device(group, gdev) {
driver_type = iommu_get_def_domain_type(group, gdev->dev,
driver_type);
@@ -1913,11 +1901,13 @@ static int iommu_get_default_domain_type(struct iommu_group *group,
/*
* If the common dma ops are not selected in kconfig then we cannot use
- * IOMMU_DOMAIN_DMA at all. Force IDENTITY if nothing else has been
- * selected.
+ * IOMMU_DOMAIN_DMA at all, unless this is ARM32 and the driver asked
+ * for it explicitly, where CONFIG_ARM_DMA_USE_IOMMU provides the
+ * implementation. Force IDENTITY if nothing else has been selected.
*/
if (!IS_ENABLED(CONFIG_IOMMU_DMA)) {
- if (WARN_ON(driver_type == IOMMU_DOMAIN_DMA))
+ if (WARN_ON(driver_type == IOMMU_DOMAIN_DMA &&
+ !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)))
return -1;
if (!driver_type)
driver_type = IOMMU_DOMAIN_IDENTITY;
--
2.55.0