summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 11:45:58 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 11:45:58 -0400
commit91a11327a152cba1b71bf11bc3d13b1358fb35a4 (patch)
tree4018b788742894ba02ae102998b2a483e5a11c11 /tools/guest-diag
parent7924df70261aad94b919add5778a910b0f9837bd (diff)
downloadopen-iov-91a11327a152cba1b71bf11bc3d13b1358fb35a4.tar.gz
open-iov-91a11327a152cba1b71bf11bc3d13b1358fb35a4.zip
wall2 session 90: current-boot wait site identified (eglcore+0xB2852D in-process word pair wait inside vkCreateInstance; old 0xa85d24/16K sites dead this boot); t83 sampler + widened nudge tools; multi-word nudge trips -4 (caution confirmed)
Diffstat (limited to 'tools/guest-diag')
-rw-r--r--tools/guest-diag/wall2/README-session77.md25
-rwxr-xr-xtools/guest-diag/wall2/nudge2.sh22
-rw-r--r--tools/guest-diag/wall2/t80r.py32
-rw-r--r--tools/guest-diag/wall2/t83.py25
4 files changed, 104 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/README-session77.md b/tools/guest-diag/wall2/README-session77.md
index 1c59e2d..46d3b8a 100644
--- a/tools/guest-diag/wall2/README-session77.md
+++ b/tools/guest-diag/wall2/README-session77.md
@@ -481,3 +481,28 @@ gr_forward=0 is the correct test configuration; the remaining suspect is
the service-global svc.op_tr_pending path in svc_opdef_release (it records
the release into an opdef slot and returns true silently when the slot
already contains it).
+
+**7. Session 90: the CURRENT-boot wait loop site (the old recipe no longer matches).**
+The client's long spin on this driver/boot sits INSIDE vkCreateInstance (bt:
+libEGL -> eglcore -> 0xB2852D helper), a bounded yield loop at
+eglcore+0xB2852D: `mov (%r11),%r12d / test $1,%r12b / jne <exit> /
+mov 0x4(%r11),%eax / cmp $1,%eax / jne <retry>` - the loop waits for an
+IN-PROCESS word pair at r11 (e.g. 0x7ffc2a1c5080, stack/heap; guest-written
+only, the host RAM file cannot feed it because it is not a GPU buffer).
+Evidence the old site moved: t91's breakpoint at eglcore+0xa85d24 never
+fires this boot (`clears=0`) and a read-watchpoint (t80r.py) on the +0x80
+words of the two 16 KB rw-s nvidiactl mappings does not fire either (the
+16K event-buffer wait of sessions 77/78 is not the live target now; the
+spin stack is +0xB2852D <- +0xA5325A <- +0xA539AD <- +0xA47491 <- +0x9FF515
+<- +0xA20D04 <- libEGL, NOT the 0xA85F1A/A8 path). A widened multi-word
+nudge (nudge2.sh/guest_words2.sh: all rw-s nvidia mappings <=256K, +0x80)
+DID fire on 20+ words but the client still returned -4 - the session-77
+caution stands: multi-word writes trip the error path; single-word only,
+after identifying the true target.
+NEXT: (a) rwatch WRITE on r11+4 to name the writer of the in-process word
+(the component that must run; if nothing ever writes it, disassemble the
+exit branch 0x...ebc9 vs retry 0x...eb93 to see the pass/fail contract);
+(b) the same for the 0xA53xxx caller chain - one of these callers is the
+A8/NvOgl GL-ucode wait of sessions 78/79 (its completion comes from the
+emulated GR engine path); (c) only then re-test the count-clear + single
+word nudge recipes.
diff --git a/tools/guest-diag/wall2/nudge2.sh b/tools/guest-diag/wall2/nudge2.sh
new file mode 100755
index 0000000..16ebcd8
--- /dev/null
+++ b/tools/guest-diag/wall2/nudge2.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# nudge2.sh - widened readiness-word nudger: ALL rw-s nvidia mappings <=256K,
+# writes 1 to any +0x80 u32 that is 0.
+DUR=${1:-300}
+F=/dev/shm/vgpu-guest-ram
+END=$(( $(date +%s) + DUR ))
+sshpass -p ubuntu scp -o StrictHostKeyChecking=no -P 2222 /tmp/opencode/guest_words2.sh ubuntu@127.0.0.1:/tmp/guest_words2.sh >/dev/null 2>&1
+while [ "$(date +%s)" -lt "$END" ]; do
+ OUT=$(timeout 12 sshpass -p ubuntu ssh -o StrictHostKeyChecking=no -p 2222 ubuntu@127.0.0.1 "sudo bash /tmp/guest_words2.sh" 2>/dev/null)
+ [ -n "$OUT" ] && echo "[$(date +%H:%M:%S)] words:" && echo "$OUT"
+ echo "$OUT" | while read -r VA PA SZ; do
+ [ -z "$PA" ] && continue
+ PAD=$((PA)); FOD=$((PAD - 0x80000000)); [ $FOD -lt 0 ] && FOD=$((PAD))
+ CUR=$(sudo dd if=$F bs=4 skip=$((FOD/4)) count=1 2>/dev/null | xxd -p)
+ if [ "$CUR" = "00000000" ]; then
+ printf '\x01\x00\x00\x00' | sudo dd of=$F bs=1 seek=$FOD count=4 conv=notrunc 2>/dev/null
+ echo " NUDGE va=$VA pa=$PA -> 1"
+ fi
+ done
+ sleep 1.5
+done
+echo NUDGE2-DONE
diff --git a/tools/guest-diag/wall2/t80r.py b/tools/guest-diag/wall2/t80r.py
new file mode 100644
index 0000000..ac2263b
--- /dev/null
+++ b/tools/guest-diag/wall2/t80r.py
@@ -0,0 +1,32 @@
+import gdb, sys
+inf = gdb.selected_inferior()
+pid = inf.pid
+cands = []
+for line in open("/proc/%d/maps" % pid):
+ if "nvidiactl" in line and "rw-s" in line:
+ parts = line.split()
+ try:
+ lo, hi = [int(x,16) for x in parts[0].split('-')]
+ except Exception:
+ continue
+ if hi - lo == 0x4000:
+ cands.append(lo + 0x80)
+print("CANDIDATES %s" % ["0x%x" % c for c in cands])
+class W(gdb.Breakpoint):
+ def __init__(self, addr):
+ super().__init__("*(unsigned int*)0x%x" % addr, gdb.BP_WATCHPOINT, gdb.WP_READ, internal=False)
+ self.addr = addr
+ self.silent = True
+ def stop(self):
+ print("READWORD 0x%x" % self.addr)
+ return True
+armed = 0
+for c in cands:
+ try:
+ W(c); armed += 1
+ except Exception as e:
+ print("watchfail 0x%x: %s" % (c, e))
+print("ARMED %d" % armed)
+if armed:
+ gdb.execute("continue")
+print("T80R-DONE")
diff --git a/tools/guest-diag/wall2/t83.py b/tools/guest-diag/wall2/t83.py
new file mode 100644
index 0000000..5e3cce2
--- /dev/null
+++ b/tools/guest-diag/wall2/t83.py
@@ -0,0 +1,25 @@
+import gdb
+from collections import Counter
+gr = gdb.execute
+pcs = Counter()
+inf = gdb.selected_inferior()
+for i in range(300):
+ try:
+ gr("stepi", to_string=True)
+ except Exception as e:
+ print("stepfail %s" % e); break
+ try:
+ pcs[int(gdb.parse_and_eval("$pc"))] += 1
+ except Exception:
+ break
+print("HOTPCS")
+top = pcs.most_common(4)
+for pc, n in top:
+ print("PC 0x%x hits=%d" % (pc, n))
+for pc, n in top[:1]:
+ try:
+ print(gr("x/10i 0x%x" % pc, to_string=True))
+ print(gr("info registers rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15", to_string=True))
+ except Exception as e:
+ print("fail %s" % e)
+print("T83-DONE")