On Mon, Aug 31, 2026 at 9:01 AM Mario Limonciello <[email protected]> wrote: > > Reading /sys/kernel/debug/kfd/mqds while a process holds an active KFD > queue triggers a NULL pointer dereference because the for loop that > calls mqd_mgr->debugfs_show_mqd() is incorrectly placed outside the > if (pqn->q) block that initializes mqd_mgr. > > The queue list can contain entries where pqn->q is NULL (kernel queues > where only pqn->kq is valid). In the original code: > > if (pqn->q) { > ... > mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type]; > size = mqd_mgr->mqd_stride(...); > } > > for (xcc = 0; xcc < num_xccs; xcc++) { // WRONG: outside if block > mqd = q->mqd + size * xcc; > r = mqd_mgr->debugfs_show_mqd(m, mqd); > } > > When iterating over a queue node where pqn->q is NULL: > 1. The if (pqn->q) block is skipped > 2. mqd_mgr remains uninitialized (NULL from declaration) > 3. The for loop executes anyway > 4. mqd_mgr->debugfs_show_mqd(m, mqd) dereferences NULL > > The crash manifests as: > > BUG: kernel NULL pointer dereference, address: 0000000000000000 > #PF: supervisor instruction fetch in kernel mode > RIP: 0010:0x0 > Call Trace: > pqm_debugfs_mqds+0x10c/0x1d0 [amdgpu] > kfd_debugfs_mqds_by_process+0x9b/0x110 [amdgpu] > seq_read_iter+0x132/0x4b0 > ... > > Fix by moving the for loop inside the if (pqn->q) block, so mqd_mgr > and related variables are only used when properly initialized. > > Cc: [email protected] > Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5689 > Signed-off-by: Mario Limonciello <[email protected]>
Reviewed-by: Alex Deucher <[email protected]> > --- > .../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c > b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c > index 9e607098c3a09..fb2d8ad9c2c5e 100644 > --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c > +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c > @@ -1170,13 +1170,13 @@ int pqm_debugfs_mqds(struct seq_file *m, void *data) > mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type]; > size = mqd_mgr->mqd_stride(mqd_mgr, > &q->properties); > - } > > - for (xcc = 0; xcc < num_xccs; xcc++) { > - mqd = q->mqd + size * xcc; > - r = mqd_mgr->debugfs_show_mqd(m, mqd); > - if (r != 0) > - break; > + for (xcc = 0; xcc < num_xccs; xcc++) { > + mqd = q->mqd + size * xcc; > + r = mqd_mgr->debugfs_show_mqd(m, mqd); > + if (r != 0) > + break; > + } > } > } > > -- > 2.43.0 >
