summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 12:46:53 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 12:46:53 -0400
commit1471101c74d50370e5a4bd1e76f6249dac60480b (patch)
treec891987d84caa57d02cd8ea7dea34c38d3b1b243
parentc4a1d573cce887dba6a3c65d86efd5662b1cec1c (diff)
downloadopen-iov-1471101c74d50370e5a4bd1e76f6249dac60480b.tar.gz
open-iov-1471101c74d50370e5a4bd1e76f6249dac60480b.zip
wall2 session 92: automated zero-touch pipeline reaches VKDEVICE on a fresh boot (t99 = marker-clear at +0xB33D30 + wait-word chase/write at +0xDCEBD9); live_walk PT injections alongside; attach-discipline lesson (wedged continue blocks later attaches); next = post-device wait identification
-rw-r--r--tools/guest-diag/wall2/README-session77.md37
-rw-r--r--tools/guest-diag/wall2/t99.py79
2 files changed, 116 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/README-session77.md b/tools/guest-diag/wall2/README-session77.md
index 97f9a84..f45dd70 100644
--- a/tools/guest-diag/wall2/README-session77.md
+++ b/tools/guest-diag/wall2/README-session77.md
@@ -536,3 +536,40 @@ data/info/status; compare against the guest's _kgspRpcPostEvent ->
gpuNotifySubDeviceEvent expectations) so the guest signals the event and
nvidia_poll returns POLLIN; then the same t94-pattern (or a service-side
equivalent) durably unblocks both waits per boot.
+
+**10. Session 92: THE AUTOMATED PIPELINE - fresh boot to VKDEVICE with ZERO manual steps.**
+On a fresh r692 boot (cycle params unchanged, gr_forward=0) a single gdb
+script (t99.py) carrying two breakpoint handlers drove the client end-to-end:
+(a) the instance-phase marker cleaner at eglcore+0xB33D30 (t94 pattern: clear
+u16@slot+0xe / u16@slot+0xc / u32@slot to 0 per entry at ptr+n*0x10 for
+entries *(obj+0x1428+i*8), cnt *(obj+0x22efc)) - fired CLEAR#1..#5 across
+five module objects; (b) the device-phase wait-word chaser at
+eglcore+0xDCEBD9 (t79 chain: rbx -> *(rbx+0x70) -> *(sub+0x58)=obj2 ->
+ off=*(u32)(obj2+0x60), holder=*(obj2+0x58), base=*(holder+0x58),
+word=base+off) - found WORD addr=0x734781a86080 val=0x0 and wrote 1.
+Result: `VKINSTANCE ok / VKDEVS 2 / VKPICK / VKDEVICE ok family=0` with no
+manual intervention (r692 client 1725). The client then sat in the
+POST-DEVICE wait (the next phase - allocation/engine-init), which t99 does
+not cover. The live_walk PT-walk injector ran alongside and injected the
+window/ring VAs (0x4d20000, 0x4923000...; note 0x4b19b10 resolved ap=FB -
+the GL init release is vidmem-mapped and skipped by the SYS-only injector).
+
+**11. HARD LESSON (attach discipline, again).** A gdb attached to a client
+that never hits its breakpoints wedges: `continue` never returns, the
+timeout's SIGTERM does not tear it down, and the ptrace slot blocks all
+later attaches (hit 3x this session: 146084, the t91-on-1725 attach, both
+left holding). RULE: only attach with breakpoints that are KNOWN to fire
+for the client's current phase, keep windows <= ~60 s, and prefer
+self-terminating handlers (hit caps). A wedged attach leaves the client
+RUNNING (state R) but unattachable; cycle the VM for a clean environment
+when more attaches are needed.
+
+**12. Continuing the chain (next session).** (1) Identify the post-device
+wait of the VKDEVICE-ok client (bt sample once attachable; likely the
+allocation/UVM phase or the A8/NvOgl engine-init with its count gate at
+lib_base+0x2070b7c=4 -> 0 and/or the 0xdceb80 wait loop - add the t91
+count-clear BP to the t99 bundle if the A8 path is live). (2) Extend t99
+into the "durable harness bundle": marker-clean + word-chase + count-clear
++ (once VKFRAME) the release/alloc phases. (3) The bNotifyList=1
+(gsp_rm_ev_nlist) path stays armed for the event-signal experiment;
+post/EVPOST logging re-budgeted (gsp_rm_ev_log=2000 set).
diff --git a/tools/guest-diag/wall2/t99.py b/tools/guest-diag/wall2/t99.py
new file mode 100644
index 0000000..ed665fb
--- /dev/null
+++ b/tools/guest-diag/wall2/t99.py
@@ -0,0 +1,79 @@
+import gdb
+gr = gdb.execute
+inf = gdb.selected_inferior()
+pid = inf.pid
+base = None
+for line in open("/proc/%d/maps" % pid):
+ parts = line.split()
+ try:
+ lo, hi = [int(x,16) for x in parts[0].split('-')]
+ except Exception:
+ continue
+ if base is None and "libnvidia-eglcore" in line and int(parts[2],16) == 0:
+ base = lo
+print("BASE 0x%x PID %d" % (base or 0, pid))
+def u64(a): return int(gdb.parse_and_eval("*(unsigned long*)0x%x" % a))
+def u32(a): return int(gdb.parse_and_eval("*(unsigned int*)0x%x" % a))
+state = {"chits":0, "cleared":0, "whits":0, "wrote":0}
+class BC(gdb.Breakpoint):
+ def __init__(self):
+ super().__init__("*0x%x" % (base + 0xB33D30), internal=False)
+ self.silent = True
+ def stop(self):
+ state["chits"] += 1
+ try:
+ obj = int(gdb.parse_and_eval("$rdi"))
+ n = int(gdb.parse_and_eval("$rsi"))
+ cnt = u32(obj + 0x22efc)
+ for i in range(0, min(cnt, 32)):
+ p = u64(obj + 0x1428 + i*8)
+ if not p:
+ continue
+ tgt = p + n * 0x10
+ try:
+ v16 = int(gdb.parse_and_eval("*(unsigned short*)0x%x" % (tgt + 0xe)))
+ if v16 == 0xffff:
+ gr("set {unsigned short}0x%x = 0" % (tgt + 0xe))
+ gr("set {unsigned int}0x%x = 0" % tgt)
+ gr("set {unsigned short}0x%x = 0" % (tgt + 0xc))
+ state["cleared"] += 1
+ if state["cleared"] <= 10:
+ print("CLEAR#%d obj=0x%x n=0x%x tgt=0x%x" % (state["cleared"], obj, n, tgt))
+ except Exception:
+ pass
+ except Exception as e:
+ if state["chits"] <= 4:
+ print("chitfail %s" % e)
+ return state["chits"] >= 6000
+class BW(gdb.Breakpoint):
+ def __init__(self):
+ super().__init__("*0x%x" % (base + 0xDCEBD9), internal=False)
+ self.silent = True
+ def stop(self):
+ state["whits"] += 1
+ try:
+ rbx = int(gdb.parse_and_eval("$rbx"))
+ sub = u64(rbx + 0x70)
+ obj2 = u64(sub + 0x58)
+ off = u32(obj2 + 0x60)
+ holder = u64(obj2 + 0x58)
+ base2 = u64(holder + 0x58)
+ word = base2 + off
+ val = u32(word)
+ if state["whits"] <= 6 or val == 0:
+ print("WORD#%d addr=0x%x val=0x%x" % (state["whits"], word, val))
+ if val == 0:
+ gr("set {unsigned int}0x%x = 1" % word)
+ state["wrote"] += 1
+ if state["wrote"] <= 10:
+ print("WORDWROTE 0x%x" % word)
+ except Exception as e:
+ if state["whits"] <= 4:
+ print("whitfail %s" % e)
+ return False
+try:
+ BC(); BW(); print("BPS-SET")
+ gr("continue")
+except Exception as e:
+ print("bpfail %s" % e)
+print("T99-DONE chits=%d cleared=%d whits=%d wrote=%d" % (state["chits"], state["cleared"], state["whits"], state["wrote"]))