From 10c043a669fed5340eb953a17e341a35a4bce1b5 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 12 Nov 2026 14:55:25 -0500 Subject: vgsp: direct-GL ring/push rescue, VAS/pdb scanners and PTIMER tick; r1780 cycle tooling --- kernel/main.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'kernel/main.c') diff --git a/kernel/main.c b/kernel/main.c index e17840a..cb296f6 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2636,6 +2636,87 @@ module_param_cb(sema_scrubbuf_add, &nv_vgpu_sema_scrubbuf_ops, NULL, 0200); MODULE_PARM_DESC(sema_scrubbuf_add, "Register the PMA scrubber finish/host-sema PAs (hex fin,hex hsem)"); +/* + * r1780 (V34): bounded page-directory scan for a content-verified pair: + * echo 0x,0x[,0x[,0x]] > .../parameters/sema_pdb_scan + * Walks every 4 KB candidate root in the FB shadow (then optional guest + * RAM) for `va` and registers the root that reproduces `pa` under `h_vas`. + */ +static int nv_vgpu_sema_pdb_scan_set(const char *val, + const struct kernel_param *kp) +{ + char buf[80]; + char *fields[4] = { NULL }; + u64 v[4] = { 0 }; + int nf = 0, i; + char *p; + + strscpy(buf, val, sizeof(buf)); + p = buf; + for (i = 0; i < 4 && p; i++) { + fields[nf++] = p; + p = strchr(p, ','); + if (p) + *p++ = '\0'; + } + for (i = 0; i < nf; i++) + if (kstrtoull(fields[i], 0, &v[i])) + return -EINVAL; + if (nf < 2) + return -EINVAL; + return gsp_sema_service_pdb_scan(v[0], v[1], + nf > 2 ? (u32)v[2] : 0xbeef0300u, + nf > 3 ? v[3] : 0); +} + +static const struct kernel_param_ops nv_vgpu_sema_pdb_scan_ops = { + .set = nv_vgpu_sema_pdb_scan_set, +}; + +module_param_cb(sema_pdb_scan, &nv_vgpu_sema_pdb_scan_ops, NULL, 0200); +MODULE_PARM_DESC(sema_pdb_scan, + "Scan FB/RAM roots for a content-verified VA->PA pair and register the VAS"); + +/* + * r1780 (V34): direct VAS registration: + * echo 0x,0x[,[,]] > .../parameters/sema_vas_force + */ +static int nv_vgpu_sema_vas_force_set(const char *val, + const struct kernel_param *kp) +{ + char buf[80]; + char *fields[4] = { NULL }; + u64 v[4] = { 0 }; + int nf = 0, i; + char *p; + + strscpy(buf, val, sizeof(buf)); + p = buf; + for (i = 0; i < 4 && p; i++) { + fields[nf++] = p; + p = strchr(p, ','); + if (p) + *p++ = '\0'; + } + for (i = 0; i < nf; i++) + if (kstrtoull(fields[i], 0, &v[i])) + return -EINVAL; + if (nf < 2 || !v[0] || !v[1]) + return -EINVAL; + gsp_sema_service_vas_force((u32)v[0], v[1], + nf > 2 ? (u32)v[2] : 4u, + nf > 3 ? !!v[3] : false); + return 0; +} + +static const struct kernel_param_ops nv_vgpu_sema_vas_force_ops = { + .set = nv_vgpu_sema_vas_force_set, +}; + +module_param_cb(sema_vas_force, &nv_vgpu_sema_vas_force_ops, NULL, 0200); +MODULE_PARM_DESC(sema_vas_force, + "Register a VAS directory out-of-band (h,pdb,entries,vidmem)"); + /* * Debug: run the page-table walks for a GPU VA with per-level tracing, * bypassing the pin/lat/pair map (see gsp_sema_service_walk_probe): -- cgit v1.2.3