[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