From: Manish Honap <mhonap@nvidia.com>
vfio_container_region_add() attempts an IOMMU DMA mapping for every
RAM section that enters the guest address space. For VFIO mmap-backed
regions (PCI BAR windows, CXL.mem regions), this mapping always fails:
the backing VMAs carry VM_IO | VM_PFNMAP flags and pin_user_pages()
refuses to pin VM_IO pages, so IOMMU_IOAS_MAP returns -EFAULT.
CPU access to these regions goes through KVM Stage-2 page faults
independently of the SMMU/IOMMU, so no IOMMU entry is required for
correct operation.
Add an early return for RAM-device sections owned by a VFIO device.
vfio_get_vfio_device(memory_region_owner(section->mr)) returns non-NULL
for any mmap subregion created by vfio_region_mmap(), since
memory_region_init_ram_device_ptr() propagates the VFIOPCIDevice owner
from the containing region. Matching on ownership covers both normal
PCI BAR windows and CXL.mem regions uniformly; non-VFIO RAM-device
regions such as NVDIMMs are unaffected and continue through the normal
mapping path.
Signed-off-by: Manish Honap <mhonap@nvidia.com>
---
hw/vfio/listener.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
index 31c3113f8f..46cad18357 100644
--- a/hw/vfio/listener.c
+++ b/hw/vfio/listener.c
@@ -608,6 +608,20 @@ void vfio_container_region_add(VFIOContainer *bcontainer,
pgmask + 1);
return;
}
+
+ /*
+ * VFIO MMAP backed regions (CXL.mem) uses VM_IO | VM_PFNMAP VMAs
+ * backed by physical device addresses. Skip vfio_container_dma_map
+ * as mapping is not needed for this region.
+ */
+ if (vfio_get_vfio_device(memory_region_owner(section->mr))) {
+ trace_vfio_listener_region_add_no_dma_map(
+ memory_region_name(section->mr),
+ section->offset_within_address_space,
+ int128_getlo(section->size),
+ pgmask + 1);
+ return;
+ }
}
ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize),
--
2.25.1