Re: [PATCH v2 0/2] iommu: Reserve PCI host bridge MMIO windows for IOVA

From: Robin Murphy

Date: Mon Sep 21 2026 - 07:29:56 EST


On 21/09/2026 11:39 am, Guanghui Feng wrote:
The DMA IOVA layer reserves PCI host bridge MMIO windows via
iova_reserve_pci_windows() to keep IOVA allocations from overlapping
those address ranges. As commit fade1ec055dc ("iommu/dma: Avoid PCI
host bridge windows") explains, a host bridge may interpret addresses
falling within its MMIO windows as peer-to-peer DMA, leading to
faults, data corruption, or DMA transactions being misrouted to the
wrong PCIe device. This is especially dangerous when a device sits
behind a PCIe switch and ACS Upstream Forwarding is not fully enabled.

Passthrough paths that let userspace pick IOVAs did not honour these
windows: VFIO type1 and iommufd only excluded IOMMU driver-level
reserved regions (RMRR, unity maps, MSI), not PCI host bridge MMIO
windows.

This was intentional - I forget where the exact discussion happened, but at the time we decided that exposing reserved regions for entire windows was the wrong thing to do, as being pessimistically inaccurate might be OK for the internal DMA API, but restricting userspace is another matter, and I think the consensus was that it wasn't really the IOMMU layer's job to get deep into PCI details anyway. Such "accidental" P2P can only happen within a group that's assigned to VFIO as a whole, so IIRC the conclusion was that users should already have enough information at the VFIO level to avoid BAR addresses if they need to.

In fact we did briefly do this once before, and it was explicitly undone again by cd2c9fcf5c66 ("iommu/dma: Move PCI window region reservation back into dma specific path."). I think there may also have been a practical issue with it breaking some standard Qemu setups.

Thanks,
Robin.


This series closes that gap:

Patch 1 adds a common helper, iommu_get_pci_resv_windows(), and
reserves PCI host bridge MMIO windows in
iommu_get_group_resv_regions() so all group-level consumers (VFIO
type1, sysfs reserved_regions) avoid them; iova_reserve_pci_windows()
is refactored to reuse the helper.

Patch 2 switches iommufd's iopt_table_enforce_dev_resv_regions() to
iommu_get_group_resv_regions() so IOMMU_IOAS_IOVA_RANGES also avoids
PCI host bridge MMIO windows, aligning iommufd with VFIO type1.

v1: https://lore.kernel.org/all/20260921070234.897736-1-guanghuifeng@xxxxxxxxxxxxxxxxx/

Changes since v1:
- v1 was a single patch; v2 is a two-patch series.
- Patch 1: build the reservations with iommu_insert_resv_region()
instead of list_add_tail(), so the group reserved list stays sorted
by start address and overlapping same-type regions are merged. The
helper now frees its partial list itself on error and leaves the
caller's list untouched.
- Patch 2 (new): reserve PCI host bridge MMIO windows for the iommufd
IOAS as well, so IOMMU_IOAS_IOVA_RANGES no longer reports IOVAs that
overlap PCI MMIO windows.

Notes on earlier automated review feedback:
- The size_t length of each window matches struct iommu_resv_region's
existing field type; no new truncation is introduced on 64-bit.
- An IOMMU group cannot span multiple PCI host bridges:
pci_device_group() only groups devices within a single host bridge
hierarchy, so scanning the first PCI device of the group is enough.

Guanghui Feng (2):
iommu: Reserve PCI host bridge MMIO windows in group reserved regions
iommufd: Reserve PCI host bridge MMIO windows in IOAS reserved regions

drivers/iommu/dma-iommu.c | 17 ++++--
drivers/iommu/iommu-priv.h | 11 ++++
drivers/iommu/iommu.c | 85 ++++++++++++++++++++++++++++
drivers/iommu/iommufd/io_pagetable.c | 15 ++++-
4 files changed, 121 insertions(+), 7 deletions(-)