#!/usr/bin/env python3 # unwait.py - guest-side, zero-ptrace wait-word poller: writes 1 to the +0x80 # u32 of every zero 16 KB rw-s nvidiactl mapping of the newest vk_frame. import os, re, subprocess, sys, time DUR = float(sys.argv[1]) if len(sys.argv) > 1 else 600 def newest_pid(): try: out = subprocess.run(["pgrep", "-n", "-x", "vk_frame"], capture_output=True).stdout return int(out.decode().strip()) except Exception: return None def maps(pid): try: return open("/proc/%d/maps" % pid).read() except Exception: return "" logged = set() end = time.time() + DUR while time.time() < end: pid = newest_pid() if pid: for line in maps(pid).splitlines(): p = line.split() if len(p) < 6 or "nvidia" not in p[-1] or "rw-s" not in p[1]: continue try: lo, hi = [int(x, 16) for x in p[0].split("-")] except Exception: continue if hi - lo != 0x4000: continue wa = lo + 0x80 try: fd = os.open("/proc/%d/mem" % pid, os.O_RDWR) os.lseek(fd, wa, 0) v = os.read(fd, 4) if len(v) == 4 and v == b"\x00\x00\x00\x00": os.lseek(fd, wa, 0) os.write(fd, b"\x01\x00\x00\x00") key = (pid, wa) if key not in logged: logged.add(key) print("WORDWROTE pid=%d va=0x%x" % (pid, wa), flush=True) os.close(fd) except Exception: pass time.sleep(0.4) print("UNWAIT-DONE", flush=True)