* [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu
@ 2026-03-11 2:50 Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 01/10] virtio-gpu: Recreate the resource's dmabuf if new backing is attached Vivek Kasireddy
` (9 more replies)
0 siblings, 10 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater, Dongwon Kim
The virtio-gpu driver running in the Guest VM can create Guest blob
resources (by importing dmabufs) that are backed by System RAM. This
is made possible by making use of memfd memory backend and udmabuf
driver on the Host side. However, in order to create Guest blobs
that are backed by vfio-pci device regions (which happens when
virtio-gpu imports dmabufs from devices that have local memory such
as dGPU VFs), we have to add support for creating dmabuf from multiple
VFIO device ranges (same region) and leverage it in virtio-gpu.
So, while creating the blobs we first try to create a dmabuf by
calling into the udmabuf driver assuming that the backing memory
is memfd based. If that fails, and if it is determined that the blob
is backed by a vfio-pci device region, we would then call into the
vfio-pci driver to have a dmabuf fd created.
Changelog:
v10 -> v11:
- Have virtio_gpu_remap_dmabuf() and vfio_device_mmap_dmabuf()
return the mapped pointer on success and NULL on error (Akihiko)
v9 -> v10:
- Adopt the logic structure and style recommended by Akihiko in
virtio_gpu_init_dmabuf() while creating and mmaping dmabuf
- Destroy the dmabuf by calling virtio_gpu_destroy_dmabuf() if
mmap fails
- Set res->dmabuf_fd to -1 after closing it to improve consistency
v8 -> v9:
- Replace VFIO_DMABUF_CREATE_GUEST_ERROR/VFIO_DMABUF_CREATE_HOST_ERROR
with VFIO_DMABUF_CREATE_ERR_INVALID_IOV/VFIO_DMABUF_CREATE_ERR_UNSPEC
(Akihiko)
- Drop the error_prepend() in virtio_gpu_init_dmabuf() (Akihiko)
- Improve the logic structure in virtio_gpu_init_dmabuf() by calling
the map memory function immediately after creating the dmabuf
in both memfd/udmabuf and VFIO cases (Akihiko)
v7 -> v8:
- Move the error enum to vfio and include only negative values (Akihiko)
- Reuse the same VFIO err enum to categorize Guest/Host errors in
virtio_gpu_create_udmabuf() (Akihiko)
- Make the error messages more descriptive and readable (Akihiko)
- Do not print any error messages on Guest triggered errors (Akihiko)
- Move the vfio dmabuf stubs file to hw/vfio directory (Akihiko)
- Make vfio_device_create_dmabuf() return an fd on success (Akihiko)
- Rename vfio_device_create_dmabuf to vfio_device_create_dmabuf_fd
since it now returns an fd on success
v6 -> v7:
- Introduce an enum to categorize Guest and Host errors (Akihiko)
- Drop the CONFIG_VIRTIO_GPU_VFIO_BLOB Kconfig option and add stubs
for VFIO dmabuf helpers when CONFIG_VFIO is not enabled (Akihiko)
- Check the correct return value of vfio_device_get_region_info()
in vfio_device_mmap_dmabuf()
v5 -> v6:
- Drop the additional error_setg() call in virtio_gpu_create_udmabuf()
and only have LOG_GUEST_ERROR for invalid ramblocks (Akihiko)
- Merge the patch that introduces vfio_device_lookup() helper with the
one that adds support for vfio_device_create_dmabuf() (Cedric)
- Use only one 'Error **' parameter instead of two while creating
and mmapping the dmabuf (Cedric)
- Collect R-b tags from Akihiko
v4 -> v5:
- Improve commit message for the patch that replaces dma_memory_map()
with virtio_gpu_dma_memory_map() (Akihiko)
- Create separate patches to remove rcu_read_lock/unlock and use
g_autofree for list pointer in virtio_gpu_create_udmabuf()
(Akihiko, Cedric)
- Create a separate patch to improve error handling (Cedric)
- Make vfio_device_lookup() a common helper local to vfio/device.c
(Cedric, Akihiko)
- Move the dmabuf mmap helper to vfio/device.c (Akihiko)
- Replace PROT_READ with PROT_NONE and vbasedev->fd with -1 while
creating the placeholder mapping in dmabuf mmap helper (Akihiko)
v3 -> v4:
- Drop the patch that introduces ram_block_is_memfd_backed()
- Drop the additional check in virtio_gpu_create_udmabuf() that
checks for memfd backed ram blocks (Akihiko)
- Remove rcu_read_lock/unlock and replace warn_report() with
qemu_log_mask() in virtio_gpu_create_udmabuf()
- Improve the commit message and logic in the patch that adds
support for vfio_device_create_dmabuf_fd()
- Rebase on top of vfio-next
v2 -> v3:
- Use memory_region_get_ram_ptr() to obtain hva for both memfd and
VFIO backed memory regions (Akihiko)
- Drop the patch that introduced qemu_iovec_same_memory_regions()
helper and move the "same memory region" check into
virtio_gpu_create_udmabuf(), vfio_device_create_dmabuf_fd() (Akihiko)
- Refactor virtio_gpu_init_dmabuf() to not rely on helpers such as
memory_region_is_ram_device() to identify memory regions and
instead call virtio_gpu_create_udmabuf() unconditionally (Akihiko)
- Add a patch to introduce ram_block_is_memfd_backed() helper
v1 -> v2:
- Drop the patch that uses res->blob_size instead of res->blob to
identify blob resources (Akihiko)
- Remove the res->dmabuf_fd < 0 check while attaching backing to a
resource (Akihiko)
- Remove cmd->cmd_hdr.type != VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB
check while attaching backing (Akihiko)
- Improve vfio_get_region_index_from_mr() and add documentation (Cedric)
- Remove rcu_read_lock/unlock around qemu_ram_block_from_host()
(Akihiko, Cedric)
- Improve, document and rename vfio_device_create_dmabuf() to
vfio_device_create_dmabuf_fd() (Cedric)
- Add a new helper to lookup VFIO device from memory region (Cedric)
- Document vfio_device_get_region_info() (Cedric)
- Ensure that info variable (in vfio_dmabuf_mmap()) is initialized
before use (Cedric)
- Rename udmabuf files and helpers to dmabuf (Akihiko)
- Remove the redundant check for virtio_gpu_have_udmabuf() in
virtio_gpu_init_dmabuf() (Akihiko)
- Add a helper to check whether all the entries of a dmabuf belong
to a single memory region or not (Akihiko)
RFC -> v1:
- Create the CPU mapping using vfio device fd if the dmabuf exporter
(vfio-pci) does not provide mmap() support (Akihiko)
- Log a warning with LOG_GUEST_ERROR instead of warn_report() when
dmabuf cannot be created using Guest provided addresses (Akihiko)
- Use address_space_translate() instead of gpa2hva() to obtain the
Host addresses (Akihiko)
- Rearrange the patches and improve the commit messages (Akihiko)
- Fix compilation error when VFIO is not enabled (Alex)
- Add a new helper to obtain VFIO region index from memory region
- Move vfio_device_create_dmabuf() to hw/vfio/device.c
Tested with an SRIOV enabled Intel dGPU (B60) by running Gnome Wayland
(in the VM) and Qemu with the following (relevant) parameters:
-device vfio-pci,host=0000:03:00.1
-device virtio-vga,max_outputs=1,xres=1920,yres=1080,blob=true
-display gtk,gl=on
Associated virtio-gpu kernel driver series (merged):
https://lore.kernel.org/dri-devel/20241126031643.3490496-1-vivek.kasireddy@intel.com/
---
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Cc: Dongwon Kim <dongwon.kim@intel.com>
Vivek Kasireddy (10):
virtio-gpu: Recreate the resource's dmabuf if new backing is attached
virtio-gpu: Find hva for Guest's DMA addr associated with a ram device
virtio-gpu: Rename udmabuf files and helpers to dmabuf
virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from
virtio_gpu_create_udmabuf()
virtio-gpu-dmabuf: Use g_autofree for the list pointer
vfio/region: Add a helper to get region index from memory region
vfio/device: Add support for creating dmabuf from multiple ranges
vfio/device: Add a helper to mmap a dmabuf
virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum
virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO
devices
hw/display/meson.build | 4 +-
...abuf-stubs.c => virtio-gpu-dmabuf-stubs.c} | 4 +-
...rtio-gpu-udmabuf.c => virtio-gpu-dmabuf.c} | 98 ++++++++----
hw/display/virtio-gpu.c | 31 +++-
hw/vfio/device.c | 145 ++++++++++++++++++
hw/vfio/dmabuf-stubs.c | 24 +++
hw/vfio/meson.build | 1 +
hw/vfio/region.c | 14 ++
include/hw/vfio/vfio-device.h | 48 ++++++
include/hw/virtio/virtio-gpu.h | 6 +-
10 files changed, 330 insertions(+), 45 deletions(-)
rename hw/display/{virtio-gpu-udmabuf-stubs.c => virtio-gpu-dmabuf-stubs.c} (79%)
rename hw/display/{virtio-gpu-udmabuf.c => virtio-gpu-dmabuf.c} (64%)
create mode 100644 hw/vfio/dmabuf-stubs.c
--
2.53.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v11 01/10] virtio-gpu: Recreate the resource's dmabuf if new backing is attached
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 02/10] virtio-gpu: Find hva for Guest's DMA addr associated with a ram device Vivek Kasireddy
` (8 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
There are cases when a blob resource's backing might get detached
and re-attached again such as when the underlying object is getting
migrated in the Guest. In these situations, we need to obtain a new
dmabuf fd, which can be done by calling virtio_gpu_init_udmabuf().
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/virtio-gpu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 643e91ca2a..f20111fa57 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -937,6 +937,10 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
+
+ if (res->blob_size) {
+ virtio_gpu_init_udmabuf(res);
+ }
}
static void
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 02/10] virtio-gpu: Find hva for Guest's DMA addr associated with a ram device
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 01/10] virtio-gpu: Recreate the resource's dmabuf if new backing is attached Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 03/10] virtio-gpu: Rename udmabuf files and helpers to dmabuf Vivek Kasireddy
` (7 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
If the Guest provides a DMA address that is associated with a ram
device (such as a VFIO PCI device region and not its system memory),
then we can obtain the hva (host virtual address) by invoking
address_space_translate() followed by memory_region_get_ram_ptr().
We cannot use dma_memory_map() because for memory regions that do
not support direct access, it would create bounce buffers instead
of returning the actual hva, which is not desirable here. And, since
VFIO device regions are not considered directly accessible (because
they are mostly MMIO based), virtio-gpu cannot invoke dma_memory_map()
to obtain the hva in this case.
Therefore, in order to handle addresses associated with VFIO devices,
we need to use the address_space_translate() API to first identify
the right memory region and the appropriate offset within that
region and then use memory_region_get_ram_ptr() to get the hva.
This approach also works for addresses associated with the system
memory region.
Note that, although we take an explicit reference on the memory
region, we would still rely on dma_memory_unmap() to drop that
reference when the dma mapping is eventually unmapped.
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/virtio-gpu.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f20111fa57..f5c6a7deb9 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -798,6 +798,23 @@ static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
&fb, res, &ss.r, &cmd->error);
}
+static void *virtio_gpu_dma_memory_map(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd,
+ uint64_t a, hwaddr *len)
+{
+ MemoryRegion *mr;
+ hwaddr xlat;
+
+ mr = address_space_translate(VIRTIO_DEVICE(g)->dma_as, a, &xlat, len,
+ DMA_DIRECTION_TO_DEVICE,
+ MEMTXATTRS_UNSPECIFIED);
+ if (memory_region_is_ram(mr)) {
+ memory_region_ref(mr);
+ return memory_region_get_ram_ptr(mr) + xlat;
+ }
+ return NULL;
+}
+
int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
uint32_t nr_entries, uint32_t offset,
struct virtio_gpu_ctrl_command *cmd,
@@ -839,9 +856,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
do {
len = l;
- map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len,
- DMA_DIRECTION_TO_DEVICE,
- MEMTXATTRS_UNSPECIFIED);
+ map = virtio_gpu_dma_memory_map(g, cmd, a, &len);
if (!map) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
" element %d\n", __func__, e);
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 03/10] virtio-gpu: Rename udmabuf files and helpers to dmabuf
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 01/10] virtio-gpu: Recreate the resource's dmabuf if new backing is attached Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 02/10] virtio-gpu: Find hva for Guest's DMA addr associated with a ram device Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 04/10] virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from virtio_gpu_create_udmabuf() Vivek Kasireddy
` (6 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
This is prep-work for adding the ability to create dmabuf fds from
VFIO devices in addition to udmabuf.
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/meson.build | 4 ++--
...gpu-udmabuf-stubs.c => virtio-gpu-dmabuf-stubs.c} | 4 ++--
.../{virtio-gpu-udmabuf.c => virtio-gpu-dmabuf.c} | 12 ++++++------
hw/display/virtio-gpu.c | 8 ++++----
include/hw/virtio/virtio-gpu.h | 6 +++---
5 files changed, 17 insertions(+), 17 deletions(-)
rename hw/display/{virtio-gpu-udmabuf-stubs.c => virtio-gpu-dmabuf-stubs.c} (79%)
rename hw/display/{virtio-gpu-udmabuf.c => virtio-gpu-dmabuf.c} (94%)
diff --git a/hw/display/meson.build b/hw/display/meson.build
index 90e6c041bd..f5f92b1068 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -69,9 +69,9 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU',
if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c'), pixman])
if host_os == 'linux'
- virtio_gpu_ss.add(files('virtio-gpu-udmabuf.c'))
+ virtio_gpu_ss.add(files('virtio-gpu-dmabuf.c'))
else
- virtio_gpu_ss.add(files('virtio-gpu-udmabuf-stubs.c'))
+ virtio_gpu_ss.add(files('virtio-gpu-dmabuf-stubs.c'))
endif
virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: files('vhost-user-gpu.c'))
hw_display_modules += {'virtio-gpu': virtio_gpu_ss}
diff --git a/hw/display/virtio-gpu-udmabuf-stubs.c b/hw/display/virtio-gpu-dmabuf-stubs.c
similarity index 79%
rename from hw/display/virtio-gpu-udmabuf-stubs.c
rename to hw/display/virtio-gpu-dmabuf-stubs.c
index f692e13510..01067e246d 100644
--- a/hw/display/virtio-gpu-udmabuf-stubs.c
+++ b/hw/display/virtio-gpu-dmabuf-stubs.c
@@ -7,12 +7,12 @@ bool virtio_gpu_have_udmabuf(void)
return false;
}
-void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res)
{
/* nothing (stub) */
}
-void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
+void virtio_gpu_fini_dmabuf(struct virtio_gpu_simple_resource *res)
{
/* nothing (stub) */
}
diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-dmabuf.c
similarity index 94%
rename from hw/display/virtio-gpu-udmabuf.c
rename to hw/display/virtio-gpu-dmabuf.c
index d804f321aa..c34d4c85bc 100644
--- a/hw/display/virtio-gpu-udmabuf.c
+++ b/hw/display/virtio-gpu-dmabuf.c
@@ -68,7 +68,7 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
g_free(list);
}
-static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *res)
+static void virtio_gpu_remap_dmabuf(struct virtio_gpu_simple_resource *res)
{
res->remapped = mmap(NULL, res->blob_size, PROT_READ,
MAP_SHARED, res->dmabuf_fd, 0);
@@ -79,7 +79,7 @@ static void virtio_gpu_remap_udmabuf(struct virtio_gpu_simple_resource *res)
}
}
-static void virtio_gpu_destroy_udmabuf(struct virtio_gpu_simple_resource *res)
+static void virtio_gpu_destroy_dmabuf(struct virtio_gpu_simple_resource *res)
{
if (res->remapped) {
munmap(res->remapped, res->blob_size);
@@ -128,7 +128,7 @@ bool virtio_gpu_have_udmabuf(void)
return memfd_backend;
}
-void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
+void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res)
{
void *pdata = NULL;
@@ -141,7 +141,7 @@ void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
if (res->dmabuf_fd < 0) {
return;
}
- virtio_gpu_remap_udmabuf(res);
+ virtio_gpu_remap_dmabuf(res);
if (!res->remapped) {
return;
}
@@ -151,10 +151,10 @@ void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
res->blob = pdata;
}
-void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res)
+void virtio_gpu_fini_dmabuf(struct virtio_gpu_simple_resource *res)
{
if (res->remapped) {
- virtio_gpu_destroy_udmabuf(res);
+ virtio_gpu_destroy_dmabuf(res);
}
}
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index f5c6a7deb9..72c7610664 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -360,7 +360,7 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
return;
}
- virtio_gpu_init_udmabuf(res);
+ virtio_gpu_init_dmabuf(res);
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
}
@@ -917,7 +917,7 @@ void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
res->addrs = NULL;
if (res->blob) {
- virtio_gpu_fini_udmabuf(res);
+ virtio_gpu_fini_dmabuf(res);
}
}
@@ -954,7 +954,7 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
}
if (res->blob_size) {
- virtio_gpu_init_udmabuf(res);
+ virtio_gpu_init_dmabuf(res);
}
}
@@ -1440,7 +1440,7 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
return -EINVAL;
}
- virtio_gpu_init_udmabuf(res);
+ virtio_gpu_init_dmabuf(res);
resource_id = qemu_get_be32(f);
}
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 58e0f91fda..e3d351a2d4 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -354,10 +354,10 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_set_scanout_blob *ss,
uint64_t blob_size);
-/* virtio-gpu-udmabuf.c */
+/* virtio-gpu-dmabuf.c */
bool virtio_gpu_have_udmabuf(void);
-void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
-void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res);
+void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res);
+void virtio_gpu_fini_dmabuf(struct virtio_gpu_simple_resource *res);
int virtio_gpu_update_dmabuf(VirtIOGPU *g,
uint32_t scanout_id,
struct virtio_gpu_simple_resource *res,
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 04/10] virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from virtio_gpu_create_udmabuf()
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (2 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 03/10] virtio-gpu: Rename udmabuf files and helpers to dmabuf Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 05/10] virtio-gpu-dmabuf: Use g_autofree for the list pointer Vivek Kasireddy
` (5 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
There is no need to wrap the call to qemu_ram_block_from_host() with
rcu_read_lock/unlock as we already hold a reference to the memory
region that owns the ram block. Note that, the reference was obtained
via dma_memory_map() while creating the mapping.
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/virtio-gpu-dmabuf.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/hw/display/virtio-gpu-dmabuf.c b/hw/display/virtio-gpu-dmabuf.c
index c34d4c85bc..0782bcf3a1 100644
--- a/hw/display/virtio-gpu-dmabuf.c
+++ b/hw/display/virtio-gpu-dmabuf.c
@@ -43,10 +43,7 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
sizeof(struct udmabuf_create_item) * res->iov_cnt);
for (i = 0; i < res->iov_cnt; i++) {
- rcu_read_lock();
rb = qemu_ram_block_from_host(res->iov[i].iov_base, false, &offset);
- rcu_read_unlock();
-
if (!rb || rb->fd < 0) {
g_free(list);
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 05/10] virtio-gpu-dmabuf: Use g_autofree for the list pointer
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (3 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 04/10] virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from virtio_gpu_create_udmabuf() Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region Vivek Kasireddy
` (4 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
Avoid the manual g_free() calls for the list pointer by using
g_autofree in virtio_gpu_create_udmabuf().
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/virtio-gpu-dmabuf.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/hw/display/virtio-gpu-dmabuf.c b/hw/display/virtio-gpu-dmabuf.c
index 0782bcf3a1..8d67ef7c2a 100644
--- a/hw/display/virtio-gpu-dmabuf.c
+++ b/hw/display/virtio-gpu-dmabuf.c
@@ -29,7 +29,7 @@
static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
{
- struct udmabuf_create_list *list;
+ g_autofree struct udmabuf_create_list *list = NULL;
RAMBlock *rb;
ram_addr_t offset;
int udmabuf, i;
@@ -45,7 +45,6 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
for (i = 0; i < res->iov_cnt; i++) {
rb = qemu_ram_block_from_host(res->iov[i].iov_base, false, &offset);
if (!rb || rb->fd < 0) {
- g_free(list);
return;
}
@@ -62,7 +61,6 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
warn_report("%s: UDMABUF_CREATE_LIST: %s", __func__,
strerror(errno));
}
- g_free(list);
}
static void virtio_gpu_remap_dmabuf(struct virtio_gpu_simple_resource *res)
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (4 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 05/10] virtio-gpu-dmabuf: Use g_autofree for the list pointer Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-17 14:41 ` Cédric Le Goater
2026-03-11 2:50 ` [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges Vivek Kasireddy
` (3 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Vivek Kasireddy, Alex Williamson, Cédric Le Goater
Having a way to figure out the region index (or bar) associated
with a memory region is helpful in various scenarios. For example,
this capability can be useful in retrieving the region info needed
for mapping a part of a VFIO region or creating a dmabuf.
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/vfio/region.c | 14 ++++++++++++++
include/hw/vfio/vfio-device.h | 10 ++++++++++
2 files changed, 24 insertions(+)
diff --git a/hw/vfio/region.c b/hw/vfio/region.c
index 47fdc2df34..4cb92216ef 100644
--- a/hw/vfio/region.c
+++ b/hw/vfio/region.c
@@ -539,3 +539,17 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled)
trace_vfio_region_mmaps_set_enabled(memory_region_name(region->mem),
enabled);
}
+
+int vfio_get_region_index_from_mr(MemoryRegion *mr)
+{
+ VFIORegion *region;
+
+ while (mr->container) {
+ if (mr->ops == &vfio_region_ops) {
+ region = mr->opaque;
+ return region->nr;
+ }
+ mr = mr->container;
+ }
+ return -1;
+}
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 828a31c006..596c7f5a10 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -308,6 +308,16 @@ bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_t
int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
struct vfio_irq_info *info);
+
+/**
+ * Return the region index associated with a given MemoryRegion. The index
+ * can be useful in retrieving region info.
+ *
+ * @mr: MemoryRegion to use
+ *
+ * Returns the region index or -1 on error.
+ */
+int vfio_get_region_index_from_mr(MemoryRegion *mr);
#endif
/* Returns 0 on success, or a negative errno. */
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (5 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-17 15:00 ` Cédric Le Goater
2026-03-11 2:50 ` [PATCH v11 08/10] vfio/device: Add a helper to mmap a dmabuf Vivek Kasireddy
` (2 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Vivek Kasireddy, Alex Williamson, Cédric Le Goater
In order to create a dmabuf associated with a buffer that spans
multiple ranges, we first need to identify the VFIO region and
index the buffer (represented by iovec) belongs to and then
translate its addresses to offsets within that region.
The qemu_ram_block_from_host() API gives us both the region and
the offset info we need to populate the dma ranges so that we can
invoke the VFIO_DEVICE_FEATURE_DMA_BUF feature to create the dmabuf.
Also, instead of iterating over all QOM devices to find the
VFIODevice associated with a memory region, introduce a helper to
just use the vfio_device_list to lookup the VFIODevice.
Lastly, introduce an enum to return the type of error encountered
while creating the dmabuf fd.
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/vfio/device.c | 81 +++++++++++++++++++++++++++++++++++
hw/vfio/dmabuf-stubs.c | 17 ++++++++
hw/vfio/meson.build | 1 +
include/hw/vfio/vfio-device.h | 22 ++++++++++
4 files changed, 121 insertions(+)
create mode 100644 hw/vfio/dmabuf-stubs.c
diff --git a/hw/vfio/device.c b/hw/vfio/device.c
index 973fc35b59..2d01059be0 100644
--- a/hw/vfio/device.c
+++ b/hw/vfio/device.c
@@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include <sys/ioctl.h>
+#include "system/ramblock.h"
#include "hw/vfio/vfio-device.h"
#include "hw/vfio/pci.h"
#include "hw/core/iommu.h"
@@ -644,3 +645,83 @@ static VFIODeviceIOOps vfio_device_io_ops_ioctl = {
.region_read = vfio_device_io_region_read,
.region_write = vfio_device_io_region_write,
};
+
+static bool vfio_device_lookup(struct iovec *iov, VFIODevice **vbasedevp,
+ Error **errp)
+{
+ VFIODevice *vbasedev;
+ RAMBlock *first_rb;
+ ram_addr_t offset;
+
+ first_rb = qemu_ram_block_from_host(iov[0].iov_base, false, &offset);
+ if (!first_rb) {
+ error_setg(errp, "Could not find first ramblock\n");
+ return false;
+ }
+
+ QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
+ if (vbasedev->dev == first_rb->mr->dev) {
+ *vbasedevp = vbasedev;
+ return true;
+ }
+ }
+ error_setg(errp, "No VFIO device found to create dmabuf from\n");
+ return false;
+}
+
+int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
+ Error **errp)
+{
+ g_autofree struct vfio_device_feature *feature = NULL;
+ struct vfio_device_feature_dma_buf *dma_buf;
+ RAMBlock *rb, *first_rb;
+ VFIODevice *vbasedev;
+ ram_addr_t offset;
+ int i, index, ret;
+ size_t argsz;
+
+ argsz = sizeof(*feature) + sizeof (*dma_buf) +
+ sizeof(struct vfio_region_dma_range) * iov_cnt;
+ feature = g_malloc0(argsz);
+ *feature = (struct vfio_device_feature) {
+ .argsz = argsz,
+ .flags = VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_DMA_BUF,
+ };
+ dma_buf = (struct vfio_device_feature_dma_buf *)feature->data;
+
+ if (!vfio_device_lookup(iov, &vbasedev, errp)) {
+ return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
+ }
+
+ for (i = 0; i < iov_cnt; i++) {
+ rb = qemu_ram_block_from_host(iov[i].iov_base, false, &offset);
+ if (i == 0) {
+ first_rb = rb;
+ }
+ if (!rb || rb != first_rb) {
+ error_setg(errp, "Cannot create dmabuf with different regions\n");
+ return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
+ }
+
+ index = vfio_get_region_index_from_mr(rb->mr);
+ if (index < 0) {
+ error_setg(errp, "Cannot find region index for dmabuf segment\n");
+ return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
+ }
+
+ dma_buf->region_index = index;
+ dma_buf->dma_ranges[i].offset = offset;
+ dma_buf->dma_ranges[i].length = iov[i].iov_len;
+ }
+
+ dma_buf->nr_ranges = iov_cnt;
+ dma_buf->open_flags = O_RDONLY | O_CLOEXEC;
+
+ ret = vfio_device_get_feature(vbasedev, feature);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret,
+ "Could not create dmabuf fd via VFIO device");
+ return VFIO_DMABUF_CREATE_ERR_UNSPEC;
+ }
+ return ret;
+}
diff --git a/hw/vfio/dmabuf-stubs.c b/hw/vfio/dmabuf-stubs.c
new file mode 100644
index 0000000000..e71e2b68dd
--- /dev/null
+++ b/hw/vfio/dmabuf-stubs.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2026 Intel and/or its affiliates.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qemu/iov.h"
+#include "hw/vfio/vfio-device.h"
+
+int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
+ Error **errp)
+{
+ error_setg(errp, "VFIO dmabuf support is not enabled");
+ return VFIO_DMABUF_CREATE_HOST_ERROR;
+}
diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
index 82f68698fb..ac899d30a8 100644
--- a/hw/vfio/meson.build
+++ b/hw/vfio/meson.build
@@ -34,3 +34,4 @@ system_ss.add(when: 'CONFIG_IOMMUFD', if_false: files('iommufd-stubs.c'))
system_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
'display.c',
))
+system_ss.add(when: 'CONFIG_VFIO', if_false: files('dmabuf-stubs.c'))
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 596c7f5a10..566e5d8bc0 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -41,6 +41,13 @@ enum {
VFIO_DEVICE_TYPE_AP = 3,
};
+enum {
+ /* The Guest passed addresses stored in IOV are invalid */
+ VFIO_DMABUF_CREATE_ERR_INVALID_IOV = -1,
+ /* Guest or Host may be at fault for this type of error */
+ VFIO_DMABUF_CREATE_ERR_UNSPEC = -2,
+};
+
typedef struct VFIODeviceOps VFIODeviceOps;
typedef struct VFIODeviceIOOps VFIODeviceIOOps;
typedef struct VFIOMigration VFIOMigration;
@@ -318,6 +325,21 @@ int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
* Returns the region index or -1 on error.
*/
int vfio_get_region_index_from_mr(MemoryRegion *mr);
+
+/**
+ * Create a dmabuf fd by first translating the addresses in the
+ * iovec array into VFIO region offsets and then invoking the
+ * VFIO_DEVICE_FEATURE_DMA_BUF feature.
+ *
+ * @iov: array of iovec entries associated with a buffer
+ * @iov_cnt: number of entries in the iovec array
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns the created dmabuf fd or either VFIO_DMABUF_CREATE_ERR_UNSPEC
+ * or VFIO_DMABUF_CREATE_ERR_INVALID_IOV on error.
+ */
+int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
+ Error **errp);
#endif
/* Returns 0 on success, or a negative errno. */
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 08/10] vfio/device: Add a helper to mmap a dmabuf
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (6 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 09/10] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Vivek Kasireddy
9 siblings, 0 replies; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel; +Cc: Vivek Kasireddy, Alex Williamson, Cédric Le Goater
In order to mmap a dmabuf, we first need to create a placeholder
mapping that would fit the entire size of the dmabuf. This mapping
would then be replaced with smaller mappings of individual dmabuf
segments.
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/vfio/device.c | 64 +++++++++++++++++++++++++++++++++++
hw/vfio/dmabuf-stubs.c | 7 ++++
include/hw/vfio/vfio-device.h | 16 +++++++++
3 files changed, 87 insertions(+)
diff --git a/hw/vfio/device.c b/hw/vfio/device.c
index 2d01059be0..fdb94f1457 100644
--- a/hw/vfio/device.c
+++ b/hw/vfio/device.c
@@ -725,3 +725,67 @@ int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
}
return ret;
}
+
+void *vfio_device_mmap_dmabuf(struct iovec *iov, unsigned int iov_cnt,
+ size_t total_size, Error **errp)
+{
+ struct vfio_region_info *info = NULL;
+ VFIODevice *vbasedev = NULL;
+ ram_addr_t offset, len = 0;
+ RAMBlock *first_rb, *rb;
+ void *map, *submap;
+ int i, index;
+
+ if (!vfio_device_lookup(iov, &vbasedev, errp)) {
+ return NULL;
+ }
+
+ /*
+ * We first reserve a contiguous chunk of address space for the entire
+ * dmabuf, then replace it with smaller mappings that correspond to the
+ * individual segments of the dmabuf.
+ */
+ map = mmap(NULL, total_size, PROT_NONE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+ if (map == MAP_FAILED) {
+ error_setg_errno(errp, errno, "Could not reserve placeholder mapping");
+ return NULL;
+ }
+
+ for (i = 0; i < iov_cnt; i++) {
+ rb = qemu_ram_block_from_host(iov[i].iov_base, false, &offset);
+ if (i == 0) {
+ first_rb = rb;
+ }
+ if (!rb || rb != first_rb) {
+ error_setg(errp, "Cannot mmap dmabuf with different regions\n");
+ goto err;
+ }
+
+ index = vfio_get_region_index_from_mr(rb->mr);
+ if (index < 0) {
+ error_setg(errp, "Cannot find region index for dmabuf segment\n");
+ goto err;
+ }
+
+ if (vfio_device_get_region_info(vbasedev, index, &info)) {
+ error_setg(errp, "Cannot find region info for dmabuf segment\n");
+ goto err;
+ }
+
+ submap = mmap(map + len, iov[i].iov_len, PROT_READ,
+ MAP_SHARED | MAP_FIXED, vbasedev->fd,
+ info->offset + offset);
+ if (submap == MAP_FAILED) {
+ error_setg_errno(errp, errno, "Could not mmap dmabuf segment\n");
+ goto err;
+ }
+
+ len += iov[i].iov_len;
+ }
+ return map;
+err:
+ munmap(map, total_size);
+ error_prepend(errp, "VFIO dmabuf mmap failed: ");
+ return NULL;
+}
+
diff --git a/hw/vfio/dmabuf-stubs.c b/hw/vfio/dmabuf-stubs.c
index e71e2b68dd..92b52bc60d 100644
--- a/hw/vfio/dmabuf-stubs.c
+++ b/hw/vfio/dmabuf-stubs.c
@@ -15,3 +15,10 @@ int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
error_setg(errp, "VFIO dmabuf support is not enabled");
return VFIO_DMABUF_CREATE_HOST_ERROR;
}
+
+void *vfio_device_mmap_dmabuf(struct iovec *iov, unsigned int iov_cnt,
+ size_t total_size, Error **errp)
+{
+ error_setg(errp, "VFIO mmap dmabuf support is not enabled");
+ return NULL;
+}
diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
index 566e5d8bc0..60783d6fd5 100644
--- a/include/hw/vfio/vfio-device.h
+++ b/include/hw/vfio/vfio-device.h
@@ -340,6 +340,22 @@ int vfio_get_region_index_from_mr(MemoryRegion *mr);
*/
int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
Error **errp);
+
+/**
+ * Mmap a dmabuf by first translating the addresses in the iovec
+ * array into VFIO region offsets and then creating a placeholder
+ * mapping that would be replaced later with mappings that
+ * correspond to the dmabuf segments.
+ *
+ * @iov: array of iovec entries associated with the dmabuf
+ * @iov_cnt: number of entries in the iovec array
+ * @total_size: total size of the dmabuf
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns the mapped pointer on success and NULL on error.
+ */
+void *vfio_device_mmap_dmabuf(struct iovec *iov, unsigned int iov_cnt,
+ size_t total_size, Error **errp);
#endif
/* Returns 0 on success, or a negative errno. */
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 09/10] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (7 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 08/10] vfio/device: Add a helper to mmap a dmabuf Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 5:16 ` Akihiko Odaki
2026-03-11 2:50 ` [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Vivek Kasireddy
9 siblings, 1 reply; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
Make the error handling more robust in virtio_gpu_init_udmabuf()
by introducing 'Error **' parameter to capture errors and using
an enum from VFIO to categorize different errors. This allows for
better error reporting and handling of errors from
virtio_gpu_create_udmabuf() and virtio_gpu_remap_dmabuf().
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/virtio-gpu-dmabuf.c | 67 +++++++++++++++++++++++-----------
1 file changed, 45 insertions(+), 22 deletions(-)
diff --git a/hw/display/virtio-gpu-dmabuf.c b/hw/display/virtio-gpu-dmabuf.c
index 8d67ef7c2a..eddf398a43 100644
--- a/hw/display/virtio-gpu-dmabuf.c
+++ b/hw/display/virtio-gpu-dmabuf.c
@@ -18,6 +18,7 @@
#include "ui/console.h"
#include "hw/virtio/virtio-gpu.h"
#include "hw/virtio/virtio-gpu-pixman.h"
+#include "hw/vfio/vfio-device.h"
#include "trace.h"
#include "system/ramblock.h"
#include "system/hostmem.h"
@@ -27,16 +28,18 @@
#include "standard-headers/linux/udmabuf.h"
#include "standard-headers/drm/drm_fourcc.h"
-static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
+static int virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res,
+ Error **errp)
{
g_autofree struct udmabuf_create_list *list = NULL;
RAMBlock *rb;
ram_addr_t offset;
- int udmabuf, i;
+ int udmabuf, i, fd;
udmabuf = udmabuf_fd();
if (udmabuf < 0) {
- return;
+ error_setg(errp, "udmabuf device not available or enabled");
+ return VFIO_DMABUF_CREATE_ERR_UNSPEC;
}
list = g_malloc0(sizeof(struct udmabuf_create_list) +
@@ -45,7 +48,8 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
for (i = 0; i < res->iov_cnt; i++) {
rb = qemu_ram_block_from_host(res->iov[i].iov_base, false, &offset);
if (!rb || rb->fd < 0) {
- return;
+ error_setg(errp, "IOV memory address incompatible with udmabuf ");
+ return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
}
list->list[i].memfd = rb->fd;
@@ -56,22 +60,28 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
list->count = res->iov_cnt;
list->flags = UDMABUF_FLAGS_CLOEXEC;
- res->dmabuf_fd = ioctl(udmabuf, UDMABUF_CREATE_LIST, list);
- if (res->dmabuf_fd < 0) {
- warn_report("%s: UDMABUF_CREATE_LIST: %s", __func__,
- strerror(errno));
+ fd = ioctl(udmabuf, UDMABUF_CREATE_LIST, list);
+ if (fd < 0) {
+ error_setg_errno(errp, errno, "UDMABUF_CREATE_LIST: ioctl failed");
+ if (errno == EINVAL || errno == EBADFD) {
+ return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
+ }
+ return VFIO_DMABUF_CREATE_ERR_UNSPEC;
}
+ return fd;
}
-static void virtio_gpu_remap_dmabuf(struct virtio_gpu_simple_resource *res)
+static void *virtio_gpu_remap_dmabuf(struct virtio_gpu_simple_resource *res,
+ Error **errp)
{
- res->remapped = mmap(NULL, res->blob_size, PROT_READ,
- MAP_SHARED, res->dmabuf_fd, 0);
- if (res->remapped == MAP_FAILED) {
- warn_report("%s: dmabuf mmap failed: %s", __func__,
- strerror(errno));
- res->remapped = NULL;
+ void *map;
+
+ map = mmap(NULL, res->blob_size, PROT_READ, MAP_SHARED, res->dmabuf_fd, 0);
+ if (map == MAP_FAILED) {
+ error_setg_errno(errp, errno, "dmabuf mmap failed");
+ return NULL;
}
+ return map;
}
static void virtio_gpu_destroy_dmabuf(struct virtio_gpu_simple_resource *res)
@@ -125,22 +135,35 @@ bool virtio_gpu_have_udmabuf(void)
void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res)
{
+ Error *local_err = NULL;
void *pdata = NULL;
- res->dmabuf_fd = -1;
if (res->iov_cnt == 1 &&
res->iov[0].iov_len < 4096) {
+ res->dmabuf_fd = -1;
pdata = res->iov[0].iov_base;
} else {
- virtio_gpu_create_udmabuf(res);
+ res->dmabuf_fd = virtio_gpu_create_udmabuf(res, &local_err);
+ if (res->dmabuf_fd == VFIO_DMABUF_CREATE_ERR_INVALID_IOV) {
+ error_free_or_abort(&local_err);
+
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Cannot create dmabuf: incompatible memory\n");
+ return;
+ } else if (res->dmabuf_fd >= 0) {
+ pdata = virtio_gpu_remap_dmabuf(res, &local_err);
+ if (!pdata) {
+ virtio_gpu_destroy_dmabuf(res);
+ }
+ } else {
+ res->dmabuf_fd = -1;
+ }
+
if (res->dmabuf_fd < 0) {
+ error_report_err(local_err);
return;
}
- virtio_gpu_remap_dmabuf(res);
- if (!res->remapped) {
- return;
- }
- pdata = res->remapped;
+ res->remapped = pdata;
}
res->blob = pdata;
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
` (8 preceding siblings ...)
2026-03-11 2:50 ` [PATCH v11 09/10] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum Vivek Kasireddy
@ 2026-03-11 2:50 ` Vivek Kasireddy
2026-03-11 5:21 ` Akihiko Odaki
9 siblings, 1 reply; 22+ messages in thread
From: Vivek Kasireddy @ 2026-03-11 2:50 UTC (permalink / raw)
To: qemu-devel
Cc: Vivek Kasireddy, Marc-André Lureau, Alex Bennée,
Akihiko Odaki, Dmitry Osipenko, Alex Williamson,
Cédric Le Goater
In addition to memfd, a blob resource can also have its backing
storage in a VFIO device region. Since, there is no effective way
to determine where the backing storage is located, we first try to
create a dmabuf assuming it is in memfd. If that fails, we try to
create a dmabuf assuming it is in VFIO device region.
So, we first call virtio_gpu_create_udmabuf() to check if the blob's
backing storage is located in a memfd or not. If it is not, we invoke
the vfio_device_create_dmabuf_fd() API which identifies the right
VFIO device and eventually creates a dmabuf fd.
Note that, for mmapping the dmabuf, we directly call mmap() if the
dmabuf fd was created via virtio_gpu_create_udmabuf() since we know
that the udmabuf driver supports mmap(). However, if the dmabuf was
created via vfio_device_create_dmabuf_fd(), we use the
vfio_device_mmap_dmabuf() API to get a mapping for the dmabuf.
Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
Cc: Alex Bennée <alex.bennee@linaro.org>
Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Cc: Alex Williamson <alex@shazbot.org>
Cc: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
---
hw/display/virtio-gpu-dmabuf.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/hw/display/virtio-gpu-dmabuf.c b/hw/display/virtio-gpu-dmabuf.c
index eddf398a43..ccb9c82a6f 100644
--- a/hw/display/virtio-gpu-dmabuf.c
+++ b/hw/display/virtio-gpu-dmabuf.c
@@ -147,9 +147,25 @@ void virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res)
if (res->dmabuf_fd == VFIO_DMABUF_CREATE_ERR_INVALID_IOV) {
error_free_or_abort(&local_err);
- qemu_log_mask(LOG_GUEST_ERROR,
- "Cannot create dmabuf: incompatible memory\n");
- return;
+ res->dmabuf_fd = vfio_device_create_dmabuf_fd(res->iov,
+ res->iov_cnt,
+ &local_err);
+ if (res->dmabuf_fd == VFIO_DMABUF_CREATE_ERR_INVALID_IOV) {
+ error_free_or_abort(&local_err);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Cannot create dmabuf: incompatible memory\n");
+ return;
+ }
+
+ if (res->dmabuf_fd >= 0) {
+ pdata = vfio_device_mmap_dmabuf(res->iov, res->iov_cnt,
+ res->blob_size, &local_err);
+ if (!pdata) {
+ virtio_gpu_destroy_dmabuf(res);
+ }
+ } else {
+ res->dmabuf_fd = -1;
+ }
} else if (res->dmabuf_fd >= 0) {
pdata = virtio_gpu_remap_dmabuf(res, &local_err);
if (!pdata) {
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v11 09/10] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum
2026-03-11 2:50 ` [PATCH v11 09/10] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum Vivek Kasireddy
@ 2026-03-11 5:16 ` Akihiko Odaki
0 siblings, 0 replies; 22+ messages in thread
From: Akihiko Odaki @ 2026-03-11 5:16 UTC (permalink / raw)
To: Vivek Kasireddy, qemu-devel
Cc: Marc-André Lureau, Alex Bennée, Dmitry Osipenko,
Alex Williamson, Cédric Le Goater
On 2026/03/11 11:50, Vivek Kasireddy wrote:
> Make the error handling more robust in virtio_gpu_init_udmabuf()
> by introducing 'Error **' parameter to capture errors and using
> an enum from VFIO to categorize different errors. This allows for
> better error reporting and handling of errors from
> virtio_gpu_create_udmabuf() and virtio_gpu_remap_dmabuf().
>
> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> Cc: Alex Bennée <alex.bennee@linaro.org>
> Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices
2026-03-11 2:50 ` [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Vivek Kasireddy
@ 2026-03-11 5:21 ` Akihiko Odaki
2026-03-12 5:41 ` Kasireddy, Vivek
0 siblings, 1 reply; 22+ messages in thread
From: Akihiko Odaki @ 2026-03-11 5:21 UTC (permalink / raw)
To: Vivek Kasireddy, qemu-devel
Cc: Marc-André Lureau, Alex Bennée, Dmitry Osipenko,
Alex Williamson, Cédric Le Goater
On 2026/03/11 11:50, Vivek Kasireddy wrote:
> In addition to memfd, a blob resource can also have its backing
> storage in a VFIO device region. Since, there is no effective way
> to determine where the backing storage is located, we first try to
> create a dmabuf assuming it is in memfd. If that fails, we try to
> create a dmabuf assuming it is in VFIO device region.
>
> So, we first call virtio_gpu_create_udmabuf() to check if the blob's
> backing storage is located in a memfd or not. If it is not, we invoke
> the vfio_device_create_dmabuf_fd() API which identifies the right
> VFIO device and eventually creates a dmabuf fd.
>
> Note that, for mmapping the dmabuf, we directly call mmap() if the
> dmabuf fd was created via virtio_gpu_create_udmabuf() since we know
> that the udmabuf driver supports mmap(). However, if the dmabuf was
> created via vfio_device_create_dmabuf_fd(), we use the
> vfio_device_mmap_dmabuf() API to get a mapping for the dmabuf.
>
> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> Cc: Alex Bennée <alex.bennee@linaro.org>
> Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Now I think this patch implements proper handling of all error
conditions and conforms the convention.
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices
2026-03-11 5:21 ` Akihiko Odaki
@ 2026-03-12 5:41 ` Kasireddy, Vivek
2026-03-17 5:42 ` Kasireddy, Vivek
0 siblings, 1 reply; 22+ messages in thread
From: Kasireddy, Vivek @ 2026-03-12 5:41 UTC (permalink / raw)
To: Akihiko Odaki, qemu-devel@nongnu.org
Cc: Marc-André Lureau, Alex Bennée, Dmitry Osipenko,
Alex Williamson, Cédric Le Goater
Hi Akihiko,
> Subject: Re: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for
> blobs associated with VFIO devices
>
> On 2026/03/11 11:50, Vivek Kasireddy wrote:
> > In addition to memfd, a blob resource can also have its backing
> > storage in a VFIO device region. Since, there is no effective way
> > to determine where the backing storage is located, we first try to
> > create a dmabuf assuming it is in memfd. If that fails, we try to
> > create a dmabuf assuming it is in VFIO device region.
> >
> > So, we first call virtio_gpu_create_udmabuf() to check if the blob's
> > backing storage is located in a memfd or not. If it is not, we invoke
> > the vfio_device_create_dmabuf_fd() API which identifies the right
> > VFIO device and eventually creates a dmabuf fd.
> >
> > Note that, for mmapping the dmabuf, we directly call mmap() if the
> > dmabuf fd was created via virtio_gpu_create_udmabuf() since we know
> > that the udmabuf driver supports mmap(). However, if the dmabuf was
> > created via vfio_device_create_dmabuf_fd(), we use the
> > vfio_device_mmap_dmabuf() API to get a mapping for the dmabuf.
> >
> > Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> > Cc: Alex Bennée <alex.bennee@linaro.org>
> > Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> > Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> > Cc: Alex Williamson <alex@shazbot.org>
> > Cc: Cédric Le Goater <clg@redhat.com>
> > Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
>
> Now I think this patch implements proper handling of all error
> conditions and conforms the convention.
>
> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Thank you for taking the time to review these patches!
Thanks,
Vivek
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices
2026-03-12 5:41 ` Kasireddy, Vivek
@ 2026-03-17 5:42 ` Kasireddy, Vivek
2026-03-17 10:18 ` Cédric Le Goater
0 siblings, 1 reply; 22+ messages in thread
From: Kasireddy, Vivek @ 2026-03-17 5:42 UTC (permalink / raw)
To: Cédric Le Goater, qemu-devel@nongnu.org
Cc: Akihiko Odaki, Marc-André Lureau, Alex Bennée,
Dmitry Osipenko, Alex Williamson
Hi Cedric,
> Subject: RE: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for
> blobs associated with VFIO devices
> >
> > On 2026/03/11 11:50, Vivek Kasireddy wrote:
> > > In addition to memfd, a blob resource can also have its backing
> > > storage in a VFIO device region. Since, there is no effective way to
> > > determine where the backing storage is located, we first try to
> > > create a dmabuf assuming it is in memfd. If that fails, we try to
> > > create a dmabuf assuming it is in VFIO device region.
> > >
> > > So, we first call virtio_gpu_create_udmabuf() to check if the blob's
> > > backing storage is located in a memfd or not. If it is not, we
> > > invoke the vfio_device_create_dmabuf_fd() API which identifies the
> > > right VFIO device and eventually creates a dmabuf fd.
> > >
> > > Note that, for mmapping the dmabuf, we directly call mmap() if the
> > > dmabuf fd was created via virtio_gpu_create_udmabuf() since we
> know
> > > that the udmabuf driver supports mmap(). However, if the dmabuf
> was
> > > created via vfio_device_create_dmabuf_fd(), we use the
> > > vfio_device_mmap_dmabuf() API to get a mapping for the dmabuf.
> > >
> > > Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> > > Cc: Alex Bennée <alex.bennee@linaro.org>
> > > Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> > > Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> > > Cc: Alex Williamson <alex@shazbot.org>
> > > Cc: Cédric Le Goater <clg@redhat.com>
> > > Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> >
> > Now I think this patch implements proper handling of all error
> > conditions and conforms the convention.
> >
> > Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> Thank you for taking the time to review these patches!
Can this series be merged to vfio-next given the dependencies on
the newly added VFIO APIs?
Thanks,
Vivek
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices
2026-03-17 5:42 ` Kasireddy, Vivek
@ 2026-03-17 10:18 ` Cédric Le Goater
2026-03-18 5:42 ` Kasireddy, Vivek
0 siblings, 1 reply; 22+ messages in thread
From: Cédric Le Goater @ 2026-03-17 10:18 UTC (permalink / raw)
To: Kasireddy, Vivek, qemu-devel@nongnu.org
Cc: Akihiko Odaki, Marc-André Lureau, Alex Bennée,
Dmitry Osipenko, Alex Williamson
Hello Vivek,
On 3/17/26 06:42, Kasireddy, Vivek wrote:
> Hi Cedric,
>
>> Subject: RE: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for
>> blobs associated with VFIO devices
>>>
>>> On 2026/03/11 11:50, Vivek Kasireddy wrote:
>>>> In addition to memfd, a blob resource can also have its backing
>>>> storage in a VFIO device region. Since, there is no effective way to
>>>> determine where the backing storage is located, we first try to
>>>> create a dmabuf assuming it is in memfd. If that fails, we try to
>>>> create a dmabuf assuming it is in VFIO device region.
>>>>
>>>> So, we first call virtio_gpu_create_udmabuf() to check if the blob's
>>>> backing storage is located in a memfd or not. If it is not, we
>>>> invoke the vfio_device_create_dmabuf_fd() API which identifies the
>>>> right VFIO device and eventually creates a dmabuf fd.
>>>>
>>>> Note that, for mmapping the dmabuf, we directly call mmap() if the
>>>> dmabuf fd was created via virtio_gpu_create_udmabuf() since we
>> know
>>>> that the udmabuf driver supports mmap(). However, if the dmabuf
>> was
>>>> created via vfio_device_create_dmabuf_fd(), we use the
>>>> vfio_device_mmap_dmabuf() API to get a mapping for the dmabuf.
>>>>
>>>> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>> Cc: Alex Bennée <alex.bennee@linaro.org>
>>>> Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>>>> Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
>>>> Cc: Alex Williamson <alex@shazbot.org>
>>>> Cc: Cédric Le Goater <clg@redhat.com>
>>>> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
>>>
>>> Now I think this patch implements proper handling of all error
>>> conditions and conforms the convention.
>>>
>>> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
>> Thank you for taking the time to review these patches!
> Can this series be merged to vfio-next given the dependencies on
> the newly added VFIO APIs?
I could merge in advance the VFIO changes but the series does not
apply nor compiles. We need feedback from the virtio-gpu maintainers
that this proposal is a useful feature too.
Since this is QEMU 11.1 material, we have some time. Let me review
it first.
Thanks,
C.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region
2026-03-11 2:50 ` [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region Vivek Kasireddy
@ 2026-03-17 14:41 ` Cédric Le Goater
2026-03-17 15:01 ` Cédric Le Goater
0 siblings, 1 reply; 22+ messages in thread
From: Cédric Le Goater @ 2026-03-17 14:41 UTC (permalink / raw)
To: Vivek Kasireddy, qemu-devel; +Cc: Alex Williamson
On 3/11/26 03:50, Vivek Kasireddy wrote:
> Having a way to figure out the region index (or bar) associated
> with a memory region is helpful in various scenarios. For example,
> this capability can be useful in retrieving the region info needed
> for mapping a part of a VFIO region or creating a dmabuf.
>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> ---
> hw/vfio/region.c | 14 ++++++++++++++
> include/hw/vfio/vfio-device.h | 10 ++++++++++
> 2 files changed, 24 insertions(+)
>
> diff --git a/hw/vfio/region.c b/hw/vfio/region.c
> index 47fdc2df34..4cb92216ef 100644
> --- a/hw/vfio/region.c
> +++ b/hw/vfio/region.c
> @@ -539,3 +539,17 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled)
> trace_vfio_region_mmaps_set_enabled(memory_region_name(region->mem),
> enabled);
> }
> +
> +int vfio_get_region_index_from_mr(MemoryRegion *mr)
I think you can move this routine as a static in device.c now. No need
to export a service.
Thanks,
C.
> +{
> + VFIORegion *region;
> +
> + while (mr->container) {
> + if (mr->ops == &vfio_region_ops) {
> + region = mr->opaque;
> + return region->nr;
> + }
> + mr = mr->container;
> + }
> + return -1;
> +}
> diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
> index 828a31c006..596c7f5a10 100644
> --- a/include/hw/vfio/vfio-device.h
> +++ b/include/hw/vfio/vfio-device.h
> @@ -308,6 +308,16 @@ bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_t
>
> int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
> struct vfio_irq_info *info);
> +
> +/**
> + * Return the region index associated with a given MemoryRegion. The index
> + * can be useful in retrieving region info.
> + *
> + * @mr: MemoryRegion to use
> + *
> + * Returns the region index or -1 on error.
> + */
> +int vfio_get_region_index_from_mr(MemoryRegion *mr);
> #endif
>
> /* Returns 0 on success, or a negative errno. */
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges
2026-03-11 2:50 ` [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges Vivek Kasireddy
@ 2026-03-17 15:00 ` Cédric Le Goater
2026-03-18 5:49 ` Kasireddy, Vivek
0 siblings, 1 reply; 22+ messages in thread
From: Cédric Le Goater @ 2026-03-17 15:00 UTC (permalink / raw)
To: Vivek Kasireddy, qemu-devel; +Cc: Alex Williamson
HEllo,
On 3/11/26 03:50, Vivek Kasireddy wrote:
> In order to create a dmabuf associated with a buffer that spans
> multiple ranges, we first need to identify the VFIO region and
> index the buffer (represented by iovec) belongs to and then
> translate its addresses to offsets within that region.
>
> The qemu_ram_block_from_host() API gives us both the region and
> the offset info we need to populate the dma ranges so that we can
> invoke the VFIO_DEVICE_FEATURE_DMA_BUF feature to create the dmabuf.
>
> Also, instead of iterating over all QOM devices to find the
> VFIODevice associated with a memory region, introduce a helper to
> just use the vfio_device_list to lookup the VFIODevice.
>
> Lastly, introduce an enum to return the type of error encountered
> while creating the dmabuf fd.
>
> Cc: Alex Williamson <alex@shazbot.org>
> Cc: Cédric Le Goater <clg@redhat.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> ---
> hw/vfio/device.c | 81 +++++++++++++++++++++++++++++++++++
> hw/vfio/dmabuf-stubs.c | 17 ++++++++
> hw/vfio/meson.build | 1 +
> include/hw/vfio/vfio-device.h | 22 ++++++++++
Please add to your .git/config
[diff]
orderFile = /path/to/qemu/scripts/git.orderfile
> 4 files changed, 121 insertions(+)
> create mode 100644 hw/vfio/dmabuf-stubs.c
>
> diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> index 973fc35b59..2d01059be0 100644
> --- a/hw/vfio/device.c
> +++ b/hw/vfio/device.c
> @@ -21,6 +21,7 @@
> #include "qemu/osdep.h"
> #include <sys/ioctl.h>
>
> +#include "system/ramblock.h"
> #include "hw/vfio/vfio-device.h"
> #include "hw/vfio/pci.h"
> #include "hw/core/iommu.h"
> @@ -644,3 +645,83 @@ static VFIODeviceIOOps vfio_device_io_ops_ioctl = {
> .region_read = vfio_device_io_region_read,
> .region_write = vfio_device_io_region_write,
> };
> +
Please add a comment
/*
* For virtio-gpu, < explain the context >
*/
> +static bool vfio_device_lookup(struct iovec *iov, VFIODevice **vbasedevp,
> + Error **errp)
> +{
> + VFIODevice *vbasedev;
> + RAMBlock *first_rb;
> + ram_addr_t offset;
> +
> + first_rb = qemu_ram_block_from_host(iov[0].iov_base, false, &offset);
> + if (!first_rb) {
> + error_setg(errp, "Could not find first ramblock\n");
> + return false;
> + }
> +
> + QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
> + if (vbasedev->dev == first_rb->mr->dev) {
> + *vbasedevp = vbasedev;
> + return true;
> + }
> + }
> + error_setg(errp, "No VFIO device found to create dmabuf from\n");
> + return false;
> +}
> +
> +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
> + Error **errp)
> +{
> + g_autofree struct vfio_device_feature *feature = NULL;
> + struct vfio_device_feature_dma_buf *dma_buf;
> + RAMBlock *rb, *first_rb;
> + VFIODevice *vbasedev;
> + ram_addr_t offset;
> + int i, index, ret;
> + size_t argsz;
Shouldn't we check iov and iov_cnt values ?
> + argsz = sizeof(*feature) + sizeof (*dma_buf) +
> + sizeof(struct vfio_region_dma_range) * iov_cnt;
> + feature = g_malloc0(argsz);
> + *feature = (struct vfio_device_feature) {
> + .argsz = argsz,
> + .flags = VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_DMA_BUF,
> + };
> + dma_buf = (struct vfio_device_feature_dma_buf *)feature->data;
> +
> + if (!vfio_device_lookup(iov, &vbasedev, errp)) {
> + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> + }
> +
> + for (i = 0; i < iov_cnt; i++) {
> + rb = qemu_ram_block_from_host(iov[i].iov_base, false, &offset);
> + if (i == 0) {
> + first_rb = rb;
> + }
> + if (!rb || rb != first_rb) {
> + error_setg(errp, "Cannot create dmabuf with different regions\n");
> + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> + }
> +
> + index = vfio_get_region_index_from_mr(rb->mr);
returning a VFIORegion seems cleaner.
> + if (index < 0) {
> + error_setg(errp, "Cannot find region index for dmabuf segment\n");
> + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> + }
Could you please introduce a common helper for the code above that
could be shared with vfio_device_mmap_dmabuf() ? The same sequence
is duplicated.
> + dma_buf->region_index = index;
> + dma_buf->dma_ranges[i].offset = offset;
> + dma_buf->dma_ranges[i].length = iov[i].iov_len;
> + }
> +
> + dma_buf->nr_ranges = iov_cnt;
> + dma_buf->open_flags = O_RDONLY | O_CLOEXEC;
> +
> + ret = vfio_device_get_feature(vbasedev, feature);
> + if (ret < 0) {
> + error_setg_errno(errp, -ret,
> + "Could not create dmabuf fd via VFIO device");
> + return VFIO_DMABUF_CREATE_ERR_UNSPEC;
See vfio_region_create_dma_buf() for possible errors. You might want
to introduce a helper.
> + }
> + return ret;
> +}
> diff --git a/hw/vfio/dmabuf-stubs.c b/hw/vfio/dmabuf-stubs.c
> new file mode 100644
> index 0000000000..e71e2b68dd
> --- /dev/null
> +++ b/hw/vfio/dmabuf-stubs.c
> @@ -0,0 +1,17 @@
> +/*
> + * Copyright (c) 2026 Intel and/or its affiliates.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/error-report.h"
> +#include "qemu/iov.h"
> +#include "hw/vfio/vfio-device.h"
> +
> +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
> + Error **errp)
> +{
> + error_setg(errp, "VFIO dmabuf support is not enabled");
> + return VFIO_DMABUF_CREATE_HOST_ERROR;
> +}
> diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
> index 82f68698fb..ac899d30a8 100644
> --- a/hw/vfio/meson.build
> +++ b/hw/vfio/meson.build
> @@ -34,3 +34,4 @@ system_ss.add(when: 'CONFIG_IOMMUFD', if_false: files('iommufd-stubs.c'))
> system_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
> 'display.c',
> ))
> +system_ss.add(when: 'CONFIG_VFIO', if_false: files('dmabuf-stubs.c'))
> diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
> index 596c7f5a10..566e5d8bc0 100644
> --- a/include/hw/vfio/vfio-device.h
> +++ b/include/hw/vfio/vfio-device.h
> @@ -41,6 +41,13 @@ enum {
> VFIO_DEVICE_TYPE_AP = 3,
> };
>
> +enum {
> + /* The Guest passed addresses stored in IOV are invalid */
> + VFIO_DMABUF_CREATE_ERR_INVALID_IOV = -1,
> + /* Guest or Host may be at fault for this type of error */
> + VFIO_DMABUF_CREATE_ERR_UNSPEC = -2,
> +};
This is overkill. Please return a bool value and ensure the errp
argument is correctly filled.
> +
> typedef struct VFIODeviceOps VFIODeviceOps;
> typedef struct VFIODeviceIOOps VFIODeviceIOOps;
> typedef struct VFIOMigration VFIOMigration;
> @@ -318,6 +325,21 @@ int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
> * Returns the region index or -1 on error.
> */
> int vfio_get_region_index_from_mr(MemoryRegion *mr);
> +
> +/**
> + * Create a dmabuf fd by first translating the addresses in the
> + * iovec array into VFIO region offsets and then invoking the
> + * VFIO_DEVICE_FEATURE_DMA_BUF feature.
> + *
> + * @iov: array of iovec entries associated with a buffer
> + * @iov_cnt: number of entries in the iovec array
> + * @errp: pointer to Error*, to store an error if it happens.
> + *
> + * Returns the created dmabuf fd or either VFIO_DMABUF_CREATE_ERR_UNSPEC
> + * or VFIO_DMABUF_CREATE_ERR_INVALID_IOV on error.
> + */
> +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int iov_cnt,
> + Error **errp);
> #endif
>
> /* Returns 0 on success, or a negative errno. */
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region
2026-03-17 14:41 ` Cédric Le Goater
@ 2026-03-17 15:01 ` Cédric Le Goater
2026-03-18 5:43 ` Kasireddy, Vivek
0 siblings, 1 reply; 22+ messages in thread
From: Cédric Le Goater @ 2026-03-17 15:01 UTC (permalink / raw)
To: Vivek Kasireddy, qemu-devel; +Cc: Alex Williamson
On 3/17/26 15:41, Cédric Le Goater wrote:
> On 3/11/26 03:50, Vivek Kasireddy wrote:
>> Having a way to figure out the region index (or bar) associated
>> with a memory region is helpful in various scenarios. For example,
>> this capability can be useful in retrieving the region info needed
>> for mapping a part of a VFIO region or creating a dmabuf.
>>
>> Cc: Alex Williamson <alex@shazbot.org>
>> Cc: Cédric Le Goater <clg@redhat.com>
>> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
>> ---
>> hw/vfio/region.c | 14 ++++++++++++++
>> include/hw/vfio/vfio-device.h | 10 ++++++++++
>> 2 files changed, 24 insertions(+)
>>
>> diff --git a/hw/vfio/region.c b/hw/vfio/region.c
>> index 47fdc2df34..4cb92216ef 100644
>> --- a/hw/vfio/region.c
>> +++ b/hw/vfio/region.c
>> @@ -539,3 +539,17 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled)
>> trace_vfio_region_mmaps_set_enabled(memory_region_name(region->mem),
>> enabled);
>> }
>> +
>> +int vfio_get_region_index_from_mr(MemoryRegion *mr)
>
>
> I think you can move this routine as a static in device.c now. No need
> to export a service.
you can't because of vfio_region_ops.
Returning a VFIORegion seems cleaner though.
Thanks,
C.
>
> Thanks,
>
> C.
>
>> +{
>> + VFIORegion *region;
>> +
>> + while (mr->container) {
>> + if (mr->ops == &vfio_region_ops) {
>> + region = mr->opaque;
>> + return region->nr;
>> + }
>> + mr = mr->container;
>> + }
>> + return -1;
>> +}
>> diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h
>> index 828a31c006..596c7f5a10 100644
>> --- a/include/hw/vfio/vfio-device.h
>> +++ b/include/hw/vfio/vfio-device.h
>> @@ -308,6 +308,16 @@ bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_t
>> int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
>> struct vfio_irq_info *info);
>> +
>> +/**
>> + * Return the region index associated with a given MemoryRegion. The index
>> + * can be useful in retrieving region info.
>> + *
>> + * @mr: MemoryRegion to use
>> + *
>> + * Returns the region index or -1 on error.
>> + */
>> +int vfio_get_region_index_from_mr(MemoryRegion *mr);
>> #endif
>> /* Returns 0 on success, or a negative errno. */
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices
2026-03-17 10:18 ` Cédric Le Goater
@ 2026-03-18 5:42 ` Kasireddy, Vivek
0 siblings, 0 replies; 22+ messages in thread
From: Kasireddy, Vivek @ 2026-03-18 5:42 UTC (permalink / raw)
To: Cédric Le Goater, qemu-devel@nongnu.org
Cc: Akihiko Odaki, Marc-André Lureau, Alex Bennée,
Dmitry Osipenko, Alex Williamson
Hi Cedric,
> Subject: Re: [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for
> blobs associated with VFIO devices
>
> Hello Vivek,
>
>
> >>>
> >>> On 2026/03/11 11:50, Vivek Kasireddy wrote:
> >>>> In addition to memfd, a blob resource can also have its backing
> >>>> storage in a VFIO device region. Since, there is no effective way to
> >>>> determine where the backing storage is located, we first try to
> >>>> create a dmabuf assuming it is in memfd. If that fails, we try to
> >>>> create a dmabuf assuming it is in VFIO device region.
> >>>>
> >>>> So, we first call virtio_gpu_create_udmabuf() to check if the blob's
> >>>> backing storage is located in a memfd or not. If it is not, we
> >>>> invoke the vfio_device_create_dmabuf_fd() API which identifies
> the
> >>>> right VFIO device and eventually creates a dmabuf fd.
> >>>>
> >>>> Note that, for mmapping the dmabuf, we directly call mmap() if
> the
> >>>> dmabuf fd was created via virtio_gpu_create_udmabuf() since we
> >> know
> >>>> that the udmabuf driver supports mmap(). However, if the dmabuf
> >> was
> >>>> created via vfio_device_create_dmabuf_fd(), we use the
> >>>> vfio_device_mmap_dmabuf() API to get a mapping for the dmabuf.
> >>>>
> >>>> Cc: Marc-André Lureau <marcandre.lureau@redhat.com>
> >>>> Cc: Alex Bennée <alex.bennee@linaro.org>
> >>>> Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> >>>> Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
> >>>> Cc: Alex Williamson <alex@shazbot.org>
> >>>> Cc: Cédric Le Goater <clg@redhat.com>
> >>>> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> >>>
> >>> Now I think this patch implements proper handling of all error
> >>> conditions and conforms the convention.
> >>>
> >>> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
> >> Thank you for taking the time to review these patches!
> > Can this series be merged to vfio-next given the dependencies on
> > the newly added VFIO APIs?
> I could merge in advance the VFIO changes but the series does not
> apply nor compiles.
The current series is based on vfio-next. I'll rebase it on top of Qemu
master for the next version.
> We need feedback from the virtio-gpu maintainers
> that this proposal is a useful feature too.
All the virtio-gpu patches are thoroughly reviewed by Akihiko (who is
a virtio-gpu reviewer).
>
> Since this is QEMU 11.1 material, we have some time. Let me review
> it first.
Ok, sounds good.
Thanks,
Vivek
>
> Thanks,
>
> C.
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region
2026-03-17 15:01 ` Cédric Le Goater
@ 2026-03-18 5:43 ` Kasireddy, Vivek
0 siblings, 0 replies; 22+ messages in thread
From: Kasireddy, Vivek @ 2026-03-18 5:43 UTC (permalink / raw)
To: Cédric Le Goater, qemu-devel@nongnu.org; +Cc: Alex Williamson
> Subject: Re: [PATCH v11 06/10] vfio/region: Add a helper to get region
> index from memory region
>
> On 3/17/26 15:41, Cédric Le Goater wrote:
> > On 3/11/26 03:50, Vivek Kasireddy wrote:
> >> Having a way to figure out the region index (or bar) associated
> >> with a memory region is helpful in various scenarios. For example,
> >> this capability can be useful in retrieving the region info needed
> >> for mapping a part of a VFIO region or creating a dmabuf.
> >>
> >> Cc: Alex Williamson <alex@shazbot.org>
> >> Cc: Cédric Le Goater <clg@redhat.com>
> >> Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> >> ---
> >> hw/vfio/region.c | 14 ++++++++++++++
> >> include/hw/vfio/vfio-device.h | 10 ++++++++++
> >> 2 files changed, 24 insertions(+)
> >>
> >> diff --git a/hw/vfio/region.c b/hw/vfio/region.c
> >> index 47fdc2df34..4cb92216ef 100644
> >> --- a/hw/vfio/region.c
> >> +++ b/hw/vfio/region.c
> >> @@ -539,3 +539,17 @@ void
> vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled)
> >> trace_vfio_region_mmaps_set_enabled(memory_region_name(re
> gion->mem),
> >> enabled);
> >> }
> >> +
> >> +int vfio_get_region_index_from_mr(MemoryRegion *mr)
> >
> >
> > I think you can move this routine as a static in device.c now. No need
> > to export a service.
>
> you can't because of vfio_region_ops.
>
> Returning a VFIORegion seems cleaner though.
I agree. Will make the change in the next version.
Thanks,
Vivek
>
> Thanks,
>
> C.
>
>
> >
> > Thanks,
> >
> > C.
> >
> >> +{
> >> + VFIORegion *region;
> >> +
> >> + while (mr->container) {
> >> + if (mr->ops == &vfio_region_ops) {
> >> + region = mr->opaque;
> >> + return region->nr;
> >> + }
> >> + mr = mr->container;
> >> + }
> >> + return -1;
> >> +}
> >> diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-
> device.h
> >> index 828a31c006..596c7f5a10 100644
> >> --- a/include/hw/vfio/vfio-device.h
> >> +++ b/include/hw/vfio/vfio-device.h
> >> @@ -308,6 +308,16 @@ bool
> vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t
> cap_t
> >> int vfio_device_get_irq_info(VFIODevice *vbasedev, int index,
> >> struct vfio_irq_info *info);
> >> +
> >> +/**
> >> + * Return the region index associated with a given MemoryRegion.
> The index
> >> + * can be useful in retrieving region info.
> >> + *
> >> + * @mr: MemoryRegion to use
> >> + *
> >> + * Returns the region index or -1 on error.
> >> + */
> >> +int vfio_get_region_index_from_mr(MemoryRegion *mr);
> >> #endif
> >> /* Returns 0 on success, or a negative errno. */
> >
^ permalink raw reply [flat|nested] 22+ messages in thread
* RE: [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges
2026-03-17 15:00 ` Cédric Le Goater
@ 2026-03-18 5:49 ` Kasireddy, Vivek
0 siblings, 0 replies; 22+ messages in thread
From: Kasireddy, Vivek @ 2026-03-18 5:49 UTC (permalink / raw)
To: Cédric Le Goater, qemu-devel@nongnu.org, Akihiko Odaki
Cc: Alex Williamson
Hi Cedric,
> Subject: Re: [PATCH v11 07/10] vfio/device: Add support for creating
> dmabuf from multiple ranges
>
> HEllo,
>
> On 3/11/26 03:50, Vivek Kasireddy wrote:
> > In order to create a dmabuf associated with a buffer that spans
> > multiple ranges, we first need to identify the VFIO region and
> > index the buffer (represented by iovec) belongs to and then
> > translate its addresses to offsets within that region.
> >
> > The qemu_ram_block_from_host() API gives us both the region and
> > the offset info we need to populate the dma ranges so that we can
> > invoke the VFIO_DEVICE_FEATURE_DMA_BUF feature to create the
> dmabuf.
> >
> > Also, instead of iterating over all QOM devices to find the
> > VFIODevice associated with a memory region, introduce a helper to
> > just use the vfio_device_list to lookup the VFIODevice.
> >
> > Lastly, introduce an enum to return the type of error encountered
> > while creating the dmabuf fd.
> >
> > Cc: Alex Williamson <alex@shazbot.org>
> > Cc: Cédric Le Goater <clg@redhat.com>
> > Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
> > ---
> > hw/vfio/device.c | 81
> +++++++++++++++++++++++++++++++++++
> > hw/vfio/dmabuf-stubs.c | 17 ++++++++
> > hw/vfio/meson.build | 1 +
> > include/hw/vfio/vfio-device.h | 22 ++++++++++
>
> Please add to your .git/config
>
> [diff]
> orderFile = /path/to/qemu/scripts/git.orderfile
Done. Thank you for the tip.
>
>
>
> > 4 files changed, 121 insertions(+)
> > create mode 100644 hw/vfio/dmabuf-stubs.c
> >
> > diff --git a/hw/vfio/device.c b/hw/vfio/device.c
> > index 973fc35b59..2d01059be0 100644
> > --- a/hw/vfio/device.c
> > +++ b/hw/vfio/device.c
> > @@ -21,6 +21,7 @@
> > #include "qemu/osdep.h"
> > #include <sys/ioctl.h>
> >
> > +#include "system/ramblock.h"
> > #include "hw/vfio/vfio-device.h"
> > #include "hw/vfio/pci.h"
> > #include "hw/core/iommu.h"
> > @@ -644,3 +645,83 @@ static VFIODeviceIOOps
> vfio_device_io_ops_ioctl = {
> > .region_read = vfio_device_io_region_read,
> > .region_write = vfio_device_io_region_write,
> > };
> > +
>
> Please add a comment
>
> /*
> * For virtio-gpu, < explain the context >
> */
Ok, will do.
>
>
> > +static bool vfio_device_lookup(struct iovec *iov, VFIODevice
> **vbasedevp,
> > + Error **errp)
> > +{
> > + VFIODevice *vbasedev;
> > + RAMBlock *first_rb;
> > + ram_addr_t offset;
> > +
> > + first_rb = qemu_ram_block_from_host(iov[0].iov_base, false,
> &offset);
> > + if (!first_rb) {
> > + error_setg(errp, "Could not find first ramblock\n");
> > + return false;
> > + }
> > +
> > + QLIST_FOREACH(vbasedev, &vfio_device_list, next) {
> > + if (vbasedev->dev == first_rb->mr->dev) {
> > + *vbasedevp = vbasedev;
> > + return true;
> > + }
> > + }
> > + error_setg(errp, "No VFIO device found to create dmabuf from\n");
> > + return false;
> > +}
> > +
> > +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int
> iov_cnt,
> > + Error **errp)
> > +{
> > + g_autofree struct vfio_device_feature *feature = NULL;
> > + struct vfio_device_feature_dma_buf *dma_buf;
> > + RAMBlock *rb, *first_rb;
> > + VFIODevice *vbasedev;
> > + ram_addr_t offset;
> > + int i, index, ret;
> > + size_t argsz;
>
> Shouldn't we check iov and iov_cnt values ?
You mean something like this:
if (iov_size(iov, iov_cnt) != dmabuf_size)
and also calling vfio_device_lookup() here instead of below?
>
> > + argsz = sizeof(*feature) + sizeof (*dma_buf) +
> > + sizeof(struct vfio_region_dma_range) * iov_cnt;
> > + feature = g_malloc0(argsz);
> > + *feature = (struct vfio_device_feature) {
> > + .argsz = argsz,
> > + .flags = VFIO_DEVICE_FEATURE_GET |
> VFIO_DEVICE_FEATURE_DMA_BUF,
> > + };
> > + dma_buf = (struct vfio_device_feature_dma_buf *)feature->data;
> > +
> > + if (!vfio_device_lookup(iov, &vbasedev, errp)) {
> > + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> > + }
> > +
> > + for (i = 0; i < iov_cnt; i++) {
> > + rb = qemu_ram_block_from_host(iov[i].iov_base, false, &offset);
> > + if (i == 0) {
> > + first_rb = rb;
> > + }
> > + if (!rb || rb != first_rb) {
> > + error_setg(errp, "Cannot create dmabuf with different
> regions\n");
> > + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> > + }
> > +
> > + index = vfio_get_region_index_from_mr(rb->mr);
>
> returning a VFIORegion seems cleaner.
>
> > + if (index < 0) {
> > + error_setg(errp, "Cannot find region index for dmabuf
> segment\n");
> > + return VFIO_DMABUF_CREATE_ERR_INVALID_IOV;
> > + }
>
>
> Could you please introduce a common helper for the code above that
> could be shared with vfio_device_mmap_dmabuf() ? The same
> sequence
> is duplicated.
Ok, I'll try to add a common helper.
>
>
> > + dma_buf->region_index = index;
> > + dma_buf->dma_ranges[i].offset = offset;
> > + dma_buf->dma_ranges[i].length = iov[i].iov_len;
> > + }
> > +
> > + dma_buf->nr_ranges = iov_cnt;
> > + dma_buf->open_flags = O_RDONLY | O_CLOEXEC;
> > +
> > + ret = vfio_device_get_feature(vbasedev, feature);
> > + if (ret < 0) {
> > + error_setg_errno(errp, -ret,
> > + "Could not create dmabuf fd via VFIO device");
> > + return VFIO_DMABUF_CREATE_ERR_UNSPEC;
>
> See vfio_region_create_dma_buf() for possible errors. You might want
> to introduce a helper.
IIUC, for this use-case, I think we want to treat any error here as a failure
instead of treating ENOTTY as success like in the case of
vfio_region_create_dma_buf().
>
>
> > + }
> > + return ret;
> > +}
> > diff --git a/hw/vfio/dmabuf-stubs.c b/hw/vfio/dmabuf-stubs.c
> > new file mode 100644
> > index 0000000000..e71e2b68dd
> > --- /dev/null
> > +++ b/hw/vfio/dmabuf-stubs.c
> > @@ -0,0 +1,17 @@
> > +/*
> > + * Copyright (c) 2026 Intel and/or its affiliates.
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/error-report.h"
> > +#include "qemu/iov.h"
> > +#include "hw/vfio/vfio-device.h"
> > +
> > +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int
> iov_cnt,
> > + Error **errp)
> > +{
> > + error_setg(errp, "VFIO dmabuf support is not enabled");
> > + return VFIO_DMABUF_CREATE_HOST_ERROR;
> > +}
> > diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build
> > index 82f68698fb..ac899d30a8 100644
> > --- a/hw/vfio/meson.build
> > +++ b/hw/vfio/meson.build
> > @@ -34,3 +34,4 @@ system_ss.add(when: 'CONFIG_IOMMUFD',
> if_false: files('iommufd-stubs.c'))
> > system_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files(
> > 'display.c',
> > ))
> > +system_ss.add(when: 'CONFIG_VFIO', if_false: files('dmabuf-stubs.c'))
> > diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-
> device.h
> > index 596c7f5a10..566e5d8bc0 100644
> > --- a/include/hw/vfio/vfio-device.h
> > +++ b/include/hw/vfio/vfio-device.h
> > @@ -41,6 +41,13 @@ enum {
> > VFIO_DEVICE_TYPE_AP = 3,
> > };
> >
> > +enum {
> > + /* The Guest passed addresses stored in IOV are invalid */
> > + VFIO_DMABUF_CREATE_ERR_INVALID_IOV = -1,
> > + /* Guest or Host may be at fault for this type of error */
> > + VFIO_DMABUF_CREATE_ERR_UNSPEC = -2,
> > +};
>
> This is overkill. Please return a bool value and ensure the errp
> argument is correctly filled.
Having these specific errors is really useful as it makes the dmabuf
handling in virtio-gpu very intuitive and sensible. Akihiko (virtio-gpu
reviewer) suggested this mechanism and can add more comments
or explain the rationale for this.
Thanks,
Vivek
>
> > +
> > typedef struct VFIODeviceOps VFIODeviceOps;
> > typedef struct VFIODeviceIOOps VFIODeviceIOOps;
> > typedef struct VFIOMigration VFIOMigration;
> > @@ -318,6 +325,21 @@ int vfio_device_get_irq_info(VFIODevice
> *vbasedev, int index,
> > * Returns the region index or -1 on error.
> > */
> > int vfio_get_region_index_from_mr(MemoryRegion *mr);
> > +
> > +/**
> > + * Create a dmabuf fd by first translating the addresses in the
> > + * iovec array into VFIO region offsets and then invoking the
> > + * VFIO_DEVICE_FEATURE_DMA_BUF feature.
> > + *
> > + * @iov: array of iovec entries associated with a buffer
> > + * @iov_cnt: number of entries in the iovec array
> > + * @errp: pointer to Error*, to store an error if it happens.
> > + *
> > + * Returns the created dmabuf fd or either
> VFIO_DMABUF_CREATE_ERR_UNSPEC
> > + * or VFIO_DMABUF_CREATE_ERR_INVALID_IOV on error.
> > + */
> > +int vfio_device_create_dmabuf_fd(struct iovec *iov, unsigned int
> iov_cnt,
> > + Error **errp);
> > #endif
> >
> > /* Returns 0 on success, or a negative errno. */
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-03-18 5:50 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-11 2:50 [PATCH v11 00/10] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 01/10] virtio-gpu: Recreate the resource's dmabuf if new backing is attached Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 02/10] virtio-gpu: Find hva for Guest's DMA addr associated with a ram device Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 03/10] virtio-gpu: Rename udmabuf files and helpers to dmabuf Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 04/10] virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from virtio_gpu_create_udmabuf() Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 05/10] virtio-gpu-dmabuf: Use g_autofree for the list pointer Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 06/10] vfio/region: Add a helper to get region index from memory region Vivek Kasireddy
2026-03-17 14:41 ` Cédric Le Goater
2026-03-17 15:01 ` Cédric Le Goater
2026-03-18 5:43 ` Kasireddy, Vivek
2026-03-11 2:50 ` [PATCH v11 07/10] vfio/device: Add support for creating dmabuf from multiple ranges Vivek Kasireddy
2026-03-17 15:00 ` Cédric Le Goater
2026-03-18 5:49 ` Kasireddy, Vivek
2026-03-11 2:50 ` [PATCH v11 08/10] vfio/device: Add a helper to mmap a dmabuf Vivek Kasireddy
2026-03-11 2:50 ` [PATCH v11 09/10] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum Vivek Kasireddy
2026-03-11 5:16 ` Akihiko Odaki
2026-03-11 2:50 ` [PATCH v11 10/10] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Vivek Kasireddy
2026-03-11 5:21 ` Akihiko Odaki
2026-03-12 5:41 ` Kasireddy, Vivek
2026-03-17 5:42 ` Kasireddy, Vivek
2026-03-17 10:18 ` Cédric Le Goater
2026-03-18 5:42 ` Kasireddy, Vivek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox