summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/guest-diag/guest_pmap_win.py38
-rw-r--r--tools/guest-diag/pin_gr_window.py13
2 files changed, 40 insertions, 11 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))
diff --git a/tools/guest-diag/pin_gr_window.py b/tools/guest-diag/pin_gr_window.py
index 4a968c9..26083f7 100644
--- a/tools/guest-diag/pin_gr_window.py
+++ b/tools/guest-diag/pin_gr_window.py
@@ -77,9 +77,14 @@ def scan(pid):
% (pid, LO, HI, MAXP, PAMAX), 90)
pairs = []
for line in out.splitlines():
- m = re.match(r"^(0x[0-9a-f]+),(0x[0-9a-f]+)$", line.strip())
- if m:
- pairs.append((int(m.group(1), 16), int(m.group(2), 16)))
+ m = re.match(r"^(0x[0-9a-f]+),(0x[0-9a-f]+)(?:,(\d+))?$", line.strip())
+ if not m:
+ continue
+ va = int(m.group(1), 16)
+ pa = int(m.group(2), 16)
+ n = int(m.group(3)) if m.group(3) else 1
+ for i in range(n):
+ pairs.append((va + i * 0x1000, pa + i * 0x1000))
return pairs
@@ -125,7 +130,7 @@ def probe(va):
def main():
- interval = float(sys.argv[1]) if len(sys.argv) > 1 else 2.0
+ interval = float(sys.argv[1]) if len(sys.argv) > 1 else 1.0
if not push_helper():
log("FATAL: could not push guest helper")
return 1