summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-28 09:31:48 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-28 09:31:48 -0400
commit7023742accd4b2bf5dbeaf82907e465c905dbdad (patch)
treed4dc733894235a8198bb38909701387a22d86cb2 /tools
parentab393b15abac5b6c0790bb4c4fd86bc62c531bf4 (diff)
downloadopen-iov-7023742accd4b2bf5dbeaf82907e465c905dbdad.tar.gz
open-iov-7023742accd4b2bf5dbeaf82907e465c905dbdad.zip
sema: never execute work decoded from swept RAM; pin only tracker sems
The content sweep reads arbitrary guest RAM and ran the full push decoder on every page, so fabricated method streams in unrelated data executed fills/copies: one boot scanned 65M pages, 'decoded' 124k pushes and ran dozens of memsets from false positives - writes into live guest memory (a guest kernel crashed in nvidia_uvm right after such a boot). - Swept pages now only permit the bounded semaphore-release writes; fills and copies execute only for pushes the pump read through a trusted ring translation. - Pushes read for a compute (GR) channel apply releases only: their method space is not the copy engine's, so aliased encodings must never become memory writes. - sempages.py derives the pages to pin from the client's tracker objects (sem object + sem memory) instead of matching bare sem-object shapes, which pinned 140 pages where the client has ~53 sems; shape scan remains as a fallback when no tracker resolves.
Diffstat (limited to 'tools')
-rwxr-xr-xtools/guest-diag/sempages.py22
1 files changed, 19 insertions, 3 deletions
diff --git a/tools/guest-diag/sempages.py b/tools/guest-diag/sempages.py
index ad4dae6..f8d15b2 100755
--- a/tools/guest-diag/sempages.py
+++ b/tools/guest-diag/sempages.py
@@ -29,9 +29,25 @@ else:
raise SystemExit(1)
fd = os.open('/proc/%d/mem' % pid, os.O_RDONLY)
-sems = m.sem_objs(pid, fd, lo, hi)
+# Pin what libcuda actually polls: the semaphore objects referenced by the
+# client's trackers (and the semaphore memory they point at). Scanning for
+# bare sem-object shapes matches far too many pages once the ring/pushbuffer
+# windows are in range; trackers are a structural reference, so pinning is
+# limited to pages the client really waits on. Fall back to the shape scan
+# only when no tracker resolves.
+pages = set()
+trackers = m.find_trackers(pid, fd, lo, hi, limit=256)
+for _p, _sub, _last, _cur, sem, mem in trackers:
+ if sem:
+ pages.add(sem & ~0xfff)
+ if mem:
+ pages.add(mem & ~0xfff)
+if not pages:
+ sems = m.sem_objs(pid, fd, lo, hi)
+ pages = {va & ~0xfff for va in sems}
os.close(fd)
-pages = sorted({va & ~0xfff for va in sems})
-print('sem VAs: %d pages: %d (window 0x%x..0x%x)' % (len(sems), len(pages), lo, hi))
+pages = sorted(pages)
+print('trackers: %d pages: %d (window 0x%x..0x%x)' %
+ (len(trackers), len(pages), lo, hi))
for pg in pages:
print('0x%x' % pg)