> -----Original Message-----
> From: Cédric Le Goater <[email protected]>
> Sent: 15 January 2026 12:51
> To: Duan, Zhenzhong <[email protected]>; Shameer Kolothum
> <[email protected]>; [email protected]; qemu-
> [email protected]
> Cc: [email protected]; [email protected]; [email protected];
> [email protected]; Nicolin Chen <[email protected]>; Nathan Chen
> <[email protected]>; Matt Ochs <[email protected]>; Jason Gunthorpe
> <[email protected]>; Krishnakant Jaju <[email protected]>
> Subject: Re: [PATCH v2 4/4] hw/vfio/region: Create dmabuf for PCI BAR per
> region
> 

[...]

> > If you have next respin, maybe cleaner to move above dmabuf related code
> into
> >
> > vfio_region_create_dma_buf().
> 
> I agree. Can you please respin a v3 Shameer ?

Ok. Just to confirm, does below look good:

Thanks,
Shameer

...
diff --git a/hw/vfio/region.c b/hw/vfio/region.c
index ca75ab1be4..f927e64365 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,69 @@ static void vfio_subregion_unmap(VFIORegion *region, int 
index)
     region->mmaps[index].mmap = NULL;
 }

+static void vfio_region_create_dma_buf(VFIORegion *region)
+{
+    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;
+    }
+
+    ret = vfio_device_get_feature(vbasedev, feature);
+    if (ret < 0) {
+        if (ret == -ENOTTY) {
+            warn_report_once("VFIO dma-buf not supported in kernel: "
+                             "PCI BAR IOMMU mappings may fail");
+        } else {
+            error_report("%s: failed to create dma-buf (%s): "
+                         "PCI BAR IOMMU mappings may fail",
+                         memory_region_name(region->mem), strerror(errno));
+        }
+        /* P2P DMA or exposing device memory use cases are not supported. */
+        return;
+    }
+
+    /* Assign the dmabuf fd to associated RAMBlock */
+    for (i = 0; i < region->nr_mmaps; i++) {
+        MemoryRegion *mr = &region->mmaps[i].mem;
+        RAMBlock *ram_block = mr->ram_block;
+
+        ram_block->fd = ret;
+        ram_block->fd_offset = region->mmaps[i].offset;
+        trace_vfio_region_dmabuf(region->vbasedev->name, ret, region->nr,
+                                 memory_region_name(region->mem),
+                                 region->mmaps[i].offset,
+                                 region->mmaps[i].size);
+    }
+}
+
 int vfio_region_mmap(VFIORegion *region)
 {
     int i, ret, prot = 0;
     char *name;
     int fd;

-    if (!region->mem) {
+    if (!region->mem || !region->nr_mmaps) {
         return 0;
     }

@@ -305,6 +362,8 @@ int vfio_region_mmap(VFIORegion *region)
                                region->mmaps[i].size - 1);
     }

+    vfio_region_create_dma_buf(region);
+
     return 0;

 no_mmap:
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 180e3d526b..466695507b 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -118,6 +118,7 @@ vfio_device_put(int fd) "close vdev->fd=%d"
 vfio_region_write(const char *name, int index, uint64_t addr, uint64_t data, 
unsigned size) " (%s:region%d+0x%"PRIx64", 0x%"PRIx64 ", %d)"
 vfio_region_read(char *name, int index, uint64_t addr, unsigned size, uint64_t 
data) " (%s:region%d+0x%"PRIx64", %d) = 0x%"PRIx64
 vfio_region_setup(const char *dev, int index, const char *name, unsigned long 
flags, unsigned long offset, unsigned long size) "Device %s, region %d \"%s\", 
flags: 0x%lx, offset: 0x%lx, size: 0x%lx"
+vfio_region_dmabuf(const char *dev, int fd, int index,  const char *name, 
unsigned long offset, unsigned long size) "Device %s, dmabuf fd %d region %d 
\"%s\", offset: 0x%lx, size: 0x%lx"
 vfio_region_mmap_fault(const char *name, int index, unsigned long offset, 
unsigned long size, int fault) "Region %s mmaps[%d], [0x%lx - 0x%lx], fault: %d"
 vfio_region_mmap(const char *name, unsigned long offset, unsigned long end) 
"Region %s [0x%lx - 0x%lx]"
 vfio_region_exit(const char *name, int index) "Device %s, region %d"


Reply via email to