summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/wall2/gr_walk.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/wall2/gr_walk.py')
-rw-r--r--tools/guest-diag/wall2/gr_walk.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/tools/guest-diag/wall2/gr_walk.py b/tools/guest-diag/wall2/gr_walk.py
new file mode 100644
index 0000000..cbdb02d
--- /dev/null
+++ b/tools/guest-diag/wall2/gr_walk.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+# gr_walk.py - find the RM window memdesc records in the guest's own RAM
+# (via /proc/kcore direct map) and walk their kernel page-list pointers in
+# the SAME pass (addresses go stale otherwise). Prints VA->PA candidates.
+import sys, struct
+sys.path.insert(0, "/tmp")
+import guest_pin_stream as gps
+
+PAT_SIZE = struct.pack("<Q", 0x20000)
+PAT_FLAGS = struct.pack("<Q", 0x03008000)
+
+def main():
+ kc = gps.Kcore()
+ if not kc.load():
+ print("# kcore load failed"); return 1
+ pov = kc.page_offset_base
+ print("# page_offset_base=0x%x" % pov)
+ found = []
+ CH = 1 << 20
+ pa = 0x100000000
+ end = 0x180000000
+ while pa < end and len(found) < 12:
+ va = pov + pa
+ d = kc.read(va, CH)
+ if d:
+ st = 0
+ while True:
+ i = d.find(PAT_SIZE, st)
+ if i < 0:
+ break
+ st = i + 1
+ if i + 16 <= len(d) and d[i+8:i+16] == PAT_FLAGS:
+ found.append((pa + i, d[i:i+0x60]))
+ pa += CH
+ print("# memdesc records: %d" % len(found))
+ for (gpa, rec) in found:
+ size, flags = struct.unpack_from("<QQ", rec, 0)
+ wpa = struct.unpack_from("<Q", rec, 0x10)[0]
+ kptrs = [struct.unpack_from("<Q", rec, o)[0] for o in (0x18, 0x20, 0x28, 0x30, 0x38)]
+ print("rec@0x%x size=0x%x pa=0x%x kptrs=%s" %
+ (gpa, size, wpa, ["0x%x" % k for k in kptrs]))
+ # walk each kptr for PA-like lists
+ for kp in kptrs:
+ if not gps.is_kern_ptr(kp):
+ continue
+ dd = kc.read(kp, 0x80)
+ if not dd:
+ print(" kptr 0x%x: unreadable" % kp); continue
+ words = struct.unpack_from("<%dQ" % (len(dd)//8), dd, 0)
+ pas = [w for w in words if 0x100000000 <= w < 0x180000000]
+ npas = [w for w in words if 0x100000000 <= (w & ~0xfff) < 0x180000000]
+ print(" kptr 0x%x: %s" % (kp, " ".join("0x%x" % w for w in words[:10])))
+ if len(npas) >= 2:
+ print(" PA-like: %s" % ["0x%x" % w for w in npas[:16]])
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main())