From ae2bd4def95997ff7198b1bad21a73a267eea604 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Sat, 26 Sep 2026 02:46:41 -0400 Subject: kernel: add a channel-table dump param; tools: fix memprobe --max parsing --- kernel/gsp_sema_service.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/gsp_sema_service.h | 1 + kernel/main.c | 17 ++++++++++++ 3 files changed, 87 insertions(+) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index ffc8ae2..1f1222e 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3121,6 +3121,74 @@ int gsp_sema_service_probe(u64 gpu_va, u32 count) return 0; } +/* + * Diagnostic dump of the service's channel table: GPFIFO/USERD state, the + * pending-entry expectation and the two NvNotification slots the client polls + * (status + info32). Runs in the service thread (guest-DMA reads need a + * kthread context); the sysfs writer waits for completion. + */ +static struct completion chan_dump_done; +static bool chan_dump_pending; + +static void svc_handle_chan_dump(struct nv_vgpu_device *vgpu) +{ + struct svc_channel local[SVC_MAX_CHANNELS]; + unsigned long flags; + int i, n = 0; + + if (!chan_dump_pending) + return; + + spin_lock_irqsave(&svc.chan_lock, flags); + for (i = 0; i < SVC_MAX_CHANNELS; i++) + if (svc.chan[i].valid) + local[n++] = svc.chan[i]; + spin_unlock_irqrestore(&svc.chan_lock, flags); + + pr_info("sema-chan-dump: %d channel(s)\n", n); + for (i = 0; i < n; i++) { + struct svc_channel *ch = &local[i]; + u32 st0 = 0, st1 = 0, info0 = 0, info1 = 0; + + if (ch->notifier_pa) { + svc_read_ap(vgpu, ch->notifier_pa + 14, + ch->notifier_as, &st0, 2); + svc_read_ap(vgpu, ch->notifier_pa + 8, + ch->notifier_as, &info0, 4); + svc_read_ap(vgpu, ch->notifier_pa + 16 + 14, + ch->notifier_as, &st1, 2); + svc_read_ap(vgpu, ch->notifier_pa + 16 + 8, + ch->notifier_as, &info1, 4); + } + pr_info("sema-chan-dump: h=0x%x eng=%u gpfifo=0x%llx ent=%u userd=0x%llx as=%u ok=%d get=%u sub=%llu exp=%u notif=0x%llx as=%u slot0{info=0x%x st=0x%x} slot1{info=0x%x st=0x%x} notified=%llu\n", + ch->h_object, ch->engine_type, ch->gpfifo_va, + ch->gpfifo_entries, ch->userd_pa, ch->userd_as, + ch->userd_ok, ch->last_get, ch->submissions, + ch->expected_sem_payload, ch->notifier_pa, + ch->notifier_as, info0, st0, info1, st1, + ch->notified); + } + + chan_dump_pending = false; + complete(&chan_dump_done); +} + +int gsp_sema_service_dump_channels(void) +{ + if (!svc.task) + return -ENODEV; + + init_completion(&chan_dump_done); + chan_dump_pending = true; + + if (!wait_for_completion_timeout(&chan_dump_done, 3 * HZ)) { + chan_dump_pending = false; + return -ETIMEDOUT; + } + return 0; +} + + /* * Debug injection: teach the service one {GPU VA -> guest PA} translation. * Some client mappings (user VA == GPU VA, sysmem backed) are not @@ -3205,6 +3273,7 @@ static int svc_thread(void *arg) svc_handle_probe(vgpu); svc_handle_map_add(); + svc_handle_chan_dump(vgpu); if (!svc.direct_base || time_after(jiffies, svc.last_build + 10 * HZ)) diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h index 6b8dc6a..d5e41a6 100644 --- a/kernel/gsp_sema_service.h +++ b/kernel/gsp_sema_service.h @@ -57,6 +57,7 @@ void gsp_sema_service_vaspace_del(u32 h_vaspace); int gsp_sema_service_start(void); void gsp_sema_service_stop(void); int gsp_sema_service_probe(u64 gpu_va, u32 count); +int gsp_sema_service_dump_channels(void); int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len, u32 ap); void gsp_sema_service_doorbell(u32 token); diff --git a/kernel/main.c b/kernel/main.c index 63657f3..f23be27 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2247,6 +2247,23 @@ static const struct kernel_param_ops nv_vgpu_sema_probe_ops = { module_param_cb(sema_probe, &nv_vgpu_sema_probe_ops, NULL, 0200); MODULE_PARM_DESC(sema_probe, "Dump sema-service map + slot values for a GPU VA"); +/* + * Debug: dump the semaphore service's channel table (GPFIFO/USERD state and + * the two NvNotification slots each channel exposes): + * echo 1 > .../parameters/chan_dump + */ +static int nv_vgpu_chan_dump_set(const char *val, const struct kernel_param *kp) +{ + return gsp_sema_service_dump_channels(); +} + +static const struct kernel_param_ops nv_vgpu_chan_dump_ops = { + .set = nv_vgpu_chan_dump_set, +}; + +module_param_cb(chan_dump, &nv_vgpu_chan_dump_ops, NULL, 0200); +MODULE_PARM_DESC(chan_dump, "Dump the sema service channel table (any value)"); + /* * Debug: inject a verified {GPU VA -> guest PA} translation into the * semaphore service (used when the client's mapping cannot be discovered -- cgit v1.2.3