Re: [PATCH v4 3/3] hw/vfio/region: Create dmabuf for PCI BAR per region
Cédric Le Goater <[email protected]> Wed, 5 Aug 2026 10:49:48 +0200
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
On 8/5/26 03:09, Gavin Shan wrote: > Hi Nicolin and Shameer, > > On 1/21/26 9:41 PM, Shameer Kolothum wrote: >> From: Nicolin Chen <[email protected]> >> >> Linux now provides a VFIO dmabuf exporter to expose PCI BAR memory for P2P >> use cases. Create a dmabuf for each mapped BAR region after the mmap is set >> up, and store the returned fd in the region’s RAMBlock. This allows QEMU to >> pass the fd to dma_map_file(), enabling iommufd to import the dmabuf and map >> the BAR correctly in the host IOMMU page table. >> >> If the kernel lacks support or dmabuf setup fails, QEMU skips the setup >> and continues with normal mmap handling. >> >> Tested-by: Nicolin Chen <[email protected]> >> Reviewed-by: Zhenzhong Duan <[email protected]> >> Reviewed-by: Cédric Le Goater <[email protected]> >> Signed-off-by: Nicolin Chen <[email protected]> >> Signed-off-by: Shameer Kolothum <[email protected]> >> --- >> hw/vfio/region.c | 65 +++++++++++++++++++++++++++++++++++++++++++- >> hw/vfio/trace-events | 1 + >> 2 files changed, 65 insertions(+), 1 deletion(-) >> >> diff --git a/hw/vfio/region.c b/hw/vfio/region.c >> index ca75ab1be4..ab39d77574 100644 >> --- a/hw/vfio/region.c >> +++ b/hw/vfio/region.c >> @@ -29,6 +29,7 @@ >> #include "qemu/error-report.h" >> #include "qemu/units.h" >> #include "monitor/monitor.h" >> +#include "system/ramblock.h" >> #include "vfio-helpers.h" >> /* >> @@ -238,13 +239,71 @@ static void vfio_subregion_unmap(VFIORegion *region, int index) >> region->mmaps[index].mmap = NULL; >> } >> +static bool vfio_region_create_dma_buf(VFIORegion *region, Error **errp) >> +{ >> + g_autofree struct vfio_device_feature *feature = NULL; >> + VFIODevice *vbasedev = region->vbasedev; >> + struct vfio_device_feature_dma_buf *dma_buf; >> + size_t total_size; >> + int i, ret; >> + >> + total_size = sizeof(*feature) + sizeof(*dma_buf) + >> + sizeof(struct vfio_region_dma_range) * region->nr_mmaps; >> + feature = g_malloc0(total_size); >> + *feature = (struct vfio_device_feature) { >> + .argsz = total_size, >> + .flags = VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_DMA_BUF, >> + }; >> + >> + dma_buf = (void *)feature->data; >> + *dma_buf = (struct vfio_device_feature_dma_buf) { >> + .region_index = region->nr, >> + .open_flags = O_RDWR, >> + .nr_ranges = region->nr_mmaps, >> + }; >> + >> + for (i = 0; i < region->nr_mmaps; i++) { >> + dma_buf->dma_ranges[i].offset = region->mmaps[i].offset; >> + dma_buf->dma_ranges[i].length = region->mmaps[i].size; >> + } >> + > > Shall we check if @offset and @size is aligned to PAGE_SIZE? If they're not, > I guess we need to skip populating DMA buffer instead of preventing the > device from being passed through to the guest. > > Meghana <[email protected]> runs into issue when passing through an NVMe > card. The only memory BAR on the NVMe card is 16K, which is not aligned to > 64KB (host page size). > > -device vfio-pci,id=nvme,host=0004:01:00.0,addr=0x2.0x1,bus=pcie.0 > > host$ sh vfio.sh > QEMU 10.1.0 monitor - type 'help' for more information > (qemu) qemu-kvm: -device vfio-pci,id=nvme,host=0004:01:00.0,addr=0x2.0x1,bus=pcie.0: \ > 0004:01:00.0 BAR 0: failed to create dma-buf: PCI BAR IOMMU mappings may fail: Invalid argument To avoid confusion, the reported error message was slightly improved in : https://lore.kernel.org/qemu-devel/[email protected]/ Thanks, C.