On Tue, Sep 8, 2026 at 10:13 AM Akihiko Odaki
<[email protected]> wrote:
>
> Blob unmapping may be suspended because of remaining uses of the
> mapping. virtio_gpu_process_cmdq() uses the following condition to
> detect a suspended command:
>
>     !cmd->finished && !(cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE)
>
> However, the guest may set VIRTIO_GPU_FLAG_FENCE for a command that
> performs blob unmapping. Such a command will be incorrectly assumed
> as not being suspended. Add a dedicated flag for the suspended state
> to avoid overloading VIRTIO_GPU_FLAG_FENCE.
>
> Fixes: 640f9149c3dc ("virtio-gpu: Support suspension of commands processing")
> Signed-off-by: Akihiko Odaki <[email protected]>

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

> ---
>  include/hw/virtio/virtio-gpu.h |  1 +
>  hw/display/virtio-gpu-virgl.c  | 17 +++++++----------
>  hw/display/virtio-gpu.c        |  5 ++---
>  3 files changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
> index 9404e488208a..3eccc4bc39c3 100644
> --- a/include/hw/virtio/virtio-gpu.h
> +++ b/include/hw/virtio/virtio-gpu.h
> @@ -141,6 +141,7 @@ struct virtio_gpu_ctrl_command {
>      struct virtio_gpu_ctrl_hdr cmd_hdr;
>      uint32_t error;
>      bool finished;
> +    bool suspended;
>      QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
>  };
>
> diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
> index 9bda572426b2..c37df91e3ed1 100644
> --- a/hw/display/virtio-gpu-virgl.c
> +++ b/hw/display/virtio-gpu-virgl.c
> @@ -440,8 +440,7 @@ virtio_gpu_virgl_resource_unref(VirtIOGPU *g,
>  }
>
>  static void virgl_cmd_resource_unref(VirtIOGPU *g,
> -                                     struct virtio_gpu_ctrl_command *cmd,
> -                                     bool *cmd_suspended)
> +                                     struct virtio_gpu_ctrl_command *cmd)
>  {
>      struct virtio_gpu_resource_unref unref;
>      struct virtio_gpu_virgl_resource *res;
> @@ -457,7 +456,7 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
>          return;
>      }
>
> -    virtio_gpu_virgl_resource_unref(g, res, cmd_suspended);
> +    virtio_gpu_virgl_resource_unref(g, res, &cmd->suspended);
>  }
>
>  void virtio_gpu_virgl_resource_destroy(VirtIOGPU *g,
> @@ -946,8 +945,7 @@ static void virgl_cmd_resource_map_blob(VirtIOGPU *g,
>  }
>
>  static void virgl_cmd_resource_unmap_blob(VirtIOGPU *g,
> -                                          struct virtio_gpu_ctrl_command 
> *cmd,
> -                                          bool *cmd_suspended)
> +                                          struct virtio_gpu_ctrl_command 
> *cmd)
>  {
>      struct virtio_gpu_resource_unmap_blob ublob;
>      struct virtio_gpu_virgl_resource *res;
> @@ -964,7 +962,7 @@ static void virgl_cmd_resource_unmap_blob(VirtIOGPU *g,
>          return;
>      }
>
> -    ret = virtio_gpu_virgl_unmap_resource_blob(g, res, cmd_suspended);
> +    ret = virtio_gpu_virgl_unmap_resource_blob(g, res, &cmd->suspended);
>      if (ret) {
>          cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
>          return;
> @@ -1036,7 +1034,6 @@ static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
>  void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
>                                        struct virtio_gpu_ctrl_command *cmd)
>  {
> -    bool cmd_suspended = false;
>      int ret;
>
>      VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr);
> @@ -1080,7 +1077,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
>          virgl_cmd_resource_flush(g, cmd);
>          break;
>      case VIRTIO_GPU_CMD_RESOURCE_UNREF:
> -        virgl_cmd_resource_unref(g, cmd, &cmd_suspended);
> +        virgl_cmd_resource_unref(g, cmd);
>          break;
>      case VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE:
>          /* TODO add security */
> @@ -1110,7 +1107,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
>          virgl_cmd_resource_map_blob(g, cmd);
>          break;
>      case VIRTIO_GPU_CMD_RESOURCE_UNMAP_BLOB:
> -        virgl_cmd_resource_unmap_blob(g, cmd, &cmd_suspended);
> +        virgl_cmd_resource_unmap_blob(g, cmd);
>          break;
>      case VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
>          virgl_cmd_set_scanout_blob(g, cmd);
> @@ -1121,7 +1118,7 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
>          break;
>      }
>
> -    if (cmd_suspended || cmd->finished) {
> +    if (cmd->suspended || cmd->finished) {
>          return;
>      }
>      if (cmd->error) {
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index d520f69e6453..dd6c09d1ddcf 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -1193,11 +1193,10 @@ void virtio_gpu_process_cmdq(VirtIOGPU *g)
>              break;
>          }
>
> -        /* process command */
> +        cmd->suspended = false;
>          vgc->process_cmd(g, cmd);
>
> -        /* command suspended */
> -        if (!cmd->finished && !(cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE)) 
> {
> +        if (cmd->suspended) {
>              trace_virtio_gpu_cmd_suspended(cmd->cmd_hdr.type);
>              break;
>          }
>
> --
> 2.55.0
>


Reply via email to