From: Marc-André Lureau <[email protected]> When virtio_gpu_rutabaga_get_num_capsets() returns 0, virtio_init() isn't called and the device later crashes during realize. ==72545==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x556ad6f7ba9e bp 0x7ffe6958f810 sp 0x7ffe6958f7e0 T0) ==72545==The signal is caused by a READ memory access. ==72545==Hint: address points to the zero page. #0 0x556ad6f7ba9e in virtio_memory_listener_commit ../hw/virtio/virtio.c:4034 #1 0x556ad6a24c96 in listener_add_address_space ../system/memory.c:3128 #2 0x556ad6a25d15 in memory_listener_register ../system/memory.c:3216 #3 0x556ad6f7bf11 in virtio_device_realize ../hw/virtio/virtio.c:4075
Rework error handling of the function to set Error appropriately. 0 capset may be ok now. Signed-off-by: Marc-André Lureau <[email protected]> --- hw/display/virtio-gpu-rutabaga.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c index ed5ae52acbe..ebb6c783fb0 100644 --- a/hw/display/virtio-gpu-rutabaga.c +++ b/hw/display/virtio-gpu-rutabaga.c @@ -1032,19 +1032,19 @@ static bool virtio_gpu_rutabaga_init(VirtIOGPU *g, Error **errp) return true; } -static int virtio_gpu_rutabaga_get_num_capsets(VirtIOGPU *g) +static bool +virtio_gpu_rutabaga_get_num_capsets(VirtIOGPU *g, uint32_t *num_capsets, Error **errp) { int result; - uint32_t num_capsets; VirtIOGPURutabaga *vr = VIRTIO_GPU_RUTABAGA(g); - result = rutabaga_get_num_capsets(vr->rutabaga, &num_capsets); + result = rutabaga_get_num_capsets(vr->rutabaga, num_capsets); if (result) { - error_report("Failed to get capsets"); - return 0; + error_setg_errno(errp, -result, "Failed to get num_capsets"); + return false; } - vr->num_capsets = num_capsets; - return num_capsets; + vr->num_capsets = *num_capsets; + return true; } static void virtio_gpu_rutabaga_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) @@ -1070,7 +1070,7 @@ static void virtio_gpu_rutabaga_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) static void virtio_gpu_rutabaga_realize(DeviceState *qdev, Error **errp) { - int num_capsets; + uint32_t num_capsets; VirtIOGPUBase *bdev = VIRTIO_GPU_BASE(qdev); VirtIOGPU *gpudev = VIRTIO_GPU(qdev); @@ -1083,8 +1083,7 @@ static void virtio_gpu_rutabaga_realize(DeviceState *qdev, Error **errp) return; } - num_capsets = virtio_gpu_rutabaga_get_num_capsets(gpudev); - if (!num_capsets) { + if (!virtio_gpu_rutabaga_get_num_capsets(gpudev, &num_capsets, errp)) { return; } -- 2.52.0
