After guest VM resumed, you will get a black screen, and the display can't come back. It is because when guest did resuming, it called into qemu to call virtio_gpu_gl_reset. In that function, it destroyed resources created by command VIRTIO_GPU_CMD_RESOURCE_CREATE_*, which were used for display. As a result, guest's screen can't come back to the time when it was suspended.
So when freeze_mode is set FREEZE_S3 by guest, we can know that guest is doing S3, and we can prevent Qemu to destroy the resources. Signed-off-by: Jiqian Chen <jiqian.c...@amd.com> --- hw/display/virtio-gpu-gl.c | 9 ++++++++- hw/display/virtio-gpu.c | 12 ++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c index e06be60dfb..2519dc12ff 100644 --- a/hw/display/virtio-gpu-gl.c +++ b/hw/display/virtio-gpu-gl.c @@ -100,7 +100,14 @@ static void virtio_gpu_gl_reset(VirtIODevice *vdev) */ if (gl->renderer_inited && !gl->renderer_reset) { virtio_gpu_virgl_reset_scanout(g); - gl->renderer_reset = true; + /* + * If guest is suspending, we shouldn't reset renderer, + * otherwise, the display can't come back to the time when + * it was suspended after guest resumed. + */ + if (vdev->freeze_mode != VIRTIO_PCI_FREEZE_MODE_FREEZE_S3) { + gl->renderer_reset = true; + } } } diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 93857ad523..d363b886dc 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -1412,11 +1412,19 @@ static void virtio_gpu_device_unrealize(DeviceState *qdev) static void virtio_gpu_reset_bh(void *opaque) { VirtIOGPU *g = VIRTIO_GPU(opaque); + VirtIODevice *vdev = &g->parent_obj.parent_obj; struct virtio_gpu_simple_resource *res, *tmp; int i = 0; - QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) { - virtio_gpu_resource_destroy(g, res); + /* + * If guest is suspending, we shouldn't destroy resources, + * otherwise, the display can't come back to the time when + * it was suspended after guest resumed. + */ + if (vdev->freeze_mode != VIRTIO_PCI_FREEZE_MODE_FREEZE_S3) { + QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) { + virtio_gpu_resource_destroy(g, res); + } } for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { -- 2.34.1