drm/amdgpu: reject oversized IBs with per-ring packet limits

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>
This commit is contained in:
Candice Li
2026-07-30 11:28:10 +08:00
committed by Alex Deucher
parent a8e151fe62
commit 7f48fa2cf6

View File

@@ -42,6 +42,26 @@
#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,
@@ -340,7 +360,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 +388,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;