summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/guest_pmap_win.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/guest_pmap_win.py')
-rw-r--r--tools/guest-diag/guest_pmap_win.py38
1 files changed, 31 insertions, 7 deletions
diff --git a/tools/guest-diag/guest_pmap_win.py b/tools/guest-diag/guest_pmap_win.py
index a9b74a7..f6ca85c 100644
--- a/tools/guest-diag/guest_pmap_win.py
+++ b/tools/guest-diag/guest_pmap_win.py
@@ -4,8 +4,9 @@
# pread) so a 256 MB window takes about a second, not minutes.
#
# Usage: sudo python3 guest_pmap_win.py <pid> <lo-hex> <hi-hex> [max-pairs] [pa-max-hex]
-# Output: one "0x<va>,0x<pa>" line per present page (ascending VA), capped at
-# max-pairs. PAs of 0 are skipped; pages above pa-max are skipped unless 0.
+# Output: one "0x<va>,0x<pa>,<npages>" line per contiguous run (ascending VA),
+# capped at max-pairs pages. PAs of 0 are skipped; pages at/above pa-max are
+# skipped unless pa-max is 0.
import os
import sys
@@ -17,6 +18,16 @@ pa_max = int(sys.argv[5], 16) if len(sys.argv) > 5 else 0
BATCH = 512
out = []
+run_va = run_pa = None
+run_n = 0
+pairs = 0
+
+
+def flush():
+ if run_n:
+ out.append('0x%x,0x%x,%d' % (run_va, run_pa, run_n))
+
+
fd = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY)
try:
va = lo
@@ -29,19 +40,32 @@ try:
got = len(data) // 8
for i in range(got):
e = int.from_bytes(data[i * 8:i * 8 + 8], 'little')
+ page_va = va + i * 0x1000
if not ((e >> 63) & 1):
+ flush()
+ run_va = run_pa = None
+ run_n = 0
continue
pfn = e & ((1 << 55) - 1)
pa = pfn << 12
- if not pa:
- continue
- if pa_max and pa >= pa_max:
+ if not pa or (pa_max and pa >= pa_max):
+ flush()
+ run_va = run_pa = None
+ run_n = 0
continue
- out.append('0x%x,0x%x' % (va + i * 0x1000, pa))
- if len(out) >= maxp:
+ if (run_va is not None and page_va == run_va + run_n * 0x1000
+ and pa == run_pa + run_n * 0x1000):
+ run_n += 1
+ else:
+ flush()
+ run_va, run_pa, run_n = page_va, pa, 1
+ pairs += 1
+ if pairs >= maxp:
+ flush()
print('\n'.join(out))
sys.exit(0)
va += got * 0x1000
finally:
os.close(fd)
+flush()
print('\n'.join(out))