[PATCH 1/9] drm/amdgpu: validate userq input args

Alex Deucher alexdeucher at gmail.com
Fri May 30 21:31:39 UTC 2025


On Fri, May 30, 2025 at 4:05 AM Prike Liang <Prike.Liang at amd.com> wrote:
>
> This will help on validating the userq input args, and
> rejecting for the invalidate userq request at the IOCTLs
> first place.
>
> Signed-off-by: Prike Liang <Prike.Liang at amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c  | 80 +++++++++++++++-------
>  drivers/gpu/drm/amd/amdgpu/mes_userqueue.c |  7 --
>  2 files changed, 55 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> index 295e7186e156..f67969312c39 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
> @@ -359,27 +359,10 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
>                 (args->in.flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK) >>
>                 AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_SHIFT;
>
> -       /* Usermode queues are only supported for GFX IP as of now */
> -       if (args->in.ip_type != AMDGPU_HW_IP_GFX &&
> -           args->in.ip_type != AMDGPU_HW_IP_DMA &&
> -           args->in.ip_type != AMDGPU_HW_IP_COMPUTE) {
> -               drm_file_err(uq_mgr->file, "Usermode queue doesn't support IP type %u\n",
> -                            args->in.ip_type);
> -               return -EINVAL;
> -       }
> -
>         r = amdgpu_userq_priority_permit(filp, priority);
>         if (r)
>                 return r;
>
> -       if ((args->in.flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE) &&
> -           (args->in.ip_type != AMDGPU_HW_IP_GFX) &&
> -           (args->in.ip_type != AMDGPU_HW_IP_COMPUTE) &&
> -           !amdgpu_is_tmz(adev)) {
> -               drm_file_err(uq_mgr->file, "Secure only supported on GFX/Compute queues\n");
> -               return -EINVAL;
> -       }
> -
>         r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
>         if (r < 0) {
>                 drm_file_err(uq_mgr->file, "pm_runtime_get_sync() failed for userqueue create\n");
> @@ -485,22 +468,44 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
>         return r;
>  }
>
> -int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> -                      struct drm_file *filp)
> +static int amdgpu_userq_input_args_validate(struct drm_device *dev,
> +                                       union drm_amdgpu_userq *args,
> +                                       struct drm_file *filp)
>  {
> -       union drm_amdgpu_userq *args = data;
> -       int r;
> +       struct amdgpu_device *adev = drm_to_adev(dev);
>
>         switch (args->in.op) {
>         case AMDGPU_USERQ_OP_CREATE:
>                 if (args->in.flags & ~(AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK |
>                                        AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE))
>                         return -EINVAL;
> -               r = amdgpu_userq_create(filp, args);
> -               if (r)
> -                       drm_file_err(filp, "Failed to create usermode queue\n");
> -               break;
> +               /* Usermode queues are only supported for GFX IP as of now */
> +               if (args->in.ip_type != AMDGPU_HW_IP_GFX &&
> +                   args->in.ip_type != AMDGPU_HW_IP_DMA &&
> +                   args->in.ip_type != AMDGPU_HW_IP_COMPUTE) {
> +                       drm_file_err(filp, "Usermode queue doesn't support IP type %u\n",
> +                                    args->in.ip_type);
> +                       return -EINVAL;
> +               }
> +
> +               if ((args->in.flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE) &&
> +                   (args->in.ip_type != AMDGPU_HW_IP_GFX) &&
> +                   (args->in.ip_type != AMDGPU_HW_IP_COMPUTE) &&
> +                   !amdgpu_is_tmz(adev)) {
> +                       drm_file_err(filp, "Secure only supported on GFX/Compute queues\n");
> +                       return -EINVAL;
> +               }
>
> +               if (args->in.queue_va == AMDGPU_BO_INVALID_OFFSET ||
> +                               args->in.queue_size == 0) {
> +                       drm_file_err(filp, "invalidate userq queue va or size\n");
> +                       return -EINVAL;
> +               }
> +               if (!args->in.wptr_va || !args->in.rptr_va) {
> +                       drm_file_err(filp, "invalidate userq queue rptr or wptr\n");
> +                       return -EINVAL;
> +               }
> +               break;
>         case AMDGPU_USERQ_OP_FREE:
>                 if (args->in.ip_type ||
>                     args->in.doorbell_handle ||
> @@ -514,6 +519,31 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
>                     args->in.mqd ||
>                     args->in.mqd_size)
>                         return -EINVAL;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +int amdgpu_userq_ioctl(struct drm_device *dev, void *data,
> +                      struct drm_file *filp)
> +{
> +       union drm_amdgpu_userq *args = data;
> +       int r;
> +
> +       if (amdgpu_userq_input_args_validate(dev, args, filp) < 0)
> +               return -EINVAL;
> +
> +       switch (args->in.op) {
> +       case AMDGPU_USERQ_OP_CREATE:
> +               r = amdgpu_userq_create(filp, args);
> +               if (r)
> +                       drm_file_err(filp, "Failed to create usermode queue\n");
> +               break;
> +
> +       case AMDGPU_USERQ_OP_FREE:
>                 r = amdgpu_userq_destroy(filp, args->in.queue_id);
>                 if (r)
>                         drm_file_err(filp, "Failed to destroy usermode queue\n");
> diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> index d6f50b13e2ba..1457fb49a794 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
> @@ -215,13 +215,6 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr,
>                 return -ENOMEM;
>         }
>
> -       if (!mqd_user->wptr_va || !mqd_user->rptr_va ||
> -           !mqd_user->queue_va || mqd_user->queue_size == 0) {
> -               DRM_ERROR("Invalid MQD parameters for userqueue\n");
> -               r = -EINVAL;
> -               goto free_props;
> -       }

I would keep this check here as this is MES specific at this point.

Alex

> -
>         r = amdgpu_userq_create_object(uq_mgr, &queue->mqd, mqd_hw_default->mqd_size);
>         if (r) {
>                 DRM_ERROR("Failed to create MQD object for userqueue\n");
> --
> 2.34.1
>


More information about the amd-gfx mailing list