mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
hw/display/virtio-gpu: Avoid leaking migration blocker
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: d3a4969dc5 ("Support per-head resolutions with virtio-gpu")
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260725-virgl-v1-1-58bb51e60da5@rsg.ci.i.u-tokyo.ac.jp>
This commit is contained in:
parent
4ae1c5c7d6
commit
8dc8449a67
1 changed files with 16 additions and 21 deletions
|
|
@ -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 =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue