Re: [PATCH v3 2/2] iommufd: Add IOMMU_GET_PCI_MMIO_WINDOWS ioctl

From: Jason Gunthorpe

Date: Thu Oct 22 2026 - 15:38:14 EST


On Mon, Oct 05, 2026 at 12:22:13AM +0800, Guanghui Feng wrote:
> +/**
> + * struct iommu_pci_mmio_window - a PCI host bridge MMIO window
> + * @start: First PCI bus address of the window
> + * @last: Inclusive last PCI bus address of the window
> + *
> + * A memory window claimed by the PCI host bridge that a device sits
> + * behind. Addresses are PCI bus addresses (i.e. what appears in the
> + * TLP), which differ from CPU physical addresses on platforms where the
> + * host bridge applies an address translation offset. For a device
> + * using an identity (1:1) IOVA layout the IOVA equals the bus address,
> + * so these are the IOVAs that a PCIe switch could misinterpret as
> + * peer-to-peer DMA and route to the wrong device instead of memory.

iommufd has no way to use devices that are not 1:1, don't talk about
this stuff in the kdocs.

> +/**
> + * struct iommu_pci_mmio_windows - ioctl(IOMMU_GET_PCI_MMIO_WINDOWS)
> + * @size: sizeof(struct iommu_pci_mmio_windows)
> + * @flags: Must be 0
> + * @dev_id: The device bound to iommufd to query
> + * @num_windows: Input/output number of MMIO windows
> + * @windows: Pointer to the output array of struct iommu_pci_mmio_window
> + *
> + * Query the memory windows of the PCI host bridge that @dev_id sits
> + * behind. This is advisory: the kernel does not reserve these ranges, it
> + * only reports them so userspace can choose to keep its IOVA allocations
> + * away from them and avoid accidental peer-to-peer DMA routing. The
> + * reported windows are pessimistic (the whole host bridge window, not the
> + * precise BAR ranges that may actually conflict). If a IOAS has devices
> + * behind multiple host bridges, query each device and take the union.

State clearly in the kdoc if the list is strictly non-overlapping, or
the list can have overlapping ranges. It makes a big difference to how
userspace has to process things.

> + * On input num_windows is the length of the windows array. On output it
> + * is the total number of windows. The ioctl will return -EMSGSIZE and set
> + * num_windows to the required value if num_windows is too small. In this
> + * case the caller should allocate a larger output array and re-issue the
> + * ioctl.
> + *
> + * Return: 0 on success, -EOPNOTSUPP if @dev_id is not a PCI device,
> + * -ENOENT if @dev_id is invalid, -EMSGSIZE if the output array is too
> + * small.
> + */
> +struct iommu_pci_mmio_windows {
> + __u32 size;
> + __u32 flags;
> + __u32 dev_id;
> + __u32 num_windows;
> + __aligned_u64 windows;

IIRC out_windows is the convention in iommufd

Jason