summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-28 13:27:31 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-28 13:27:31 -0400
commit11ee6919311f2bee524f6d9944826e677ef62e59 (patch)
treeba71c9c27337dbc4c71f083da479afcb5d893b07 /tools
parent03d8df9ece5bd2d81703b3eeac07e4d889639674 (diff)
downloadopen-iov-11ee6919311f2bee524f6d9944826e677ef62e59.tar.gz
open-iov-11ee6919311f2bee524f6d9944826e677ef62e59.zip
guest-diag: ctx999.py (scanner/ctx gdb capture); fix pinner exact-VA match
ctx999.py arms the scanner entry/returns plus cuCtxCreate and dumps the ctx->mgr->reg->record chain at the stop. First live capture: the scanner is called with param_2=1 during normal context creation and correctly returns 0 on a zero record (mgr[+0], the channel handle, and the record walk are now confirmed live). pin_miss_pages.sh must match the exact VA pmapall printed: guest_pmap_all.py returns the first nvidia page at-or-above va-min, so a page that is not present resolves to an unrelated mapping (it pinned a UVM page for 0x20400f000).
Diffstat (limited to 'tools')
-rw-r--r--tools/guest-diag/ctx999.py102
-rwxr-xr-xtools/guest-diag/pin_miss_pages.sh2
2 files changed, 103 insertions, 1 deletions
diff --git a/tools/guest-diag/ctx999.py b/tools/guest-diag/ctx999.py
new file mode 100644
index 0000000..e5472c8
--- /dev/null
+++ b/tools/guest-diag/ctx999.py
@@ -0,0 +1,102 @@
+# gdb script: catch where a hanging/failing cuCtxCreate goes.
+#
+# Arms the libcuda 999-scanner sites (FUN_0054fa00 entry/999/0x2cf returns)
+# plus cuCtxCreate (symbol), then:
+# - at the first stop: dump RIP, backtrace and, if it is a scanner frame,
+# the RM error record chain (rdi -> ctx -> ctx[0x1291] -> +0x10 -> +0x10);
+# - then `finish` to capture the return value (rax) of whatever frame it
+# stopped in, and a backtrace of the caller.
+# Use with a cdt that holds on failure (CDT_HOLD=<s>) so the state survives.
+# Run: sudo gdb -p <cdt-pid> -batch -x /tmp/ctx999.py
+import gdb
+
+out = gdb.execute("info proc mappings", to_string=True)
+base = None
+for line in out.splitlines():
+ if "libcuda" in line and "r-xp" in line:
+ f = line.split()
+ base = int(f[0], 16) - int(f[3], 16)
+ break
+print("BASE=0x%x" % (base or 0))
+if base is None:
+ print("NO_LIBCUDA_MAPPING")
+ raise SystemExit
+gdb.execute("set pagination off")
+gdb.execute("set confirm off")
+for off in (0x44fa00, 0x44fb80, 0x44fb6c):
+ gdb.execute("break *0x%x" % (base + off))
+try:
+ gdb.execute("break cuCtxCreate")
+except gdb.error as e:
+ print("break cuCtxCreate: %s" % e)
+try:
+ gdb.execute("continue")
+except gdb.error as e:
+ print("CONTINUE_ERR %s" % e)
+print("STOPPED")
+try:
+ rip = int(gdb.parse_and_eval("$rip")) & 0xffffffffffffffff
+ print("RIP=0x%x off=0x%x" % (rip, rip - base))
+except Exception as e:
+ print("rip_fail %s" % e)
+try:
+ print(gdb.execute("info registers rdi rsi rax", to_string=True))
+except Exception:
+ pass
+try:
+ print(gdb.execute("bt 12", to_string=True))
+except Exception as e:
+ print("bt_fail %s" % e)
+
+
+def rd64(addr):
+ try:
+ return int(gdb.parse_and_eval("*(unsigned long *)0x%x" % addr)) & 0xffffffffffffffff
+ except Exception:
+ return None
+
+
+def rd32(addr):
+ try:
+ return int(gdb.parse_and_eval("*(unsigned int *)0x%x" % addr)) & 0xffffffff
+ except Exception:
+ return None
+
+
+try:
+ p1 = int(gdb.parse_and_eval("$rdi")) & 0xffffffffffffffff
+ ctx = rd64(p1)
+ print("param_1=0x%x ctx=0x%x" % (p1, ctx or 0))
+ if ctx:
+ mgr = rd64(ctx + 0x1291 * 8)
+ print("mgr=0x%x" % (mgr or 0))
+ if mgr:
+ for mo in (0x0, 0x8, 0x10, 0x18, 0x38):
+ print(" mgr[+0x%x]=0x%x" % (mo, rd64(mgr + mo) or 0))
+ reg = rd64(mgr + 0x10)
+ print("reg=0x%x" % (reg or 0))
+ if reg:
+ rec = rd64(reg + 0x10)
+ print("rec=0x%x" % (rec or 0))
+ if rec:
+ for i in range(0, 0x28, 4):
+ print(" rec[+0x%02x]=0x%08x" % (i, rd32(rec + i) or 0))
+except Exception as e:
+ print("record_dump_fail %s" % e)
+
+try:
+ gdb.execute("finish")
+ print("FINISHED")
+ print(gdb.execute("info registers rax", to_string=True))
+except gdb.error as e:
+ print("finish_err %s" % e)
+except Exception as e:
+ print("finish_other %s" % e)
+try:
+ print(gdb.execute("bt 12", to_string=True))
+except Exception:
+ pass
+try:
+ gdb.execute("detach")
+except Exception:
+ pass
diff --git a/tools/guest-diag/pin_miss_pages.sh b/tools/guest-diag/pin_miss_pages.sh
index 80b8c77..77268ef 100755
--- a/tools/guest-diag/pin_miss_pages.sh
+++ b/tools/guest-diag/pin_miss_pages.sh
@@ -43,7 +43,7 @@ for ((i = 1; i <= MAXMIN * 4; i++)); do
*" $page "*) continue ;;
esac
line=$(EXEC "sudo python3 /tmp/pmapall.py $pid $page 1" |
- grep -aE '^0x[0-9a-f]+,0x[0-9a-f]+$' | head -1)
+ grep -aE "^$page,0x[0-9a-f]+$" | head -1)
if [ -n "$line" ]; then
echo "$line,0x1000,1" | sudo tee /sys/module/open_iov_vfio/parameters/sema_map_add >/dev/null
echo "[$((i * 15))s] pinned $line (pid $pid)"