summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/guest_pmap.py
blob: e2622c4f2c03dbfef08f0651677a9d620e211f51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2026 Open-IOV contributors
# guest-side helper: translate GPU/user VAs of a process through its pagemap.
# Usage: sudo python3 guest_pmap.py <pid> <hex-va> [hex-va ...]
import os
import sys

pid = int(sys.argv[1])
vas = [int(x, 16) for x in sys.argv[2:]]

maps = []
try:
    with open('/proc/%d/maps' % pid) as f:
        for line in f:
            parts = line.split()
            a, b = parts[0].split('-')
            maps.append((int(a, 16), int(b, 16), line.strip()))
except OSError as e:
    print('MAPS_ERROR: %s' % e)

def in_maps(va):
    for a, b, line in maps:
        if a <= va < b:
            return line
    return None

fd = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY)
try:
    for va in vas:
        os.lseek(fd, (va // 4096) * 8, 0)
        e = int.from_bytes(os.read(fd, 8), 'little')
        present = (e >> 63) & 1
        pfn = e & ((1 << 55) - 1)
        pa = (pfn << 12) | (va & 0xfff)
        line = in_maps(va)
        print('VA=0x%x present=%d PA=0x%x map=%s' % (va, present, pa, line if line else '-'))
finally:
    os.close(fd)