summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/tracker_walk.py
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-24 13:24:02 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-24 13:24:02 -0400
commit74b6fa4bb0912e310c24dbeefd58eadfc938f9b2 (patch)
treeb7c64e190889b5228b7fcf7ccd1f5c0d25da258f /tools/guest-diag/tracker_walk.py
parent016c290447c72a72eaac8337cbf09b32f87e9093 (diff)
downloadopen-iov-74b6fa4bb0912e310c24dbeefd58eadfc938f9b2.tar.gz
open-iov-74b6fa4bb0912e310c24dbeefd58eadfc938f9b2.zip
tools r624: tracker_walk.py + pool_page.py - guest-side (kcore) walks for the first-wait class: read a UVM tracker's semaphore object and expected payload, and dump the semaphore-pool page's applied values; together with the host pool-wr/sema-sw logs they compare what the driver waits for against what the host wrote
Diffstat (limited to 'tools/guest-diag/tracker_walk.py')
-rwxr-xr-xtools/guest-diag/tracker_walk.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/tools/guest-diag/tracker_walk.py b/tools/guest-diag/tracker_walk.py
new file mode 100755
index 0000000..3846fa1
--- /dev/null
+++ b/tools/guest-diag/tracker_walk.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+# tracker_walk.py - read a UVM tracking semaphore's expected payload and walk
+# its semaphore object via /proc/kcore (run in the guest as root).
+#
+# Use with a live stuck client: the udvt/uvtw kprobes or the scanner's #sem
+# lines give the tracker kptr (e.g. 0xffff899a885b5480); this prints
+# tracker+0x0 = semaphore kptr
+# tracker+0x28 = expected payload (the value the client waits to observe)
+# semaphore+0.. = its pointers (rm_mem/page) and candidate value words
+# Pair it with the host's pool-wr/deferred-release logs and a pool page dump
+# (pool_page.py) to compare what the driver expects vs what the host wrote.
+import sys
+import struct
+
+sys.argv = ["tracker_walk"]
+sys.path.insert(0, "/tmp")
+import guest_pin_stream as g # noqa: E402
+
+kc = g.Kcore()
+if not kc.load():
+ print("KCORE LOAD FAILED")
+ sys.exit(1)
+
+
+def r64(a):
+ d = kc.read(a, 8)
+ return struct.unpack("<Q", d)[0] if d else None
+
+
+def r32(a):
+ d = kc.read(a, 4)
+ return struct.unpack("<I", d)[0] if d else None
+
+
+for arg in sys.argv[1:] or ["0xffff899a885b5480"]:
+ SEM = int(arg, 16)
+ print("tracker 0x%x:" % SEM)
+ for off in range(0, 0x40, 8):
+ print(" +0x%x = 0x%x" % (off, r64(SEM + off) or 0))
+ sp = r64(SEM)
+ print("semaphore=0x%x" % (sp or 0))
+ if sp and g.is_kern_ptr(sp):
+ for off in range(0, 0x80, 8):
+ v = r64(sp + off)
+ print(" sem+0x%x = 0x%x" % (off, v or 0))
+ for off in range(0, 0x80, 8):
+ v = r64(sp + off)
+ if v and g.is_kern_ptr(v):
+ w = r32(v)
+ print(" *sem+0x%x -> dword=0x%x (%u)" % (off, w or 0, w or 0))