Commit d814b44636 for qemu.org

commit d814b44636d077c2704245cdcec811168253a56b
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date:   Wed Aug 26 23:48:29 2026 +0400

    hw/display/virtio-gpu: introduce virtio_gpu_{simple,virgl}_resource_new()

    All allocation sites used g_new0() which zero-initializes fields.
    However share_handle must be SHAREABLE_NONE (-1 on Unix, NULL on
    Windows) and dmabuf_fd must be -1, not 0. Centralize allocation and
    field initialization in new constructors fix this and reduce code
    duplication.

    This fixes -display dbus with virtio-gpu blob resources. The other
    end is currently receiving qemu fd 0.

    Fixes: 5f899c34af1d (“virtio-gpu: allocate shareable 2d resources on !win32”)
    Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
    Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>

diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c
index 041216a10d..b8f8a2068d 100644
--- a/hw/display/virtio-gpu-rutabaga.c
+++ b/hw/display/virtio-gpu-rutabaga.c
@@ -100,12 +100,8 @@ rutabaga_cmd_create_resource_2d(VirtIOGPU *g,
     result = rutabaga_resource_create_3d(vr->rutabaga, c2d.resource_id, &rc_3d);
     CHECK(!result, cmd);

-    res = g_new0(struct virtio_gpu_simple_resource, 1);
-    res->width = c2d.width;
-    res->height = c2d.height;
-    res->format = c2d.format;
-    res->resource_id = c2d.resource_id;
-
+    res = virtio_gpu_simple_resource_new(c2d.resource_id, c2d.width,
+                                         c2d.height, c2d.format);
     QTAILQ_INSERT_HEAD(&g->reslist, res, next);
 }

@@ -139,12 +135,8 @@ rutabaga_cmd_create_resource_3d(VirtIOGPU *g,
     result = rutabaga_resource_create_3d(vr->rutabaga, c3d.resource_id, &rc_3d);
     CHECK(!result, cmd);

-    res = g_new0(struct virtio_gpu_simple_resource, 1);
-    res->width = c3d.width;
-    res->height = c3d.height;
-    res->format = c3d.format;
-    res->resource_id = c3d.resource_id;
-
+    res = virtio_gpu_simple_resource_new(c3d.resource_id, c3d.width,
+                                         c3d.height, c3d.format);
     QTAILQ_INSERT_HEAD(&g->reslist, res, next);
 }

@@ -634,10 +626,7 @@ rutabaga_cmd_resource_create_blob(VirtIOGPU *g,

     CHECK(cblob.resource_id != 0, cmd);

-    res = g_new0(struct virtio_gpu_simple_resource, 1);
-
-    res->resource_id = cblob.resource_id;
-    res->blob_size = cblob.size;
+    res = virtio_gpu_simple_resource_new_blob(cblob.resource_id, cblob.size);

     if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
         result = virtio_gpu_create_mapping_iov(g, cblob.nr_entries,
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 9bda572426..742d9dde4a 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -309,6 +309,33 @@ virtio_gpu_virgl_unmap_resource_blob(VirtIOGPU *g,
 }
 #endif

+static struct virtio_gpu_virgl_resource *
+virtio_gpu_virgl_resource_new(uint32_t resource_id, uint32_t width,
+                              uint32_t height, uint32_t format)
+{
+    struct virtio_gpu_virgl_resource *res;
+
+    res = g_new0(struct virtio_gpu_virgl_resource, 1);
+    virtio_gpu_simple_resource_init(&res->base, resource_id);
+    res->base.width = width;
+    res->base.height = height;
+    res->base.format = format;
+
+    return res;
+}
+
+static struct virtio_gpu_virgl_resource *
+virtio_gpu_virgl_resource_new_blob(uint32_t resource_id, uint64_t blob_size)
+{
+    struct virtio_gpu_virgl_resource *res;
+
+    res = g_new0(struct virtio_gpu_virgl_resource, 1);
+    virtio_gpu_simple_resource_init(&res->base, resource_id);
+    res->base.blob_size = blob_size;
+
+    return res;
+}
+
 static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
                                          struct virtio_gpu_ctrl_command *cmd)
 {
@@ -335,12 +362,8 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
         return;
     }

-    res = g_new0(struct virtio_gpu_virgl_resource, 1);
-    res->base.width = c2d.width;
-    res->base.height = c2d.height;
-    res->base.format = c2d.format;
-    res->base.resource_id = c2d.resource_id;
-    res->base.dmabuf_fd = -1;
+    res = virtio_gpu_virgl_resource_new(c2d.resource_id, c2d.width,
+                                        c2d.height, c2d.format);
     QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);

     args.handle = c2d.resource_id;
@@ -383,12 +406,8 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
         return;
     }

-    res = g_new0(struct virtio_gpu_virgl_resource, 1);
-    res->base.width = c3d.width;
-    res->base.height = c3d.height;
-    res->base.format = c3d.format;
-    res->base.resource_id = c3d.resource_id;
-    res->base.dmabuf_fd = -1;
+    res = virtio_gpu_virgl_resource_new(c3d.resource_id, c3d.width,
+                                        c3d.height, c3d.format);
     QTAILQ_INSERT_HEAD(&g->reslist, &res->base, next);

     args.handle = c3d.resource_id;
