]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amdgpu: reject oversized IBs with per-ring packet limits
authorCandice Li <candice.li@amd.com>
Thu, 30 Jul 2026 03:28:10 +0000 (11:28 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 6 Aug 2026 18:32:33 +0000 (14:32 -0400)
On GFX rings, amdgpu_cs_p2_ib() passed user-supplied ib_bytes through
to ib->length_dw without a limit, while ring_emit_ib() encodes length
into packet fields. Oversized values can corrupt adjacent control bits
and destabilize command submission.

Add a per-ring IB packet size limit helper and reject command
submissions exceeding the corresponding dword limit before IB
allocation. Use the documented 20-bit limit for GFX/compute/SDMA/VPE,
and apply the MM fallback limit for other ring types.

Signed-off-by: Candice Li <candice.li@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7f48fa2cf62e3fa6c9c3870aa74988f773247e52)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c

index 5445f75741b53d12bec625401a5bce37d717e330..f8bf0f6b5097b03bd1285b67a5c7831764b9199b 100644 (file)
 #include "amdgpu_ras.h"
 #include "amdgpu_hmm.h"
 
+/*
+ * Maximum IB length (dwords) for rings whose emit_ib packet format
+ * documents a 20-bit size field.
+ */
+#define AMDGPU_GFX_SDMA_IB_PACKET_SIZE_MAX_DW  0xFFFFF
+#define AMDGPU_MM_IB_PACKET_SIZE_MAX_DW        0x7FFFF0
+
+static u32 amdgpu_cs_ib_packet_size_max_dw(enum amdgpu_ring_type type)
+{
+       switch (type) {
+       case AMDGPU_RING_TYPE_GFX:
+       case AMDGPU_RING_TYPE_COMPUTE:
+       case AMDGPU_RING_TYPE_SDMA:
+       case AMDGPU_RING_TYPE_VPE:
+               return AMDGPU_GFX_SDMA_IB_PACKET_SIZE_MAX_DW;
+       default:
+               return AMDGPU_MM_IB_PACKET_SIZE_MAX_DW;
+       }
+}
+
 static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
                                 struct amdgpu_device *adev,
                                 struct drm_file *filp,
@@ -345,7 +365,6 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
 
        job = p->jobs[r];
        ring = amdgpu_job_ring(job);
-       ib = &job->ibs[job->num_ibs++];
 
        /* submissions to kernel queues are disabled */
        if (ring->no_user_submission)
@@ -374,6 +393,12 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
                        return -EINVAL;
        }
 
+       if (chunk_ib->ib_bytes / 4 >
+           amdgpu_cs_ib_packet_size_max_dw(ring->funcs->type))
+               return -EINVAL;
+
+       ib = &job->ibs[job->num_ibs++];
+
        if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
                job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT;