[PATCH v3 0/3] Apple M1 DART IOMMU driver

From: Sven Peter
Date: Thu Jun 03 2021 - 04:50:31 EST


This is v3 of my Apple M1 DART IOMMU driver series as a follow up to the original
two versions [1][2].

Short summary: this series adds support for the iommu found in Apple's new M1
SoC which is required to use DMA on most peripherals. So far this code has been
tested with dwc3 in host and device mode and PCIe on a M1 Mac Mini.

This IOMMU comes with a hard-wired pagesize of 16K. This makes booting a
kernel with 4K page challenging.

For dwc3 this is no issue: As long as the iommu is set to bypass mode
dwc3 works just fine. Translated mode isn't supported right now.

The most controversial part on which I'd like to get feedback are the
PCIe DARTs. These DARTs do not support hardware bypass mode and also limit
the iova space to 32 bit. To still allow booting on kernels with a 4K
pagesize I have introduced the following hack:

I program a static pagetable that maps the entire 32bit iova space to the
first 4GB of RAM starting at 0x8_0000_0000. Combined with an appropriate
dma-ranges property in the pcie node this allows to create a fake
bypass mode and successfully enables PCIe.
Right now the RAM offset is hardcoded in the DART driver and this will
likely have to change if this workaround is acceptable for now. I could
either introduce a separate property for the iommu node or try to grab
the offset from the dma-ranges once the first device is attached.

Changes for v3:
- fixed name of the iommu node in the device tree binding example
pointed out by Arnd Bergmann
- remove hardware specific checks from io-pgtable.c as pointed out by
Will Deacon
- introduced a fake bypass mode by programming static linear pagetables
if the DART does not support regular bypass mode as proposed by Alex
- added checks to enforce bypass mode if there is a pagesize mismatch
between the DART HW and the CPU.
- fixed usage of GFP_KERNEL during a held spinlock found by Julia Lawall
- rebased on v5.13-rc3

Changes for v2:
- fixed devicetree binding linting issues pointed out by Rob Herring and
reworked that file.
- made DART-specific code in io-pgtable.c unconditional and removed flag from
Kconfig as proposed by Robin Murphy.
- allowed multiple DART nodes in the "iommus" property as proposed by
Rob Herring and Robin Murphy. this resulted in significant changes
to apple-iommu-dart.c.
- the domain aperture is now forced to 32bit if translation is enabled after
the original suggestion to limit the aperture by Mark Kettenis and the
follow-up discussion and investigation with Mark Kettenis, Arnd Bergmann,
Robin Murphy and Rob Herring. This change also simplified the code
in io-pgtable.c and made some of the improvements suggested during review
not apply anymore.
- added support for bypassed and isolated domain modes.
- reject IOMMU_MMIO and IOMMU_NOEXEC since it's unknown how to set these up
for now or if the hardware even supports these flags.
- renamed some registers to be less confusing (mainly s/DOMAIN/STREAM/ to
prevent confusion with linux's iommu domain concept).

[1] v1: https://lore.kernel.org/linux-iommu/20210320151903.60759-1-sven@xxxxxxxxxxxxx/
[2] v2: https://lore.kernel.org/linux-iommu/20210328074009.95932-1-sven@xxxxxxxxxxxxx/

Sven Peter (3):
iommu: io-pgtable: add DART pagetable format
dt-bindings: iommu: add DART iommu bindings
iommu: dart: Add DART iommu driver

.../devicetree/bindings/iommu/apple,dart.yaml | 81 ++
drivers/iommu/Kconfig | 15 +
drivers/iommu/Makefile | 1 +
drivers/iommu/apple-dart-iommu.c | 966 ++++++++++++++++++
drivers/iommu/io-pgtable-arm.c | 62 ++
drivers/iommu/io-pgtable.c | 1 +
include/linux/io-pgtable.h | 7 +
8 files changed, 1140 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iommu/apple,dart.yaml
create mode 100644 drivers/iommu/apple-dart-iommu.c