@@ -853,10 +872,7 @@ static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
         return;
     }

-    res = g_new0(struct virtio_gpu_virgl_resource, 1);
-    res->base.resource_id = cblob.resource_id;
-    res->base.blob_size = cblob.size;
-    res->base.dmabuf_fd = -1;
+    res = virtio_gpu_virgl_resource_new_blob(cblob.resource_id, cblob.size);

     if (cblob.blob_mem != VIRTIO_GPU_BLOB_MEM_HOST3D) {
         ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 3c3539e337..cb45360e76 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -41,6 +41,42 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,

 static void virtio_gpu_reset_bh(void *opaque);

+void
+virtio_gpu_simple_resource_init(struct virtio_gpu_simple_resource *res,
+                               uint32_t resource_id)
+{
+    res->share_handle = SHAREABLE_NONE;
+    res->dmabuf_fd = -1;
+    res->resource_id = resource_id;
+}
+
+struct virtio_gpu_simple_resource *
+virtio_gpu_simple_resource_new(uint32_t resource_id, uint32_t width,
+                               uint32_t height, uint32_t format)
+{
+    struct virtio_gpu_simple_resource *res;
+
+    res = g_new0(struct virtio_gpu_simple_resource, 1);
+    virtio_gpu_simple_resource_init(res, resource_id);
+    res->width = width;
+    res->height = height;
+    res->format = format;
+
+    return res;
+}
+
+struct virtio_gpu_simple_resource *
+virtio_gpu_simple_resource_new_blob(uint32_t resource_id, uint64_t blob_size)
+{
+    struct virtio_gpu_simple_resource *res;
+
+    res = g_new0(struct virtio_gpu_simple_resource, 1);
+    virtio_gpu_simple_resource_init(res, resource_id);
+    res->blob_size = blob_size;
+
+    return res;
+}
+
 void virtio_gpu_update_cursor_data(VirtIOGPU *g,
                                    struct virtio_gpu_scanout *s,
                                    uint32_t resource_id)
@@ -267,12 +303,8 @@ static void virtio_gpu_resource_create_2d(VirtIOGPU *g,
         return;
     }

-    res = g_new0(struct virtio_gpu_simple_resource, 1);
-
-    res->width = c2d.width;
-    res->height = c2d.height;
-    res->format = c2d.format;
-    res->resource_id = c2d.resource_id;
+    res = virtio_gpu_simple_resource_new(c2d.resource_id, c2d.width,
+                                         c2d.height, c2d.format);

     pformat = virtio_gpu_get_pixman_format(c2d.format);
     if (!pformat) {
@@ -353,9 +385,7 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
         return;
     }

-    res = g_new0(struct virtio_gpu_simple_resource, 1);
-    res->resource_id = cblob.resource_id;
-    res->blob_size = cblob.size;
+    res = virtio_gpu_simple_resource_new_blob(cblob.resource_id, cblob.size);

     if (cblob.nr_entries) {
         ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
@@ -1455,16 +1485,17 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,

     resource_id = qemu_get_be32(f);
     while (resource_id != 0) {
+        uint32_t width, height, format;
+
         res = virtio_gpu_find_resource(g, resource_id);
         if (res) {
             return -EINVAL;
         }

-        res = g_new0(struct virtio_gpu_simple_resource, 1);
-        res->resource_id = resource_id;
-        res->width = qemu_get_be32(f);
-        res->height = qemu_get_be32(f);
-        res->format = qemu_get_be32(f);
+        width = qemu_get_be32(f);
+        height = qemu_get_be32(f);
+        format = qemu_get_be32(f);
+        res = virtio_gpu_simple_resource_new(resource_id, width, height, format);
         res->iov_cnt = qemu_get_be32(f);

         /* allocate */
@@ -1568,14 +1599,15 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,

     resource_id = qemu_get_be32(f);
     while (resource_id != 0) {
+        uint32_t blob_size;
+
         res = virtio_gpu_find_resource(g, resource_id);
         if (res) {
             return -EINVAL;
         }

-        res = g_new0(struct virtio_gpu_simple_resource, 1);
-        res->resource_id = resource_id;
-        res->blob_size = qemu_get_be32(f);
+        blob_size = qemu_get_be32(f);
+        res = virtio_gpu_simple_resource_new_blob(resource_id, blob_size);
         res->iov_cnt = qemu_get_be32(f);

         if (res->iov_cnt) {
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 69b5ee2e38..8c0df60b3b 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -64,6 +64,17 @@ struct virtio_gpu_simple_resource {
     QTAILQ_ENTRY(virtio_gpu_simple_resource) next;
 };

+void
+virtio_gpu_simple_resource_init(struct virtio_gpu_simple_resource *res,
+                               uint32_t resource_id);
+
+struct virtio_gpu_simple_resource *
+virtio_gpu_simple_resource_new(uint32_t resource_id, uint32_t width,
+                               uint32_t height, uint32_t format);
+
+struct virtio_gpu_simple_resource *
+virtio_gpu_simple_resource_new_blob(uint32_t resource_id, uint64_t blob_size);
+
 struct virtio_gpu_framebuffer {
     pixman_format_code_t format;
     uint32_t width, height;