[PATCH v3 00/10] Make the 32-bit ARM DMA API work with normal IOMMU DMA default domains (+ Tegra PoC)

From: Mikko Perttunen

Date: Mon Oct 26 2026 - 05:22:33 EST


Depending on the probe ordering, TegraDRM does not currently probe on
kernels with CONFIG_ARM_DMA_USE_IOMMU enabled, such as with
multi_v7_defconfig. The Tegra SMMU puts several display and 2D/3D
clients into one IOMMU group, and the legacy 32-bit ARM DMA API path
creates one UNMANAGED domain per device and attaches it with
iommu_attach_device(). That only works for one device per group, so
every client after the first fails to attach,
iommu_device_use_default_domain() rejects the group with -EBUSY, and the
driver goes down with it. tegra_defconfig is currently working by virtue
of not enabling CONFIG_ARM_DMA_USE_IOMMU.

Robin suggested [1] that instead of teaching the legacy path about
groups, we should explore modernizing the 32-bit ARM DMA code a bit by
making it use domain cookies and have the core code own the domains, as
is the case on other architectures. Still, ARM's own DMA code is kept to
support existing drivers and APIs that expect it, and because dma-iommu
is considered too big and unnecessary for 32-bit ARM.

The series is in four parts:

- Patches 1-2 are preparation in the IOMMU core:
1. Add iommu_teardown_dma_ops, counterpart to iommu_setup_dma_ops.
2. Add cookie type for ARM's DMA domains.
- Patches 3-6 implement the DMA API side on 32-bit ARM:
3. Split up mapping alloc and init (bitmap alloc) code to separate
functions.
4. Implement parallel dma_ops / cookie APIs on ARM side.
5. Avoid domain allocation when IOMMU core does it.
6. Check upper DMA range limit during IOVA allocation.
- Patch 7 removes the forced IDENTITY default domain in core IOMMU
code and adds explicit IDENTITY defaults to a few individual IOMMU
drivers.
- Patches 8-10 convert Tegra:
8. Fixes device parameter in calls to dma_get_sgtable.
9. Allows deferring translation enable until driver handshake for
selected devices.
10. Switches to DMA default domain for selected Tegra devices.

This moves 32-bit ARM devices from the unmanaged IOMMU DMA domain to the
core-owned default DMA domain except for mtk_iommu_v1, ipmmu-vmsa,
omap-iommu, and msm_iommu. (tegra-smmu also stays on the legacy path
until the last patch in the series.) See commit 7 for further
information. Existing drivers are intended to continue working without
changes.

Patches 8-10 are provided for demonstration; we can deal with them
separately if the rest of the series is accepted.

Patches 1,2,3,6 are applicable independently.
Patches 4,5 depend on the previous patches.
Patch 7 requires the prior patches to be in place.

Patches 1-7 only touch drivers/iommu/ and arch/arm/mm/ and associated
headers.

Best regards,
Mikko

[1] https://lore.kernel.org/linux-tegra/910d1492-ad3b-4201-93c6-208be1dcde7d@xxxxxxx/

---
Changes in v3:
- Removed the forced IDENTITY default domain workaround from IOMMU core.
Explicit IDENTITY default kept for a few IOMMU drivers.
- Keep the arm_iommu_* APIs usable with DMA default domains. Drop
related Host1x/TegraDRM cleanup patches. Detaching an explicitly
created mapping restores the default domain.
- Install and clear DMA ops in iommu_setup/teardown_dma_ops for
core-owned domains.
- Use iommu_is_dma_domain instead of custom flag to distinguish between
core-owned domains and unmanaged DMA domains.
- Allocate IOVA bookkeeping in iommu_setup_dma_ops, after attachment
has established domain geometry.
- Add an upper-bound check during IOVA allocation to replace setup-time
dma-ranges based check.
- Remove change to arm_iommu_get_sgtable in favor of correct fix in
TegraDRM.
- Simplify tegra_smmu_def_domain_type.
- Link to v2: https://patch.msgid.link/20261016-b4-arm32-iommu-dma-cookie-v2-0-b06842a01938@xxxxxxxxxx

Changes in v2:
- Addressed sashiko comments:
- We still don't take device tree dma-ranges into account for the allocatable
IOVA range. This is closer to arm64 and only some OMAP5 devices currently
have dma-ranges where this would matter. A check is added to error out in
such cases. As in v1, this code path is only active when enabled by the
IOMMU driver so there is no breakage.
- Added a check in tegra_smmu_enable_translation to return early if the IOMMU
attached to the device is not a tegra-smmu.
- Added .release_domain in tegra-smmu to handle address space release for DMA
domains.
- Link to v1: https://patch.msgid.link/20260915-b4-arm32-iommu-dma-cookie-v1-0-ba4f9d33a2b8@xxxxxxxxxx

---
Mikko Perttunen (10):
iommu: Add iommu_teardown_dma_ops
iommu: Add cookie type for ARM_DMA_USE_IOMMU
ARM: dma-mapping: Split mapping initialization from allocation
ARM: dma-mapping: Implement and expose DMA setup functions
ARM: dma-mapping: Bypass the legacy path for core-owned DMA API domains
ARM: dma-mapping: Bound IOVA allocation by device DMA limits
iommu: Enable DMA default domains on (most) 32-bit ARM platforms
drm/tegra: Fix device parameter to dma_get_sgtable
iommu/tegra-smmu: Defer display client translation to driver handover
iommu/tegra-smmu: Use a DMA API default domain per swgroup

arch/arm/include/asm/dma-iommu.h | 9 ++
arch/arm/mm/dma-mapping.c | 297 +++++++++++++++++++++++++++++----------
drivers/gpu/drm/tegra/dc.c | 8 ++
drivers/gpu/drm/tegra/gem.c | 5 +-
drivers/iommu/Kconfig | 1 +
drivers/iommu/dma-iommu.c | 5 +
drivers/iommu/dma-iommu.h | 49 +++++--
drivers/iommu/iommu.c | 24 +---
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 +
drivers/iommu/tegra-smmu.c | 103 +++++++++++++-
drivers/memory/tegra/tegra114.c | 15 +-
drivers/memory/tegra/tegra124.c | 12 +-
drivers/memory/tegra/tegra210.c | 6 +-
drivers/memory/tegra/tegra30.c | 18 ++-
include/linux/iommu.h | 3 +
include/soc/tegra/mc.h | 20 +++
19 files changed, 467 insertions(+), 132 deletions(-)
---
base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
change-id: 20260728-b4-arm32-iommu-dma-cookie-3170e07f9125