On 2026-07-02 11:28 PM, Narayana Murty N wrote:
> Add helper support for sPAPR TCE v2 DMA windows in the VFIO selftest
> library.
>
> Track the platform default DMA window separately from selftest-created
> dynamic DMA windows. The default window is discovered with
> VFIO_IOMMU_SPAPR_TCE_GET_INFO and is not removed during cleanup.
>
> Add helpers to create and remove DDWs, return the active IOVA range, and
> register/unregister memory around DMA map/unmap operations. Window
> selection is done before IOVA allocation; the map path only validates,
> registers memory, and calls VFIO_IOMMU_MAP_DMA.
>
> Signed-off-by: Narayana Murty N <[email protected]>
> +static int spapr_tce_read_default_window(struct iommu *iommu)
Please add vfio_iommu_*() prefix to these routines that wrap
VFIO_IOMMU_* ioctls.
e.g.
spapr_tce_read_default_window() -> vfio_iommu_spapr_tce_get_default()
spapr_tce_create_ddw() -> vfio_iommu_spapr_tce_create_window()
spapr_tce_remove_ddw() -> vfio_iommu_spapr_tce_remove_window()
spapr_register_memory() -> vfio_iommu_spapr_register_memory()
spapr_unregister_memory() -> vfio_iommu_spapr_unregister_memory()
This helps with readability since it makes it clear these functions are
interacting with the VFIO IOMMU driver.
> +{
> + struct vfio_iommu_spapr_tce_info info = {
> + .argsz = sizeof(info),
> + };
> +
> + if (iommu->default_window.valid)
> + return 0;
> +
> + if (ioctl(iommu->container_fd, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &info))
> + return -errno;
> +
> + iommu->default_window.start = info.dma32_window_start;
> + iommu->default_window.size = info.dma32_window_size;
> + iommu->default_window.page_shift = page_size_to_shift(getpagesize());
> + iommu->default_window.valid = true;
> + iommu->default_window.dynamic = false;
> + iommu->default_window.remove_on_cleanup = false;
> +
> + return 0;
> +}
> +
> +static int spapr_tce_create_ddw(struct iommu *iommu, u64 min_size, u32
> page_shift)
> +{
> + struct vfio_iommu_spapr_tce_create create = {
> + .argsz = sizeof(create),
> + .page_shift = page_shift,
> + .levels = 1,
> + .window_size = min_size,
> + };
> +
> + if (ioctl(iommu->container_fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create))
> + return -errno;
> +
> + iommu->ddw_window.start = create.start_addr;
> + iommu->ddw_window.size = create.window_size;
> + iommu->ddw_window.page_shift = page_shift;
> + iommu->ddw_window.valid = true;
> + iommu->ddw_window.dynamic = true;
> + iommu->ddw_window.remove_on_cleanup = true;
> +
> + return 0;
> +}
> +
> +static int spapr_tce_remove_window(struct iommu *iommu, struct
> spapr_tce_window *window)
> +{
> + struct vfio_iommu_spapr_tce_remove remove = {
> + .argsz = sizeof(remove),
> + .start_addr = window->start,
> + };
> +
> + if (!window->valid || !window->remove_on_cleanup)
> + return 0;
> +
> + if (ioctl(iommu->container_fd, VFIO_IOMMU_SPAPR_TCE_REMOVE, &remove))
> + return -errno;
> +
> + window->valid = false;
> + return 0;
> +}