summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/wall2/t121.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/wall2/t121.py')
-rw-r--r--tools/guest-diag/wall2/t121.py151
1 files changed, 151 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/t121.py b/tools/guest-diag/wall2/t121.py
new file mode 100644
index 0000000..1ae25ed
--- /dev/null
+++ b/tools/guest-diag/wall2/t121.py
@@ -0,0 +1,151 @@
+import gdb
+gr = gdb.execute
+state = {"n": 0, "any": 0, "pend": None, "base": None, "chits": 0, "cleared": 0,
+ "whits": 0, "wrote": 0}
+
+def u32(a):
+ return int(gdb.parse_and_eval("*(unsigned int*)0x%x" % a))
+def u64(a):
+ return int(gdb.parse_and_eval("*(unsigned long*)0x%x" % a))
+
+def ioc(d, t, nr, size):
+ return (d << 30) | (size << 16) | (t << 8) | nr
+
+VIDHEAP = ioc(3, 0x46, 0x4a, 0xb8)
+
+def glbase():
+ try:
+ pid = gdb.selected_inferior().pid
+ for line in open("/proc/%d/maps" % pid):
+ parts = line.split()
+ if "libnvidia-eglcore" in line and int(parts[2], 16) == 0:
+ return int(parts[0].split("-")[0], 16)
+ except Exception:
+ pass
+ return None
+
+class BC(gdb.Breakpoint):
+ def __init__(self, addr):
+ super().__init__("*0x%x" % addr, 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
+ print("CLEAR#%d obj=0x%x n=0x%x tgt=0x%x" % (state["cleared"], obj, n, tgt), flush=True)
+ except Exception:
+ pass
+ except Exception:
+ pass
+ return False
+
+class BW(gdb.Breakpoint):
+ def __init__(self, addr):
+ super().__init__("*0x%x" % addr, 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), flush=True)
+ if val == 0:
+ gr("set {unsigned int}0x%x = 1" % word)
+ state["wrote"] += 1
+ except Exception:
+ pass
+ return False
+
+class IOC(gdb.Breakpoint):
+ def __init__(self):
+ super().__init__("ioctl", internal=False)
+ self.silent = True
+ def stop(self):
+ if state["base"] is None:
+ b = glbase()
+ if b:
+ state["base"] = b
+ print("GLBASE 0x%x" % b, flush=True)
+ try:
+ BC(b + 0xB33D30)
+ BW(b + 0xDCEBD9)
+ print("BC-BW-SET", flush=True)
+ except Exception as e:
+ print("bpset-fail %s" % e, flush=True)
+ try:
+ req = int(gdb.parse_and_eval("$rsi")) & 0xFFFFFFFF
+ arg = int(gdb.parse_and_eval("$rdx"))
+ except Exception:
+ return False
+ if state["pend"] is not None:
+ try:
+ st = u32(state["pend"] + 0x14)
+ at = u32(state["pend"] + 0x38)
+ off = u64(state["pend"] + 0x68)
+ print("PREV149-OUT st=0x%x attr=0x%x off=0x%x" % (st, at, off), flush=True)
+ except Exception as e:
+ print("PREV149-STATUS unreadable %s" % e, flush=True)
+ state["pend"] = None
+ if req != VIDHEAP:
+ return False
+ state["any"] += 1
+ try:
+ fn = u32(arg + 0x08)
+ size = u64(arg + 0x58)
+ attr = u32(arg + 0x38)
+ owner = u32(arg + 0x28)
+ flags = u32(arg + 0x34)
+ except Exception:
+ return False
+ if fn == 2:
+ state["n"] += 1
+ if state["n"] >= 120:
+ print("VH#%d size=0x%x align=0x%x attr=0x%x attr2=0x%x flags=0x%x owner=0x%x range=0x%x-0x%x" % (
+ state["n"], size, u64(arg + 0x60), attr, u32(arg + 0x90), flags, owner,
+ u64(arg + 0x80), u64(arg + 0x88)), flush=True)
+ if size == 0x10000 and (attr & 0xf000) == 0x2000 and owner == 0x474C0000:
+ print("HIT149 attr=0x%x flags=0x%x" % (attr, flags), flush=True)
+ gr("bt 12")
+ newattr = attr & 0xFFFFCFFF
+ gr("set {unsigned int}0x%x = 0x%x" % (arg + 0x38, newattr))
+ print("FLIP149 attr 0x%x -> 0x%x" % (attr, newattr), flush=True)
+ state["pend"] = arg
+ return False
+
+try:
+ IOC()
+ print("BPS-SET", flush=True)
+except Exception as e:
+ print("bpset-fail %s" % e, flush=True)
+
+gr("set pagination off")
+gr("set confirm off")
+try:
+ gr("run")
+except Exception as e:
+ print("runend %s" % e, flush=True)
+print("T120-DONE n=%d any=%d chits=%d cleared=%d whits=%d wrote=%d" % (
+ state["n"], state["any"], state["chits"], state["cleared"],
+ state["whits"], state["wrote"]), flush=True)
+gr("quit")