drm/amdkfd: Validate user queue update
authorPhilip Yang <Philip.Yang@amd.com>
Thu, 20 Jun 2024 17:00:48 +0000 (13:00 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 24 Jul 2024 18:43:49 +0000 (14:43 -0400)
Ensure update queue new ring buffer is mapped on GPU with correct size.

Decrease queue old ring_bo queue_refcount and increase new ring_bo
queue_refcount.

Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c

index 4947f28b3afbb15751cea6f40ae143a142aed69e..9995dbb433599a3b4c9f0d66e4c0e6c34048bc76 100644 (file)
@@ -549,11 +549,41 @@ int pqm_update_queue_properties(struct process_queue_manager *pqm,
        struct process_queue_node *pqn;
 
        pqn = get_queue_by_qid(pqm, qid);
-       if (!pqn) {
+       if (!pqn || !pqn->q) {
                pr_debug("No queue %d exists for update operation\n", qid);
                return -EFAULT;
        }
 
+       /*
+        * Update with NULL ring address is used to disable the queue
+        */
+       if (p->queue_address && p->queue_size) {
+               struct kfd_process_device *pdd;
+               struct amdgpu_vm *vm;
+               struct queue *q = pqn->q;
+               int err;
+
+               pdd = kfd_get_process_device_data(q->device, q->process);
+               if (!pdd)
+                       return -ENODEV;
+               vm = drm_priv_to_vm(pdd->drm_priv);
+               err = amdgpu_bo_reserve(vm->root.bo, false);
+               if (err)
+                       return err;
+
+               if (kfd_queue_buffer_get(vm, (void *)p->queue_address, &p->ring_bo,
+                                        p->queue_size)) {
+                       pr_debug("ring buf 0x%llx size 0x%llx not mapped on GPU\n",
+                                p->queue_address, p->queue_size);
+                       return -EFAULT;
+               }
+
+               kfd_queue_buffer_put(vm, &pqn->q->properties.ring_bo);
+               amdgpu_bo_unreserve(vm->root.bo);
+
+               pqn->q->properties.ring_bo = p->ring_bo;
+       }
+
        pqn->q->properties.queue_address = p->queue_address;
        pqn->q->properties.queue_size = p->queue_size;
        pqn->q->properties.queue_percent = p->queue_percent;