summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/wall2/unwait2.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/wall2/unwait2.py')
-rw-r--r--tools/guest-diag/wall2/unwait2.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/unwait2.py b/tools/guest-diag/wall2/unwait2.py
new file mode 100644
index 0000000..cd4169b
--- /dev/null
+++ b/tools/guest-diag/wall2/unwait2.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+# unwait2.py - no-ptrace guest-side harness:
+# (a) writes 1 to any zero u32 at +0x80 of every 0x4000-byte rw-s nvidia
+# mapping of EVERY live vk_frame;
+# (b) scans each live vk_frame's anonymous/heap rw-p mappings (16-byte
+# aligned) for marker slots {u32@0==0, u16@+0xe==0xffff} and clears
+# u16@+0xe to 0 (the instance-phase pending markers the t105 gdb used
+# to clear). No ptrace anywhere.
+import os, subprocess, sys, time
+DUR = float(sys.argv[1]) if len(sys.argv) > 1 else 600
+def pids():
+ try:
+ out = subprocess.run(["pgrep", "-x", "vk_frame"], capture_output=True).stdout
+ return [int(x) for x in out.split()]
+ except Exception:
+ return []
+def rd(fd, off, n):
+ try:
+ os.lseek(fd, off, 0)
+ return os.read(fd, n)
+ except Exception:
+ return b""
+def wr(fd, off, data):
+ try:
+ os.lseek(fd, off, 0)
+ os.write(fd, data)
+ return True
+ except Exception:
+ return False
+wlog = set(); mlog = set()
+end = time.time() + DUR
+last_scan = 0.0
+while time.time() < end:
+ for pid in pids():
+ try:
+ fd = os.open("/proc/%d/mem" % pid, os.O_RDWR)
+ except Exception:
+ continue
+ try:
+ for line in open("/proc/%d/maps" % pid):
+ p = line.split()
+ if len(p) < 6 or "nvidia" not in p[-1] or "rw-s" not in p[1]:
+ continue
+ lo, hi = [int(x, 16) for x in p[0].split("-")]
+ if hi - lo != 0x4000:
+ continue
+ wa = lo + 0x80
+ v = rd(fd, wa, 4)
+ if len(v) == 4 and v == b"\x00\x00\x00\x00":
+ if wr(fd, wa, b"\x01\x00\x00\x00"):
+ k = (pid, wa)
+ if k not in wlog:
+ wlog.add(k)
+ print("WORDWROTE pid=%d va=0x%x" % (pid, wa), flush=True)
+ except Exception:
+ pass
+ if time.time() - last_scan > 1.5:
+ budget = 64
+ try:
+ for line in open("/proc/%d/maps" % pid):
+ p = line.split()
+ if len(p) < 6 or p[1] != "rw-p":
+ continue
+ path = p[-1]
+ if path.startswith("/") and "nvidia" not in path and path != "[heap]":
+ continue
+ lo, hi = [int(x, 16) for x in p[0].split("-")]
+ if hi - lo > 0x10000000:
+ hi = lo + 0x10000000
+ off = lo
+ while off < hi:
+ chunk = rd(fd, off, 0x100000)
+ if len(chunk) < 32:
+ break
+ j = 0
+ while j + 16 <= len(chunk):
+ if chunk[j:j+4] == b"\x00\x00\x00\x00" and chunk[j+0xe:j+0x10] == b"\xff\xff":
+ wa = off + j + 0xe
+ if (pid, wa) not in mlog:
+ if wr(fd, wa, b"\x00\x00"):
+ mlog.add((pid, wa))
+ print("MARKCLR pid=%d va=0x%x" % (pid, wa), flush=True)
+ j += 16
+ off += 0x100000
+ budget -= 1
+ if budget <= 0:
+ break
+ if budget <= 0:
+ break
+ except Exception:
+ pass
+ last_scan = time.time()
+ os.close(fd)
+ time.sleep(0.4)
+print("UNWAIT2-DONE", flush=True)