diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/guest-diag/guest_pmap_win.py | 38 | ||||
| -rw-r--r-- | tools/guest-diag/pin_gr_window.py | 13 |
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 |
