When the kernel does not support the VFIO_DEVICE_FEATURE_DMA_BUF
feature (e.g. old kernel or out-of-tree vGPU driver),
vfio_region_create_dma_buf() returns with a warning and no fd is
assigned to the BAR RAMBlocks. Later, when the VFIO listener tries
to DMA-map these BAR regions, the iommufd backend falls back to
IOMMU_IOAS_MAP with a vaddr pointing at device MMIO. The kernel cannot
pin device memory and fails with EFAULT on aarch64, producing these
warnings:

  qemu-kvm: warning: VFIO dma-buf not supported in kernel, using mmap fallback, 
P2P DMA will not work
  qemu-kvm: warning: IOMMU_IOAS_MAP failed: Bad address, PCI BAR?
  qemu-kvm: warning: vfio_container_dma_map(0xaaabb9621a90, 0x88400000000, 
0x10000, 0xfffe50100000) = -14 (Bad address)
  hostdev0: PCI peer-to-peer transactions on BARs are not supported.

memory_region_set_skip_iommu_map() was recently introduced by commit
11b9798c7b52 ("memory: Allow RAM device regions to skip IOMMU
mapping") for the Tegra CMDQV case. Use it to mark BAR mmap regions
when dma-buf is unavailable so the VFIO listener skips them. This
drops the last three messages and covers both the iommufd and legacy
Type1 IOMMU backends.

Cc: Shameer Kolothum <[email protected]>
Cc: Nicolin Chen <[email protected]>
Cc: Eric Auger <[email protected]>
Fixes: 8cfaf22668c7 ("hw/vfio/region: Create dmabuf for PCI BAR per region")
Signed-off-by: Cédric Le Goater <[email protected]>
---
 hw/vfio/region.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/vfio/region.c b/hw/vfio/region.c
index 
996bc523edfe10bd256f5b09dec45cb5c9f543f0..4148d0ea8e35496e4c5a2bf97d1ef6974df7ccbb
 100644
--- a/hw/vfio/region.c
+++ b/hw/vfio/region.c
@@ -362,6 +362,9 @@ static bool vfio_region_create_dma_buf(VFIORegion *region, 
Error **errp)
         if (ret == -ENOTTY) {
             warn_report_once("VFIO dma-buf not supported in kernel, "
                              "using mmap fallback, P2P DMA will not work");
+            for (i = 0; i < region->nr_mmaps; i++) {
+                memory_region_set_skip_iommu_map(&region->mmaps[i].mem, true);
+            }
             return true;
         }
         error_setg_errno(errp, -ret, "%s: dma-buf unavailable, "
-- 
2.56.0


Reply via email to