virtio_gpu_base_device_realize() leaks a migration blocker if a
check of the output list fails after adding one. Perform the check
before adding a migration blocker to avoid the leak. This also
simplifies the code by merging two loops.
Fixes: d3a4969dc5ac ("Support per-head resolutions with virtio-gpu")
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
---
hw/display/virtio-gpu-base.c | 37 ++++++++++++++++---------------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index a68b18482956..946e56b42f61 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -195,6 +195,11 @@ virtio_gpu_base_device_realize(DeviceState *qdev,
return false;
}
+ g->enabled_output_bitmask = 1;
+
+ g->req_state[0].width = g->conf.xres;
+ g->req_state[0].height = g->conf.yres;
+
for (output_idx = 0, node = g->conf.outputs;
node; output_idx++, node = node->next) {
if (output_idx == g->conf.max_outputs) {
@@ -207,6 +212,17 @@ virtio_gpu_base_device_realize(DeviceState *qdev,
node->value->name, EDID_NAME_MAX_LENGTH);
return false;
}
+ if (node->value->has_xres != node->value->has_yres) {
+ error_setg(errp,
+ "must set both outputs[%zd].xres and outputs[%zd].yres",
+ output_idx, output_idx);
+ return false;
+ }
+ if (node->value->has_xres && node->value->has_yres) {
+ g->enabled_output_bitmask |= (1 << output_idx);
+ g->req_state[output_idx].width = node->value->xres;
+ g->req_state[output_idx].height = node->value->yres;
+ }
}
if (virtio_gpu_virgl_enabled(g->conf)) {
@@ -229,27 +245,6 @@ virtio_gpu_base_device_realize(DeviceState *qdev,
virtio_add_queue(vdev, 16, cursor_cb);
}
- g->enabled_output_bitmask = 1;
-
- g->req_state[0].width = g->conf.xres;
- g->req_state[0].height = g->conf.yres;
-
- for (output_idx = 0, node = g->conf.outputs;
- node && output_idx < g->conf.max_outputs;
- output_idx++, node = node->next) {
- if (node->value->has_xres != node->value->has_yres) {
- error_setg(errp,
- "must set both outputs[%zd].xres and outputs[%zd].yres",
- output_idx, output_idx);
- return false;
- }
- if (node->value->has_xres && node->value->has_yres) {
- g->enabled_output_bitmask |= (1 << output_idx);
- g->req_state[output_idx].width = node->value->xres;
- g->req_state[output_idx].height = node->value->yres;
- }
- }
-
g->hw_ops = &virtio_gpu_ops;
for (i = 0; i < g->conf.max_outputs; i++) {
g->scanout[i].con =
---
base-commit: 006a22cb26998998385b104db1ff9466ef2f3153
change-id: 20260725-virgl-065c44b7bd4f
Best regards,
--
Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>