diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-28 09:09:13 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-28 09:09:13 -0400 |
| commit | bde9352a0f84bdf0ef7bdfdc150f5f11a9200af3 (patch) | |
| tree | 8f151d950f65c00d191d7babbaad10e07b41f36a /tools | |
| parent | 2133dd1fd82b4fd37df45e134b9a073f081d49d1 (diff) | |
| download | open-iov-bde9352a0f84bdf0ef7bdfdc150f5f11a9200af3.tar.gz open-iov-bde9352a0f84bdf0ef7bdfdc150f5f11a9200af3.zip | |
sem: run GR channels - accept CE methods on subchannel 0, discover GR rings
- The CE semaphore/memset method groups also arrive on subchannel 0 (CUDA's
push library binds the copy class on compute channels to carry the
work-submission releases), so the stream decoder accepts both 0 and 4.
- GR (compute) channel rings live in the same video-memory allocation as the
CE rings, 0x3000 bytes per channel after them: ring (0x2000) at
ce_end + 0x3000*rank, USERD at +0x2000. Discover and pin them once the CE
ranks are known; verified against ring entry 0 (1 MB aligned push VA in
the client window, sane length) and the USERD's put/get, so a layout
change costs a failed pin, not a wrong one. Gated by sema_gr_rings
(default on).
- memprobe: require the sem-VA triple in the sem-object scanner (a bare
qword in the window matches thousands of unrelated pointers once the
ring/pushbuffer windows are part of the range).
Live evidence: ring entries read through the guest's /proc/pid/mem decode to
the GR channels' first pushes; pinning the ring (fb 0x140000+0x3000*rank),
USERD (ring+0x2000) and first-push pages made all 20 GR channels execute
their entry 0 for the first time (get=1 sub=1).
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/guest-diag/memprobe.py | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/tools/guest-diag/memprobe.py b/tools/guest-diag/memprobe.py index 96dd40b..c2bab9f 100644 --- a/tools/guest-diag/memprobe.py +++ b/tools/guest-diag/memprobe.py @@ -72,12 +72,24 @@ def scan_qwords(pid, fd, lo, hi, needle_lo=None, needle_hi=None, needle_set=None return hits def sem_objs(pid, fd, lo, hi): - # qword in [lo,hi) at address A -> a sem object holds it at +0x10 + # A real sem object stores its GPU VA three times, at so+0x08, so+0x10 and + # so+0x18. Requiring a duplicated neighbour keeps the scan selective: a + # bare qword in the window matches thousands of unrelated pointers once + # the ring/pushbuffer windows are part of the range. first = scan_qwords(pid, fd, None, None, needle_lo=lo, needle_hi=hi) - out = {} + cand = {} for addr, val in first: - so = addr - 0x10 - out.setdefault(val, set()).add(so) + cand.setdefault(val, set()).add(addr) + out = {} + for val, addrs in cand.items(): + for a in addrs: + buf = rd(fd, a - 8, 0x20) + if not buf or len(buf) < 0x20: + continue + q0, q1, q2, q3 = (r64(buf, i) for i in (0, 8, 0x10, 0x18)) + if q1 == val and (q0 == val or q2 == val) and \ + (q2 == val or q3 == val): + out.setdefault(val, set()).add(a - 0x10) return out def find_trackers(pid, fd, lo, hi, limit=8): |
