Commit a891d5731f for qemu.org
commit a891d5731feca1ad45bf9964b5ad63c06a1824f9
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date: Thu Aug 20 17:52:21 2026 +0400
virtio-gpu: release dmabuf when switching to a surface
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")
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.c b/hw/display/virtio-gpu.c
index 6e021b78b8..b2cba26405 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -704,9 +704,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)) {
@@ -733,12 +735,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;
}
@@ -748,7 +749,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 ||
@@ -773,6 +775,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);
}