[PATCH v3 07/10] iommu: Enable DMA default domains on (most) 32-bit ARM platforms
Mikko Perttunen
mperttunen at nvidia.com
Mon Oct 26 02:19:32 PDT 2026
iommu_get_default_domain_type currently forces an IDENTITY domain type
with CONFIG_ARM_DMA_USE_IOMMU because the ARM DMA implementation
traditionally installs its own UNMANAGED domains.
The ARM DMA implementation now supports core-owned DMA default domains,
so remove that override and follow the same logic as CONFIG_IOMMU_DMA
platforms. The static assertion making CONFIG_ARM_DMA_USE_IOMMU and
CONFIG_IOMMU_DMA mutually exclusive is removed as both now implement the
same callbacks making the build fail anyway.
Based on LLM eyeballing, some platforms are still not ready to be
switched over. For these platforms, a def_domain_type callback returning
IDENTITY is added unless it was already there. Specifically,
- mtk_iommu_v1 only supports the domain it internally creates via the
arm_iommu API
- ipmmu-vmsa creates its own shared ARM DMA domain. Also creating a
default DMA domain would exhaust contexts on configurations with only
one context
- omap-iommu among other things due to the omap remoteproc driver,
which relies on detaching the legacy ARM DMA domain to restore direct
DMA ops
- msm_iommu expects previous context assignments to be released
before attaching another paging domain
These drivers can be migrated later.
Signed-off-by: Mikko Perttunen <mperttunen at nvidia.com>
---
drivers/iommu/iommu.c | 20 ++++----------------
drivers/iommu/ipmmu-vmsa.c | 6 ++++++
drivers/iommu/msm_iommu.c | 6 ++++++
drivers/iommu/mtk_iommu_v1.c | 6 ++++++
drivers/iommu/omap-iommu.c | 6 ++++++
5 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 5fbb76d44a1e..e47f95fea44d 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);
@@ -1912,11 +1900,11 @@ 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.
+ * Without an IOMMU DMA implementation, force IDENTITY if the driver
+ * has not selected a domain type.
*/
- if (!IS_ENABLED(CONFIG_IOMMU_DMA)) {
+ if (!IS_ENABLED(CONFIG_IOMMU_DMA) &&
+ !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) {
if (WARN_ON(driver_type == IOMMU_DOMAIN_DMA))
return -1;
if (!driver_type)
diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c
index 9386b752dea2..39dddc3467a2 100644
--- a/drivers/iommu/ipmmu-vmsa.c
+++ b/drivers/iommu/ipmmu-vmsa.c
@@ -873,8 +873,14 @@ static void ipmmu_release_device(struct device *dev)
arm_iommu_release_mapping(mmu->mapping);
}
+static int ipmmu_def_domain_type(struct device *dev)
+{
+ return IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) ? IOMMU_DOMAIN_IDENTITY : 0;
+}
+
static const struct iommu_ops ipmmu_ops = {
.identity_domain = &ipmmu_iommu_identity_domain,
+ .def_domain_type = ipmmu_def_domain_type,
.domain_alloc_paging = ipmmu_domain_alloc_paging,
.probe_device = ipmmu_probe_device,
.release_device = ipmmu_release_device,
diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c
index 4ef1e8c8244b..7d7e91ffbf68 100644
--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -691,8 +691,14 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id)
return 0;
}
+static int msm_iommu_def_domain_type(struct device *dev)
+{
+ return IOMMU_DOMAIN_IDENTITY;
+}
+
static struct iommu_ops msm_iommu_ops = {
.identity_domain = &msm_iommu_identity_domain,
+ .def_domain_type = msm_iommu_def_domain_type,
.domain_alloc_paging = msm_iommu_domain_alloc_paging,
.probe_device = msm_iommu_probe_device,
.device_group = generic_device_group,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index e907c9953142..8d8235f55050 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -578,8 +578,14 @@ static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data)
return 0;
}
+static int mtk_iommu_v1_def_domain_type(struct device *dev)
+{
+ return IOMMU_DOMAIN_IDENTITY;
+}
+
static const struct iommu_ops mtk_iommu_v1_ops = {
.identity_domain = &mtk_iommu_v1_identity_domain,
+ .def_domain_type = mtk_iommu_v1_def_domain_type,
.domain_alloc_paging = mtk_iommu_v1_domain_alloc_paging,
.probe_device = mtk_iommu_v1_probe_device,
.probe_finalize = mtk_iommu_v1_probe_finalize,
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index 8231d7d6bb6a..56cdc4c670c0 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1712,8 +1712,14 @@ static int omap_iommu_of_xlate(struct device *dev, const struct of_phandle_args
return 0;
}
+static int omap_iommu_def_domain_type(struct device *dev)
+{
+ return IOMMU_DOMAIN_IDENTITY;
+}
+
static const struct iommu_ops omap_iommu_ops = {
.identity_domain = &omap_iommu_identity_domain,
+ .def_domain_type = omap_iommu_def_domain_type,
.domain_alloc_paging = omap_iommu_domain_alloc_paging,
.probe_device = omap_iommu_probe_device,
.release_device = omap_iommu_release_device,
--
2.55.0
More information about the linux-arm-kernel
mailing list