Subject: [PATCH v3 00/32] iommu: introduce iova_to_phys_length and remove iova_to_phys

From: Guanghui Feng <[email-masked]>
Date: Wed, 3 Jun 2026 23:17:32 +0800

This series introduces a new iova_to_phys_length() interface to the IOMMU
subsystem, migrates all drivers and callers to it, and finally removes the
legacy iova_to_phys() interface.

Motivation
==========

The existing iommu_iova_to_phys() returns only the physical address for a
given IOVA. Callers that need to walk a range of IOVA space (most notably
VFIO and IOMMUFD during unmap) have no way to learn the size of the mapping
backing an IOVA, so they are forced to iterate in fixed PAGE_SIZE steps.
When the underlying mapping uses large pages (e.g. 2MB or 1GB), this results
in a separate page table walk for every 4KB, which is highly inefficient for
large regions.

iommu_iova_to_phys_length() returns both the physical address and the page
size of the PTE backing the IOVA in a single page table walk. Callers can
then advance by the actual mapping granularity instead of PAGE_SIZE,
dramatically reducing the number of page table walks during teardown of
large mappings.

The new helper translates a missing mapping to PHYS_ADDR_MAX (rather than 0)
so that a zero physical address can be distinguished from a translation
failure, and the legacy iommu_iova_to_phys() is reimplemented on top of it.

Approach
========

The series is structured to keep the tree bisectable at every step: the new
interface is added first with a fallback to the legacy callback, every
driver and caller is migrated, and only then is the old interface removed.

  - Core and page table layer (patches 1-5):
    Add iova_to_phys_length to iommu_domain_ops and io_pgtable_ops, the
    core iommu_iova_to_phys_length() helper with a fallback to the legacy
    iova_to_phys, and implement it in the io-pgtable arm, arm-v7s and dart
    formats as well as the generic_pt framework.

  - Driver migration (patches 6-22):
    Implement iova_to_phys_length in all remaining IOMMU drivers:
    arm-smmu-v3, arm-smmu, qcom_iommu, apple-dart, ipmmu-vmsa, mtk_iommu,
    exynos, fsl_pamu, msm, mtk_v1, omap, rockchip, s390, sprd, sun50i,
    tegra-smmu and virtio.

  - Caller migration (patches 23-28):
    Switch VFIO and IOMMUFD to iova_to_phys_length for efficient,
    granularity-aware unmap, update the iommufd selftest, migrate the
    DRM panfrost and panthor drivers, and switch the io-pgtable selftests
    to the new interface.

  - Removal (patches 29-32):
    Drop the now-unused iova_to_phys wrappers from the io-pgtable arm,
    arm-v7s and dart formats, and finally remove iova_to_phys from
    iommu_domain_ops and io_pgtable_ops.

No functional change is intended for translation results; the change is
purely about exposing mapping size and using it to make range operations
more efficient.

Guanghui Feng (32):
  iommu: introduce iova_to_phys_length in iommu_domain_ops
  iommu/io-pgtable-arm: introduce iova_to_phys_length in io_pgtable_ops
  iommu/io-pgtable-arm-v7s: introduce iova_to_phys_length in
    io_pgtable_ops
  iommu/io-pgtable-dart: introduce iova_to_phys_length in io_pgtable_ops
  iommu/generic_pt: implement iova_to_phys_length
  iommu/arm-smmu-v3: implement iova_to_phys_length
  iommu/arm-smmu: implement iova_to_phys_length
  iommu/qcom_iommu: implement iova_to_phys_length
  iommu/apple-dart: implement iova_to_phys_length
  iommu/ipmmu-vmsa: implement iova_to_phys_length
  iommu/mtk_iommu: implement iova_to_phys_length
  iommu/exynos: implement iova_to_phys_length
  iommu/fsl_pamu: implement iova_to_phys_length
  iommu/msm: implement iova_to_phys_length
  iommu/mtk_v1: implement iova_to_phys_length
  iommu/omap: implement iova_to_phys_length
  iommu/rockchip: implement iova_to_phys_length
  iommu/s390: implement iova_to_phys_length
  iommu/sprd: implement iova_to_phys_length
  iommu/sun50i: implement iova_to_phys_length
  iommu/tegra-smmu: implement iova_to_phys_length
  iommu/virtio: implement iova_to_phys_length
  vfio: use iova_to_phys_length for efficient unmap
  iommufd: use iova_to_phys_length for efficient unmap
  iommufd/selftest: switch to iommu_iova_to_phys_length
  drm/panfrost: switch to iova_to_phys_length
  drm/panthor: switch to iova_to_phys_length
  iommu/io-pgtable: selftests switch to iova_to_phys_length
  iommu/io-pgtable-arm: remove deprecated iova_to_phys wrapper
  iommu/io-pgtable-arm-v7s: remove deprecated iova_to_phys wrapper
  iommu/io-pgtable-dart: remove deprecated iova_to_phys wrapper
  iommu: remove iova_to_phys from domain_ops and io_pgtable_ops

 drivers/gpu/drm/panfrost/panfrost_mmu.c       |  2 +-
 drivers/gpu/drm/panthor/panthor_mmu.c         |  2 +-
 drivers/iommu/apple-dart.c                    | 11 +--
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 10 ++-
 .../iommu/arm/arm-smmu/arm-smmu-qcom-debug.c  |  2 +-
 drivers/iommu/arm/arm-smmu/arm-smmu.c         | 13 +--
 drivers/iommu/arm/arm-smmu/qcom_iommu.c       | 11 +--
 drivers/iommu/exynos-iommu.c                  | 20 +++--
 drivers/iommu/fsl_pamu_domain.c               | 26 +++++-
 drivers/iommu/generic_pt/iommu_pt.h           | 84 ++++++++++++++-----
 drivers/iommu/io-pgtable-arm-selftests.c      | 12 +--
 drivers/iommu/io-pgtable-arm-v7s.c            | 25 +++---
 drivers/iommu/io-pgtable-arm.c                | 16 ++--
 drivers/iommu/io-pgtable-dart.c               | 21 +++--
 drivers/iommu/iommu.c                         | 38 +++++++--
 drivers/iommu/iommufd/pages.c                 | 74 +++++++++++++---
 drivers/iommu/iommufd/selftest.c              |  2 +-
 drivers/iommu/ipmmu-vmsa.c                    | 10 ++-
 drivers/iommu/msm_iommu.c                     | 21 +++--
 drivers/iommu/mtk_iommu.c                     | 11 ++-
 drivers/iommu/mtk_iommu_v1.c                  | 13 ++-
 drivers/iommu/omap-iommu.c                    | 29 ++++---
 drivers/iommu/rockchip-iommu.c                | 10 ++-
 drivers/iommu/s390-iommu.c                    | 18 ++--
 drivers/iommu/sprd-iommu.c                    | 17 ++--
 drivers/iommu/sun50i-iommu.c                  | 14 ++--
 drivers/iommu/tegra-smmu.c                    | 11 ++-
 drivers/iommu/virtio-iommu.c                  | 12 ++-
 drivers/vfio/vfio_iommu_type1.c               | 27 ++++--
 include/linux/generic_pt/iommu.h              | 13 +--
 include/linux/io-pgtable.h                    | 11 ++-
 include/linux/iommu.h                         | 12 ++-
 32 files changed, 423 insertions(+), 175 deletions(-)

-- 
2.43.7