summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 05:33:09 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-30 05:33:09 -0400
commitcb6ca16ace1829dbe1cd25ab0af2bd138bda3162 (patch)
treea5e327bc25e5eb7c027b43372d8a8e2257f014a6
parentddd859e0c781262e477a00f08c00f585f3283db9 (diff)
downloadopen-iov-cb6ca16ace1829dbe1cd25ab0af2bd138bda3162.tar.gz
open-iov-cb6ca16ace1829dbe1cd25ab0af2bd138bda3162.zip
sema-svc: sema_vidmem_find pattern search (CE data-path ground truth)
-rw-r--r--kernel/gsp_sema_service.c49
-rw-r--r--kernel/gsp_sema_service.h1
-rw-r--r--kernel/main.c31
3 files changed, 81 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 4d3f6ef..8a60b6e 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -5127,6 +5127,55 @@ int gsp_sema_service_dump_vidmem(u64 addr, u64 len)
}
/*
+ * Search the whole emulated vidmem for an 8-byte pattern and log where it
+ * lands. The CE data-path ground truth: after a copy that should have
+ * written `pattern`, either it is somewhere or it never arrived.
+ */
+int gsp_sema_service_find_vidmem(u64 pattern, u64 max_hits)
+{
+ struct nv_vgpu_device *vgpu = NULL;
+ struct nv_vgpu_device *d;
+ u8 *base;
+ u64 off, size, hits = 0;
+
+ 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;
+ size = vgpu->bars[1].size;
+ if (!base)
+ return -EINVAL;
+ if (!max_hits)
+ max_hits = 16;
+
+ for (off = 0; off + 8 <= size; off += 8) {
+ u64 v;
+
+ memcpy(&v, base + off, 8);
+ if (v != pattern)
+ continue;
+ pr_info("sema-vidmem: found 0x%llx at 0x%llx\n",
+ (unsigned long long)pattern, (unsigned long long)off);
+ if (++hits >= max_hits) {
+ pr_info("sema-vidmem: stopping after %llu hits\n",
+ (unsigned long long)hits);
+ break;
+ }
+ }
+ pr_info("sema-vidmem: search 0x%llx done, %llu hit(s)\n",
+ (unsigned long long)pattern, (unsigned long long)hits);
+ 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 67d138d..1ffbb4a 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -61,6 +61,7 @@ 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_find_vidmem(u64 pattern, u64 max_hits);
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 3a42132..efa4bf7 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -2578,6 +2578,37 @@ 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: search the whole emulated vidmem for an 8-byte pattern:
+ * echo 0x0000000400000001,16 > .../parameters/sema_vidmem_find
+ */
+static int nv_vgpu_sema_vidmem_find_set(const char *val,
+ const struct kernel_param *kp)
+{
+ char buf[64];
+ char *comma;
+ u64 pattern = 0, max_hits = 16;
+
+ strscpy(buf, val, sizeof(buf));
+ comma = strchr(buf, ',');
+ if (comma) {
+ *comma = '\0';
+ if (kstrtoull(comma + 1, 0, &max_hits))
+ return -EINVAL;
+ }
+ if (kstrtoull(buf, 0, &pattern))
+ return -EINVAL;
+
+ return gsp_sema_service_find_vidmem(pattern, max_hits);
+}
+
+static const struct kernel_param_ops nv_vgpu_sema_vidmem_find_ops = {
+ .set = nv_vgpu_sema_vidmem_find_set,
+};
+
+module_param_cb(sema_vidmem_find, &nv_vgpu_sema_vidmem_find_ops, NULL, 0200);
+MODULE_PARM_DESC(sema_vidmem_find, "Search emulated vidmem for an 8-byte pattern (pattern, max_hits)");
+
+/*
* Debug: find page-table entries pointing at a physical address, in guest RAM
* and emulated vidmem:
* echo 0x12442b000 > .../parameters/scan_pt