summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/wall2/t79.py
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 08:05:18 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 08:05:18 -0400
commit6baa2135a7815776a114e8afe883e68883d3f31b (patch)
tree1608d8eb25f128589ed2fcf82afe64171b2dee29 /tools/guest-diag/wall2/t79.py
parente3c1cdc5ee049797fe40ae648d2a936c7384d517 (diff)
downloadopen-iov-6baa2135a7815776a114e8afe883e68883d3f31b.tar.gz
open-iov-6baa2135a7815776a114e8afe883e68883d3f31b.zip
wall-2 session-77: vkCreateDevice PASSES - r682 0x7E event validated live (registered slot 13, EVPOST rc=0) and the completion word found/driven: the main-thread wait reads a u32 at +0x80 of a 16 KB rw-s /dev/nvidiactl notification mapping (should-wait = word != 1); a host write of 1 via the guest RAM file (PA from pagemap, file offset PA-0x80000000 above 4G) flips the wait and vkCreateDevice returns success (VKDEVICE ok family=0) - reproduced 3x (r683 manual, r684 nudger, r684d probe+single-word). Tools: t79.py (wait-chain resolver), guest_words.sh, nudge.sh; README-session77.md records the recipe, the residual guest event-dispatch gap (records consumed, notification word not written), and the -4/gdb-attach cautions.
Diffstat (limited to 'tools/guest-diag/wall2/t79.py')
-rw-r--r--tools/guest-diag/wall2/t79.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/t79.py b/tools/guest-diag/wall2/t79.py
new file mode 100644
index 0000000..c2fe381
--- /dev/null
+++ b/tools/guest-diag/wall2/t79.py
@@ -0,0 +1,99 @@
+import gdb, sys
+
+inf = gdb.selected_inferior()
+pid = inf.pid
+base = None
+for line in open("/proc/%d/maps" % pid):
+ if "libnvidia-eglcore.so.570.144" in line:
+ parts = line.split()
+ lo, hi = [int(x, 16) for x in parts[0].split('-')]
+ off = int(parts[2], 16)
+ if off == 0:
+ base = lo
+ break
+if base is None:
+ print("EGLBASE not found"); gdb.execute("detach"); sys.exit(1)
+print("EGLBASE 0x%x PID %d" % (base, pid))
+
+maps = []
+for line in open("/proc/%d/maps" % pid):
+ parts = line.split()
+ try:
+ lo, hi = [int(x, 16) for x in parts[0].split('-')]
+ maps.append((lo, hi, parts[1], parts[-1] if len(parts) > 5 else "anon"))
+ except Exception:
+ pass
+
+def resolve(addr):
+ for lo, hi, perm, name in maps:
+ if lo <= addr < hi:
+ return "0x%x-0x%x %s %s" % (lo, hi, perm, name)
+ return "?"
+
+def rd(a, n):
+ return inf.read_memory(a, n).tobytes()
+def u32(a):
+ return int.from_bytes(rd(a, 4), 'little')
+def u64(a):
+ return int.from_bytes(rd(a, 8), 'little')
+
+state = {"done": False}
+
+class B(gdb.Breakpoint):
+ def __init__(self, spec, fn, limit=100000):
+ super().__init__(spec, internal=False)
+ self.fn = fn; self.limit = limit; self.hits = 0
+ self.silent = True
+ def stop(self):
+ self.hits += 1
+ try:
+ stop = bool(self.fn(self))
+ except Exception as e:
+ print("ERR@0x%x %s" % (int(gdb.parse_and_eval("$pc")), e))
+ stop = False
+ return stop or self.hits >= self.limit
+
+def loophead(bp):
+ if state["done"]:
+ return False
+ state["done"] = True
+ rbx = int(gdb.parse_and_eval("$rbx"))
+ sub = u64(rbx+0x70)
+ print("WAIT rbx=0x%x sub=0x%x" % (rbx, sub))
+ try:
+ obj2 = u64(sub+0x58)
+ off = u32(obj2+0x60)
+ holder = u64(obj2+0x58)
+ base2 = u64(holder+0x58)
+ word_addr = base2 + off
+ val = u32(word_addr)
+ print("WAIT obj2=0x%x off=0x%x holder=0x%x base=0x%x word=0x%x val=0x%x" %
+ (obj2, off, holder, base2, word_addr, val))
+ print("WAIT word map:", resolve(word_addr))
+ print("WAIT holder obj2+0x50=0x%x obj2+0x64=0x%x" % (u64(obj2+0x50), u32(obj2+0x64)))
+ try:
+ hd = rd(holder, 0x30)
+ print("WAIT holder dump:", " ".join("%02x" % b for b in hd))
+ except Exception as e:
+ print("WAIT holder dump err", e)
+ except Exception as e:
+ print("WAIT chain err", e)
+ # dump the client's nvidiactl rw-s mappings
+ print("WAIT nvidiactl maps:")
+ for lo, hi, perm, name in maps:
+ if "nvidiactl" in name and "rw-s" in perm:
+ print(" 0x%x-0x%x size=0x%x" % (lo, hi, hi-lo))
+ return True
+
+B("*0x%x" % (base+0xdcebd9), loophead, 1)
+
+try:
+ gdb.execute("continue")
+except gdb.error as e:
+ print("CONT-ERR %s" % e)
+print("TRACE-END")
+try:
+ gdb.execute("detach")
+except gdb.error as e:
+ print("DETACH-ERR %s" % e)
+gdb.execute("quit")