[PATCH 1/4] drm/amdgpu/sdma4: replace BUG_ON with WARN_ON_ONCE in fence emission

jbmoore
2026-04-26T21:53:25Z

From: "John B. Moore" <jbmoore61@gmail.com>

sdma_v4_0_ring_emit_fence() contains two BUG_ON(addr & 0x3) assertions
that verify fence writeback addresses are dword-aligned. These
assertions can be reached via crafted DRM_IOCTL_AMDGPU_CS submissions
from unprivileged userspace, causing a fatal kernel panic in a
scheduler worker thread.

Replace both BUG_ON() calls with WARN_ON_ONCE() and force-align the
address by clearing the reserved bits. This logs the condition once
per boot and allows the hardware to proceed without crashing the
kernel.

On all hardware that amdgpu supports, bits [1:0] of ring buffer
addresses are reserved (they historically encoded byte-swap mode on
legacy pre-amdgpu hardware). A misaligned fence address indicates a
driver bug, but crashing the kernel is never the correct response.

Found by a custom amdgpu DRM ioctl fuzzer.

Fixes: 2130f89ced2c ("drm/amdgpu: add SDMA v4.0 implementation (v2)")
Signed-off-by: John B. Moore <jbmoore61@gmail.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
index 8a2a4e618..dcb7e4219 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -889,7 +889,8 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
/* write the fence */
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
/* zero in first two bits */
- BUG_ON(addr & 0x3);
+ if (WARN_ON_ONCE(addr & 0x3))
+ addr &= ~0x3ULL;
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, lower_32_bits(seq));
@@ -899,7 +900,8 @@ static void sdma_v4_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se
addr += 4;
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_FENCE));
/* zero in first two bits */
- BUG_ON(addr & 0x3);
+ if (WARN_ON_ONCE(addr & 0x3))
+ addr &= ~0x3ULL;
amdgpu_ring_write(ring, lower_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(addr));
amdgpu_ring_write(ring, upper_32_bits(seq));
--
2.43.0