Re: [PATCH v4 3/3] hw/vfio/region: Create dmabuf for PCI BAR per region

Gavin Shan <[email protected]> Wed, 5 Aug 2026 19:45:55 +1000
Newsgroups org.nongnu.qemu-arm,org.nongnu.qemu-devel
Message-ID <[email protected]>
On 8/5/26 6:49 PM, Cédric Le Goater wrote:
> 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]/
> 

Yeah, the warning message was reported from our downstream QEMU where this
commit (for the improved messages) isn't there yet.

> Thanks,
> 
> C.
> 

Thanks,
Gavin