diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 05:17:23 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 05:17:23 -0400 |
| commit | 85113f53848b1d1ae577967fff540d6406346ff2 (patch) | |
| tree | f776b878bb1f3b4ec6a15f59ccbf7e32c47eb449 | |
| parent | a422055208b800313d44c9fa6a3df81e650999e2 (diff) | |
| download | open-iov-85113f53848b1d1ae577967fff540d6406346ff2.tar.gz open-iov-85113f53848b1d1ae577967fff540d6406346ff2.zip | |
sema-svc: sema_vidmem_dump param to inspect emulated vidmem (CE data-path audit)
| -rw-r--r-- | kernel/gsp_sema_service.c | 36 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.h | 1 | ||||
| -rw-r--r-- | kernel/main.c | 30 |
3 files changed, 67 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 6703403..56285bf 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -5052,6 +5052,42 @@ int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len, u32 ap) } /* + * Dump a range of the emulated vidmem (BAR1 shadow) into the kernel log. + * Debug aid for the CE data path: verifies whether a decoded fill/copy + * actually landed where the CE operand said it should. + */ +int gsp_sema_service_dump_vidmem(u64 addr, u64 len) +{ + struct nv_vgpu_device *vgpu = NULL; + struct nv_vgpu_device *d; + u8 *base; + + if (!len || len > 4096) + return -EINVAL; + + mutex_lock(&nv_vgpu_driver.lock); + list_for_each_entry(d, &nv_vgpu_driver.devices, list) { + if (atomic_read(&d->vfio_dev_open_count) > 0) { + vgpu = d; + break; + } + } + mutex_unlock(&nv_vgpu_driver.lock); + if (!vgpu) + return -ENODEV; + + base = vgpu->bars[1].vaddr; + if (!base || addr + len > vgpu->bars[1].size) + return -EINVAL; + + pr_info("sema-vidmem: dump addr=0x%llx len=%llu\n", + (unsigned long long)addr, (unsigned long long)len); + print_hex_dump(KERN_INFO, "sema-vidmem: ", DUMP_PREFIX_OFFSET, + 16, 1, base + addr, (size_t)len, false); + return 0; +} + +/* * Register a channel's GPU completion counter (guest PA of the u32 the GPU * would advance as pushes complete). Called from the sema_counter debug * parameter; plain state update, so it runs in the caller's context. diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h index 7af498e..7eb7382 100644 --- a/kernel/gsp_sema_service.h +++ b/kernel/gsp_sema_service.h @@ -60,6 +60,7 @@ int gsp_sema_service_probe(u64 gpu_va, u32 count); int gsp_sema_service_walk_probe(u64 gpu_va); int gsp_sema_service_dump_channels(void); int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len, u32 ap); +int gsp_sema_service_dump_vidmem(u64 addr, u64 len); int gsp_sema_service_counter_add(u32 h_object, u64 pa); void gsp_sema_service_doorbell(u32 token); diff --git a/kernel/main.c b/kernel/main.c index 454f3b9..52156dc 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2540,6 +2540,36 @@ module_param_cb(sema_counter, &nv_vgpu_sema_counter_ops, NULL, 0200); MODULE_PARM_DESC(sema_counter, "Register channel GPU completion counter (h_object,pa)"); /* + * Debug: dump a range of the emulated vidmem (BAR1 shadow) into the kernel + * log, to verify where a decoded CE copy actually landed: + * echo 0x227000,256 > .../parameters/sema_vidmem_dump + */ +static int nv_vgpu_sema_vidmem_dump_set(const char *val, + const struct kernel_param *kp) +{ + char buf[64]; + char *comma; + u64 addr = 0, len = 0; + + strscpy(buf, val, sizeof(buf)); + comma = strchr(buf, ','); + if (!comma) + return -EINVAL; + *comma = '\0'; + if (kstrtoull(buf, 0, &addr) || kstrtoull(comma + 1, 0, &len)) + return -EINVAL; + + return gsp_sema_service_dump_vidmem(addr, len); +} + +static const struct kernel_param_ops nv_vgpu_sema_vidmem_dump_ops = { + .set = nv_vgpu_sema_vidmem_dump_set, +}; + +module_param_cb(sema_vidmem_dump, &nv_vgpu_sema_vidmem_dump_ops, NULL, 0200); +MODULE_PARM_DESC(sema_vidmem_dump, "Dump emulated vidmem (addr,len) to the kernel log"); + +/* * Debug: find page-table entries pointing at a physical address, in guest RAM * and emulated vidmem: * echo 0x12442b000 > .../parameters/scan_pt |
