mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
drm/amdgpu/gfx: fix cleaner shader IB buffer overflow
The cleaner shader sysfs path allocates a 16-dword (64 byte) IB but
incorrectly fills (align_mask + 1) dwords. On GFX rings align_mask is
0xff, so the loop wrote 256 dwords into a 64-byte buffer, causing a
kernel page fault.
The IB only needs to be a minimal NOP shell to schedule the job; the
cleaner shader itself is emitted on the ring via emit_cleaner_shader().
Fill 16 dwords to match the allocation.
v2: Use ib_size_dw variable (Lijo)
Fixes: d361ad5d2f ("drm/amdgpu: Add sysfs interface for running cleaner shader")
Suggested-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Asad Kamal <asad.kamal@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit bf21af331ebf72d0935fd70c73192414a422c03a)
CC: stable@vger.kernel.org
This commit is contained in:
parent
3d3372add0
commit
3e864bf2a3
|
|
@ -1664,12 +1664,13 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring)
|
|||
struct amdgpu_device *adev = ring->adev;
|
||||
struct drm_gpu_scheduler *sched = &ring->sched;
|
||||
struct drm_sched_entity entity;
|
||||
unsigned int ib_size_dw = 16;
|
||||
static atomic_t counter;
|
||||
struct dma_fence *f;
|
||||
struct amdgpu_job *job;
|
||||
struct amdgpu_ib *ib;
|
||||
void *owner;
|
||||
int i, r;
|
||||
int r;
|
||||
|
||||
/* Initialize the scheduler entity */
|
||||
r = drm_sched_entity_init(&entity, DRM_SCHED_PRIORITY_NORMAL,
|
||||
|
|
@ -1687,7 +1688,7 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring)
|
|||
owner = (void *)(unsigned long)atomic_inc_return(&counter);
|
||||
|
||||
r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner,
|
||||
64, 0, &job,
|
||||
ib_size_dw * sizeof(uint32_t), 0, &job,
|
||||
AMDGPU_KERNEL_JOB_ID_CLEANER_SHADER);
|
||||
if (r)
|
||||
goto err;
|
||||
|
|
@ -1697,9 +1698,8 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring)
|
|||
job->run_cleaner_shader = true;
|
||||
|
||||
ib = &job->ibs[0];
|
||||
for (i = 0; i <= ring->funcs->align_mask; ++i)
|
||||
ib->ptr[i] = ring->funcs->nop;
|
||||
ib->length_dw = ring->funcs->align_mask + 1;
|
||||
memset32(ib->ptr, ring->funcs->nop, ib_size_dw);
|
||||
ib->length_dw = ib_size_dw;
|
||||
|
||||
f = amdgpu_job_submit(job);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user