On 1/15/26 15:32, Shameer Kolothum wrote:
-----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:
it does.
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)
+{
While at changing things, could you please add an 'Error** errp'
parameter to vfio_region_create_dma_buf() and make it return a
bool.
+ 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 = ®ion->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);
+
vfio_region_mmap() would then test the returned value and call
error_report_err() on the error.
In follow-ups patches, we could propagate this error to callers
of vfio_region_mmap(). Can come later.
Thanks,
C.
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"