]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amdgpu: validate userq input args
authorPrike Liang <Prike.Liang@amd.com>
Wed, 14 May 2025 04:43:57 +0000 (12:43 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 9 Sep 2025 20:17:57 +0000 (16:17 -0400)
This will help on validating the userq input args, and
rejecting for the invalid userq request at the IOCTLs
first place.

Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
drivers/gpu/drm/amd/amdgpu/mes_userqueue.c

index 467e8fa6cb8b01764f3a160b9871c9fdeb7402eb..f8648e169f8b2665467726555b0465ccc1d70fce 100644 (file)
@@ -404,27 +404,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");
@@ -543,22 +526,45 @@ unlock:
        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_va == 0 ||
+                   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 ||
@@ -571,6 +577,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");
index aee26f80bd5307373c4fc7ba3734606e2d45a803..66467f41294c19dcb5fe2522cf2384bfb140e329 100644 (file)
@@ -263,13 +263,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;
-       }
-
        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");