From: Vivek Kasireddy <vivek.kasireddy@intel.com>
To: qemu-devel@nongnu.org
Cc: "Vivek Kasireddy" <vivek.kasireddy@intel.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Akihiko Odaki" <odaki@rsg.ci.i.u-tokyo.ac.jp>,
"Dmitry Osipenko" <dmitry.osipenko@collabora.com>,
"Alex Williamson" <alex@shazbot.org>,
"Cédric Le Goater" <clg@redhat.com>
Subject: [PATCH v13 8/9] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum
Date: Wed, 7 Oct 2026 13:09:27 -0700 [thread overview]
Message-ID: <20261007201222.648687-9-vivek.kasireddy@intel.com> (raw)
In-Reply-To: <20261007201222.648687-1-vivek.kasireddy@intel.com>
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().
Furtheremore, the main reason for using the VFIO enum is to handle
the special INVALID_IOV case which can happen in two scenarios:
1) When the Blob resource's memory is backed by a VFIO region. This
would cause INVALID_IOV error when we try to create a dmabuf via
udmabuf driver but we can recover from this error by having the
dmabuf be created by the VFIO driver instead.
2) When the Blob resource's memory is not backed by memfd or VFIO
region. In this case, since the error can be attributed to the
guest, we should use qemu_log_mask() instead of error_report_err()
and emit a message that can be used to debug the guest error.
Note that, to diagnose errors, a common pattern is to return -errno
to enable the caller to implement specific error handling. However, in
this case, since we want to distinguish the INVALID_IOV error from other
errors, using the VFIO enum allows us to do so and is very convenient.
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 | 69 ++++++++++++++++++++++------------
1 file changed, 46 insertions(+), 23 deletions(-)
diff --git a/hw/display/virtio-gpu-dmabuf.c b/hw/display/virtio-gpu-dmabuf.c
index 6f05f367d0..c9de8e9ba3 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,28 +28,32 @@
#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_try_malloc0(sizeof(struct udmabuf_create_list) +
sizeof(struct udmabuf_create_item) * res->iov_cnt);
if (!list) {
- return;
+ error_setg(errp, "failed to allocate udmabuf create list");
+ return VFIO_DMABUF_CREATE_ERR_UNSPEC;
}
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;
@@ -59,22 +64,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;
}
void virtio_gpu_fini_dmabuf(struct virtio_gpu_simple_resource *res)
@@ -130,6 +141,7 @@ bool virtio_gpu_have_udmabuf(void)
bool virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res)
{
+ Error *local_err = NULL;
void *pdata = NULL;
res->dmabuf_fd = -1;
@@ -137,17 +149,28 @@ bool virtio_gpu_init_dmabuf(struct virtio_gpu_simple_resource *res)
res->iov[0].iov_len < 4096) {
pdata = res->iov[0].iov_base;
} else if (res->blob_size) {
- 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 false;
+ } else if (res->dmabuf_fd >= 0) {
+ pdata = virtio_gpu_remap_dmabuf(res, &local_err);
+ if (!pdata) {
+ virtio_gpu_fini_dmabuf(res);
+ }
+ } else {
+ res->dmabuf_fd = -1;
+ }
+
if (res->dmabuf_fd < 0) {
- return false;
- }
- virtio_gpu_remap_dmabuf(res);
- if (!res->remapped) {
- virtio_gpu_fini_dmabuf(res);
+ error_report_err(local_err);
return false;
}
res->share_handle = res->dmabuf_fd;
- pdata = res->remapped;
+ res->remapped = pdata;
}
res->blob = pdata;
--
2.53.0
next prev parent reply other threads:[~2026-10-07 20:15 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 20:09 [PATCH v13 0/9] vfio: Create dmabuf from multiple VFIO ranges and use it in virtio-gpu Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 1/9] virtio-gpu: Find hva for Guest's DMA addr associated with a ram device Vivek Kasireddy
2026-10-08 9:02 ` Akihiko Odaki
2026-10-09 4:32 ` Kasireddy, Vivek
2026-10-09 9:26 ` Akihiko Odaki
2026-10-12 6:10 ` Kasireddy, Vivek
2026-10-07 20:09 ` [PATCH v13 2/9] virtio-gpu: Rename udmabuf files and helpers to dmabuf Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 3/9] virtio-gpu-dmabuf: Remove rcu_read_lock/unlock from virtio_gpu_create_udmabuf() Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 4/9] virtio-gpu-dmabuf: Use g_autofree for the list pointer Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 5/9] vfio/region: Add a helper to get VFIO region from memory region Vivek Kasireddy
2026-10-07 20:09 ` [PATCH v13 6/9] vfio/device: Add support for creating dmabuf from multiple ranges Vivek Kasireddy
2026-10-08 9:08 ` Akihiko Odaki
2026-10-09 4:24 ` Kasireddy, Vivek
2026-10-09 8:13 ` Cédric Le Goater
2026-10-12 6:27 ` Kasireddy, Vivek
2026-10-12 14:01 ` Akihiko Odaki
2026-10-13 4:06 ` Kasireddy, Vivek
2026-10-13 16:20 ` Cédric Le Goater
2026-10-14 2:17 ` Akihiko Odaki
2026-10-14 7:41 ` Cédric Le Goater
2026-10-14 16:40 ` Cédric Le Goater
2026-10-14 7:03 ` Markus Armbruster
2026-10-14 13:07 ` Akihiko Odaki
2026-10-14 16:29 ` Cédric Le Goater
2026-10-13 16:40 ` Cédric Le Goater
2026-10-07 20:09 ` [PATCH v13 7/9] vfio/device: Add a helper to mmap a dmabuf Vivek Kasireddy
2026-10-09 8:13 ` Cédric Le Goater
2026-10-07 20:09 ` Vivek Kasireddy [this message]
2026-10-09 8:17 ` [PATCH v13 8/9] virtio-gpu-dmabuf: Improve error handling with 'Error **' and err enum Cédric Le Goater
2026-10-07 20:09 ` [PATCH v13 9/9] virtio-gpu-dmabuf: Create dmabuf for blobs associated with VFIO devices Vivek Kasireddy
2026-10-08 9:11 ` Akihiko Odaki
2026-10-09 4:26 ` Kasireddy, Vivek
2026-10-09 9:51 ` Akihiko Odaki
2026-10-12 6:14 ` Kasireddy, Vivek
2026-10-12 14:00 ` Akihiko Odaki
2026-10-13 3:57 ` Kasireddy, Vivek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261007201222.648687-9-vivek.kasireddy@intel.com \
--to=vivek.kasireddy@intel.com \
--cc=alex.bennee@linaro.org \
--cc=alex@shazbot.org \
--cc=clg@redhat.com \
--cc=dmitry.osipenko@collabora.com \
--cc=marcandre.lureau@redhat.com \
--cc=odaki@rsg.ci.i.u-tokyo.ac.jp \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.