On Sat, Jul 25, 2026 at 11:15 AM Akihiko Odaki
<[email protected]> wrote:
>
> 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 <[email protected]>

Reviewed-by: Marc-André Lureau <[email protected]>

> ---
>  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 <[email protected]>
>
>


-- 
Marc-André Lureau

Reply via email to