[PATCH] drm/amd/display: fix EPERM reading amdgpu_dm_dmub_fw_state
Lars Nieradzik <[email protected]> Sat, 8 Aug 2026 19:09:26 +0200
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
dmub_fw_state_show() returns seq_write()'s value directly. On overflow
seq_write() returns a literal -1 rather than a meaningful error code, and
seq_read_iter() treats any negative return from ->show() as fatal, so it
breaks out before reaching the grow-and-retry further down the same loop:
err = m->op->show(m, p);
if (err < 0) // hard error
break;
if (unlikely(err)) // ->show() says "skip it"
m->count = 0;
if (unlikely(!m->count)) { // empty record
p = m->op->next(m, p, &m->index);
continue;
}
if (!seq_has_overflowed(m)) // got it
goto Fill;
// need a bigger buffer
m->op->stop(m, p);
kvfree(m->buf);
m->count = 0;
m->buf = seq_buf_alloc(m->size <<= 1);
The DMUB_WINDOW_6_FW_STATE region is much larger than the initial one-page
seq_file buffer, so seq_write() always overflows on the first pass. The -1
breaks the loop before seq_has_overflowed() is ever tested, and since -1 is
-EPERM userspace sees:
# cat /sys/kernel/debug/dri/0/amdgpu_dm_dmub_fw_state
cat: ...: Operation not permitted
That reads as a permissions problem even though the file is 0644 and
the read is performed as root, so the file has been unusable since it
was added.
The adjacent dmub_tracebuffer_show() shows the correct pattern: it
emits via seq_printf() and returns 0, letting seq_has_overflowed()
drive the retry. On a Ryzen 9 8945HS (Phoenix, DCN 3.1.4) that sibling
returns 224332 bytes from the same debugfs directory, so the growth
loop handles output of this magnitude without difficulty.
Return 0 and let the seq_file core detect the overflow.
Fixes: 2364076772b1 ("drm/amd/display: Add DMUB firmware state debugfs")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Lars Nieradzik <[email protected]>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index c4b2fc690fd7..ea4cae7d140f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -989,7 +989,9 @@ static int dmub_fw_state_show(struct seq_file *m, void *data)
state_size = fb_info->fb[DMUB_WINDOW_6_FW_STATE].size;
- return seq_write(m, state_base, state_size);
+ seq_write(m, state_base, state_size);
+
+ return 0;
}
/* replay_capability_show() - show eDP panel replay capability
base-commit: c4f76bf5e107bcda6e496f1c4060c55af091fa79
--
2.55.0