On 2026/08/25 19:20, Marc-André Lureau wrote:
A scanout may hold an active QemuDmaBuf when a SET_SCANOUT switches to
CPU-backed display data. Force surface recreation and release the old
buffer in this case.


Fixes: 32db3c63ae11 ("virtio-gpu: Add virtio_gpu_set_scanout_blob")

Signed-off-by: Marc-André Lureau <[email protected]>
---
  hw/display/virtio-gpu.c | 13 +++++++++----
  1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 5362f7a4c269..a74475dc6741 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -658,9 +658,11 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
  {
      struct virtio_gpu_scanout *scanout;
      uint32_t bytes_pp = virtio_gpu_format_bytes_pp(fb->format);
+    bool was_dmabuf;
      uint8_t *data;
scanout = &g->parent_obj.scanout[scanout_id];
+    was_dmabuf = scanout->dmabuf != NULL;
if (!virtio_gpu_check_scanout_bounds(scanout_id, res->resource_id,
                                           fb->width, fb->height, r, error)) {
@@ -687,12 +689,11 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
if (res->blob) {
          if (qemu_console_has_gl(scanout->con)) {
-            if (!virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) {
-                virtio_gpu_update_scanout(g, scanout_id, res, fb, r);
-            } else {
+            if (virtio_gpu_update_dmabuf(g, scanout_id, res, fb, r)) {
                  *error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
                  return false;
              }
+            virtio_gpu_update_scanout(g, scanout_id, res, fb, r);
              return true;
          }
@@ -702,7 +703,8 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
      }
/* create a surface for this scanout */
-    if ((res->blob && !qemu_console_has_gl(scanout->con)) ||
+    if (was_dmabuf ||
+        (res->blob && !qemu_console_has_gl(scanout->con)) ||
          !scanout->ds ||
          surface_data(scanout->ds) != data + fb->offset ||
          scanout->width != r->width ||
@@ -727,6 +729,9 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
          qemu_displaysurface_set_share_handle(scanout->ds, res->share_handle, 
fb->offset);
pixman_image_unref(rect);
+        if (was_dmabuf) {
+            virtio_gpu_release_scanout_dmabuf(g, scanout_id);
+        }
          qemu_console_set_surface(g->parent_obj.scanout[scanout_id].con,
                                  scanout->ds);
      }



Reply via email to