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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#!/usr/bin/env python3
# r674: find every reference to the push VA 0x4480000 and follow RM structures
# (direct-map pointers: PA = ptr - page_offset_base) toward a page list.
import numpy as np, struct, os, time, sys
RAM="/dev/shm/vgpu-guest-ram"
VA=0x4480000
BASE=0xffff8916c0000000 # r674 page_offset_base (from dmesg rebuild #15)
img=open(RAM,"rb"); fsz=os.path.getsize(RAM)
def gpa2off(pa):
if pa<0x80000000: return pa
if pa<0x180000000: return 0x80000000+(pa-0x100000000)
return None
def off2gpa(off):
return off if off<0x80000000 else 0x100000000+(off-0x80000000)
def rd(pa,n):
off=gpa2off(pa)
if off is None or off+n>fsz: return None
img.seek(off); return img.read(n)
def ptr2pa(v):
if BASE<=v<BASE+0x180000000:
return v-BASE
return None
CH=64<<20
hits=[]
t0=time.time()
for pos in range(0,fsz,CH):
img.seek(pos); d=img.read(min(CH,fsz-pos))
n=len(d)//8
a=np.frombuffer(d[:n*8],dtype=np.uint64)
idx=np.nonzero(a==np.uint64(VA))[0]
for i in idx: hits.append(off2gpa(pos+int(i)*8))
print("VA hits:", len(hits), "(%.1fs)" % (time.time()-t0))
def tag(v):
bs=struct.pack("<Q",v)
return bs.decode() if all(32<=c<127 for c in bs) else ""
for gpa in hits:
page=gpa&~0xfff
d=rd(page,0x1000)
if not d: continue
ro=gpa-page
print("== hit gpa=0x%x page=0x%x off=0x%x ==" % (gpa,page,ro))
# print 0x60 before, 0x80 after
s=max(0,ro-0x60); e=min(0x1000,ro+0x80)
for o in range(s,e,0x10):
a,b=struct.unpack_from("<QQ",d,o)
print(" +0x%03x: %016x %016x %s %s" % (o,a,b,tag(a),tag(b)))
# follow direct-map pointers in this page
for o in range(0,0x1000-8,8):
v=struct.unpack_from("<Q",d,o)[0]
pa=ptr2pa(v)
if pa is None: continue
dd=rd(pa&~0xfff,0x1000)
if not dd: continue
# search that page for PA runs (>=8 page-aligned RAM PAs ascending/descending)
runs=[]; cur=[]
for oo in range(0,0xff8,8):
vv=struct.unpack_from("<Q",dd,oo)[0]
if 0x100000000<=vv<0x180000000 and (vv&0xfff)==0:
cur.append((oo,vv))
else:
if len(cur)>=8: runs.append(cur)
cur=[]
if len(cur)>=8: runs.append(cur)
if runs:
print(" ptr +0x%03x -> pa=0x%x has %d PA-run(s):" % (o,pa&~0xfff,len(runs)))
for r in runs[:4]:
print(" run at +0x%x: %d pages first=0x%x last=0x%x" % (r[0][0],len(r),r[0][1],r[-1][1]))
|