drm/amdkfd: Reject zero-sized AQL queue allocations after size halving
authorSunday Clement <Sunday.Clement@amd.com>
Thu, 6 Aug 2026 14:59:34 +0000 (10:59 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 25 Aug 2026 22:18:44 +0000 (18:18 -0400)
KFD_IOC_ALLOC_MEMORY_OF_GPU with flag
KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM and size=1 triggers the AQL
wraparound workaround (size >>= 1), reducing size to 0. The resulting
zero passes through PAGE_ALIGN(0) = 0 without validation, bypassing the
per-process VRAM quota check in reserve_mem_limit()
(vram_used + 0 > vram_available is always false).

The fix adds post-halving zero-size validation in the primary
allocation path (amdgpu_amdkfd_gpuvm.c). The check happens after size
halving but before reserve_mem_limit(), and uses err_alignment_size
error path to properly clean up the allocated kgd_mem structure and
mutex.

Cc: stable@vger.kernel.org
Signed-off-by: Sunday Clement <Sunday.Clement@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_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c

index 34481ee..d668816 100644 (file)
@@ -1795,6 +1795,12 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
                size >>= 1;
        aligned_size = PAGE_ALIGN(size);
 
+       /* reject AQL queue with size < 2 */
+       if (!aligned_size) {
+               ret = -EINVAL;
+               goto err_alignment_size;
+       }
+
        (*mem)->alloc_flags = flags;
 
        amdgpu_sync_create(&(*mem)->sync);
@@ -1886,6 +1892,7 @@ err_bo_create:
        amdgpu_amdkfd_unreserve_mem_limit(adev, aligned_size, flags, xcp_id);
 err_reserve_limit:
        amdgpu_sync_free(&(*mem)->sync);
+err_alignment_size:
        mutex_destroy(&(*mem)->lock);
        if (gobj)
                drm_gem_object_put(gobj);
index 6fd1848..7fcfc15 100644 (file)
@@ -1200,7 +1200,8 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
 
                if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM)
                        size >>= 1;
-               atomic64_add(PAGE_ALIGN(size), &pdd->vram_usage);
+               size = PAGE_ALIGN(size);
+               atomic64_add(size, &pdd->vram_usage);
        }
 
        mutex_unlock(&p->mutex);