[PATCH] drm/amdgpu: reject oversized IBs on rings with 20-bit size fields

Candice Li <[email protected]> Thu, 30 Jul 2026 17:40:11 +0800
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
PM4 INDIRECT_BUFFER control words encode IB size in 20 bits.  On GFX
rings amdgpu_cs_p2_ib() passed user-supplied ib_bytes through to
ib->length_dw without a limit, and ring_emit_ib() ORed length_dw
directly into the control dword.

Reject IB submissions whose length exceeds the hardware maximum in
amdgpu_cs_p2_ib(), but only for rings whose emit_ib packet format
documents a 20-bit size field (GFX, compute and SDMA).

Signed-off-by: Candice Li <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index afc1c631d55aa6..0d06b6d166c576 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -42,6 +42,25 @@
 #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, e.g. GFX PM4 INDIRECT_BUFFER ([19:0])
+ * and SDMA indirect packets.
+ */
+#define AMDGPU_IB_PACKET_SIZE_MAX_DW	0xFFFFF
+
+static bool amdgpu_cs_ib_has_packet_length_limit(enum amdgpu_ring_type type)
+{
+	switch (type) {
+	case AMDGPU_RING_TYPE_GFX:
+	case AMDGPU_RING_TYPE_COMPUTE:
+	case AMDGPU_RING_TYPE_SDMA:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p,
 				 struct amdgpu_device *adev,
 				 struct drm_file *filp,
@@ -340,7 +359,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)
@@ -369,6 +387,12 @@ static int amdgpu_cs_p2_ib(struct amdgpu_cs_parser *p,
 			return -EINVAL;
 	}
 
+	if (amdgpu_cs_ib_has_packet_length_limit(ring->funcs->type) &&
+	    chunk_ib->ib_bytes / 4 > AMDGPU_IB_PACKET_SIZE_MAX_DW)
+		return -EINVAL;
+
+	ib = &job->ibs[job->num_ibs++];
+
 	if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
 		job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT;
 
-- 
2.25.1