On Mon, Aug 03, 2026 at 05:07:10PM +0300, Shahar Shitrit wrote:
> From: Daniel Jurgens <[email protected]>
> 
> This will allow device drivers to issue administration commands.
> 
> Signed-off-by: Daniel Jurgens <[email protected]>
> Reviewed-by: Parav Pandit <[email protected]>
> Reviewed-by: Xuan Zhuo <[email protected]>
> Signed-off-by: Shahar Shitrit <[email protected]>
> ---
>  drivers/virtio/virtio_pci_modern.c | 2 ++
>  include/linux/virtio_config.h      | 6 ++++++
>  2 files changed, 8 insertions(+)
> 
> diff --git a/drivers/virtio/virtio_pci_modern.c 
> b/drivers/virtio/virtio_pci_modern.c
> index ef4a64eb9982..a18683761aa5 100644
> --- a/drivers/virtio/virtio_pci_modern.c
> +++ b/drivers/virtio/virtio_pci_modern.c
> @@ -1238,6 +1238,7 @@ static const struct virtio_config_ops 
> virtio_pci_config_nodev_ops = {
>       .get_shm_region  = vp_get_shm_region,
>       .disable_vq_and_reset = vp_modern_disable_vq_and_reset,
>       .enable_vq_after_reset = vp_modern_enable_vq_after_reset,
> +     .admin_cmd_exec = vp_modern_admin_cmd_exec,
>  };
>  
>  static const struct virtio_config_ops virtio_pci_config_ops = {
> @@ -1258,6 +1259,7 @@ static const struct virtio_config_ops 
> virtio_pci_config_ops = {
>       .get_shm_region  = vp_get_shm_region,
>       .disable_vq_and_reset = vp_modern_disable_vq_and_reset,
>       .enable_vq_after_reset = vp_modern_enable_vq_after_reset,
> +     .admin_cmd_exec = vp_modern_admin_cmd_exec,
>  };
>  
>  /* the PCI probing function */


So the issue here is that vp_modern_admin_cmd_exec has been
broken for a while:


        spin_lock_irqsave(&admin_vq->lock, flags);
        ret = virtqueue_add_sgs(vq, sgs, out_num, in_num, cmd, GFP_KERNEL);



which is pre-existing but now that this is going to be triggered by userspace,
we need to fix this.

I guess admin vq lock must be a mutex and complete through a wq?

> diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
> index 69f84ea85d71..e36a32e0a20c 100644
> --- a/include/linux/virtio_config.h
> +++ b/include/linux/virtio_config.h
> @@ -108,6 +108,10 @@ struct virtqueue_info {
>   *   Returns 0 on success or error status
>   *   If disable_vq_and_reset is set, then enable_vq_after_reset must also be
>   *   set.
> + * @admin_cmd_exec: Execute an admin VQ command (optional).
> + *   vdev: the virtio_device
> + *   cmd: the command to execute
> + *   Returns 0 on success or error status
>   */
>  struct virtio_config_ops {
>       void (*get)(struct virtio_device *vdev, unsigned offset,
> @@ -137,6 +141,8 @@ struct virtio_config_ops {
>                              struct virtio_shm_region *region, u8 id);
>       int (*disable_vq_and_reset)(struct virtqueue *vq);
>       int (*enable_vq_after_reset)(struct virtqueue *vq);
> +     int (*admin_cmd_exec)(struct virtio_device *vdev,
> +                           struct virtio_admin_cmd *cmd);
>  };
>  
>  /**
> -- 
> 2.49.0


Reply via email to