[PATCH AUTOSEL 6.19-6.12] drm/amdgpu: fix NULL pointer issue buffer funcs

Sasha Levin
2026-02-14T01:04:00Z

From: Likun Gao <Likun.Gao@amd.com>

[ Upstream commit 9877a865d62c9c3e0f4cc369dc9ca9f7f24f5ee9 ]

If SDMA block not enabled, buffer_funcs will not initialize,
fix the null pointer issue if buffer_funcs not initialized.

Signed-off-by: Likun Gao <Likun.Gao@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

Good. When called with `enable=false`,
`amdgpu_ttm_set_buffer_funcs_status` doesn't dereference
`buffer_funcs_ring` (the ring access is only in the `enable=true` path
at line 2166). The disable calls (lines 3991, 5064, 5330) are thus safe.
But the `enable=true` calls with the `buffer_funcs_ring->sched.ready`
guard check are the problematic ones.

## Detailed Analysis

### 1. COMMIT MESSAGE ANALYSIS

The subject explicitly says **"fix NULL pointer issue buffer funcs"** —
a clear bug fix. The description explains: *"If SDMA block not enabled,
buffer_funcs will not initialize, fix the null pointer issue if
buffer_funcs not initialized."* The author (Likun Gao, AMD engineer) and
reviewer (Hawking Zhang, AMD engineer) clearly identified a NULL pointer
dereference.

### 2. CODE CHANGE ANALYSIS

The change is minimal — a single NULL check addition:

```3312:3313:drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
if (adev->mman.buffer_funcs_ring->sched.ready)
amdgpu_ttm_set_buffer_funcs_status(adev, true);
```

Changed to:
```c
if (adev->mman.buffer_funcs_ring &&
adev->mman.buffer_funcs_ring->sched.ready)
amdgpu_ttm_set_buffer_funcs_status(adev, true);
```

**Root cause**: `buffer_funcs_ring` is explicitly initialized to NULL:

```4544:4545:drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
adev->mman.buffer_funcs = NULL;
adev->mman.buffer_funcs_ring = NULL;
```

It only gets set to a non-NULL value when SDMA `set_buffer_funcs()`
callbacks run during SDMA `early_init`. This happens in every SDMA
version: `sdma_v4_0`, `sdma_v5_0`, `sdma_v5_2`, `sdma_v6_0`,
`sdma_v7_0`, etc. If SDMA is disabled (via `amdgpu_ip_block_mask` module
parameter, harvesting, or early_init failure returning `-ENOENT`),
`buffer_funcs_ring` stays NULL.

The dereference of `adev->mman.buffer_funcs_ring->sched.ready` when
`buffer_funcs_ring` is NULL triggers a **kernel NULL pointer
dereference** (oops/crash).

### 3. ORIGIN OF THE BUG

The vulnerable pattern was introduced by commit `b70438004a14f`
("drm/amdgpu: move buffer funcs setting up a level") which landed in
**v6.7-rc1**. That commit moved the `buffer_funcs_ring->sched.ready`
checks from SDMA-specific code into `amdgpu_device.c` at four locations
(init, resume, reset, suspend-unwind), but didn't add NULL guards for
configurations where SDMA is absent.

### 4. SCOPE AND RISK

- **Lines changed**: 2 (adding `&&` with NULL check)
- **Files changed**: 1
- **Risk**: Extremely low. The NULL check guard only prevents
dereferencing a NULL pointer. When `buffer_funcs_ring` is non-NULL,
behavior is identical. When it IS NULL, it prevents a crash and
correctly skips `amdgpu_ttm_set_buffer_funcs_status(adev, true)` —
which is the right thing to do since there's no SDMA ring to use.
- **Regression potential**: Essentially zero.

### 5. USER IMPACT

- **Who is affected**: Users with AMD GPUs where SDMA is not enabled —
either by hardware design (harvested), by configuration (module
parameter), or by init failure.
- **Severity**: **Kernel crash** (NULL pointer dereference/oops) during
device initialization.
- **Frequency**: Every boot attempt on affected hardware.

### 6. COMPLETENESS NOTE

There are **three other** unprotected dereferences of
`buffer_funcs_ring->sched.ready` in the same file (lines 4206, 5344,
6076 — in resume, unwind, and reset paths). This commit only fixes the
init path. However:
- The init path is hit first and is the primary crash point
- If SDMA is absent at init, the device likely won't reach resume/reset
in normal operation
- Each fix is independently valuable

### 7. STABLE CRITERIA CHECK

- Obviously correct: Yes — simple NULL guard before dereference
- Fixes a real bug: Yes — NULL pointer dereference = kernel crash
- Important issue: Yes — prevents crash during device initialization
- Small and contained: Yes — 2-line change in one file
- No new features/APIs: Correct
- Reviewed by subsystem experts: Yes (Hawking Zhang, Alex Deucher at
AMD)
- Affected versions: v6.7+ (when b70438004a14f landed)

The fix is small, surgical, obviously correct, and prevents a kernel
crash on AMD GPU initialization. It meets all stable kernel criteria
with effectively zero regression risk.

**YES**

drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index d2c3885de711f..ba6fb23b840a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3309,7 +3309,8 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)
if (r)
goto init_failed;

- if (adev->mman.buffer_funcs_ring->sched.ready)
+ if (adev->mman.buffer_funcs_ring &&
+ adev->mman.buffer_funcs_ring->sched.ready)
amdgpu_ttm_set_buffer_funcs_status(adev, true);

/* Don't init kfd if whole hive need to be reset during init */
--
2.51.0