diff options
author | Dmitry Osipenko <dmitry.osipenko@collabora.com> | 2024-10-25 00:03:02 +0300 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2024-10-28 16:56:35 +0000 |
commit | 7e688d1bf515316e1e334eb5dcb3dd1577810fe3 (patch) | |
tree | f0c3a682b24a275c17488fc0082b43e379d30ab0 /hw/display/virtio-gpu-gl.c | |
parent | a0a8f47fd0d5dc11487bb65e005700d7b984a207 (diff) | |
download | qemu-7e688d1bf515316e1e334eb5dcb3dd1577810fe3.zip qemu-7e688d1bf515316e1e334eb5dcb3dd1577810fe3.tar.gz qemu-7e688d1bf515316e1e334eb5dcb3dd1577810fe3.tar.bz2 |
virtio-gpu: Handle virtio_gpu_virgl_init() failure
virtio_gpu_virgl_init() may fail, leading to a further Qemu crash
because Qemu assumes it never fails. Check virtio_gpu_virgl_init()
return code and don't execute virtio commands on error. Failed
virtio_gpu_virgl_init() will result in a timed out virtio commands
for a guest OS.
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Message-Id: <20241024210311.118220-5-dmitry.osipenko@collabora.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Diffstat (limited to 'hw/display/virtio-gpu-gl.c')
-rw-r--r-- | hw/display/virtio-gpu-gl.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c index 29d20b0..ea3413a 100644 --- a/hw/display/virtio-gpu-gl.c +++ b/hw/display/virtio-gpu-gl.c @@ -29,9 +29,14 @@ static void virtio_gpu_gl_update_cursor_data(VirtIOGPU *g, struct virtio_gpu_scanout *s, uint32_t resource_id) { + VirtIOGPUGL *gl = VIRTIO_GPU_GL(g); uint32_t width, height; uint32_t pixels, *data; + if (gl->renderer_state != RS_INITED) { + return; + } + data = virgl_renderer_get_cursor_data(resource_id, &width, &height); if (!data) { return; @@ -65,13 +70,22 @@ static void virtio_gpu_gl_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) return; } - if (!gl->renderer_inited) { - virtio_gpu_virgl_init(g); - gl->renderer_inited = true; - } - if (gl->renderer_reset) { - gl->renderer_reset = false; + switch (gl->renderer_state) { + case RS_RESET: virtio_gpu_virgl_reset(g); + /* fallthrough */ + case RS_START: + if (virtio_gpu_virgl_init(g)) { + gl->renderer_state = RS_INIT_FAILED; + return; + } + + gl->renderer_state = RS_INITED; + break; + case RS_INIT_FAILED: + return; + case RS_INITED: + break; } cmd = virtqueue_pop(vq, sizeof(struct virtio_gpu_ctrl_command)); @@ -98,9 +112,9 @@ static void virtio_gpu_gl_reset(VirtIODevice *vdev) * GL functions must be called with the associated GL context in main * thread, and when the renderer is unblocked. */ - if (gl->renderer_inited && !gl->renderer_reset) { + if (gl->renderer_state == RS_INITED) { virtio_gpu_virgl_reset_scanout(g); - gl->renderer_reset = true; + gl->renderer_state = RS_RESET; } } |