#!/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)