summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c36
-rw-r--r--kernel/gsp_sema_service.h1
-rw-r--r--kernel/main.c30
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