summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/guest_pin_stream.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/guest-diag/guest_pin_stream.py')
-rw-r--r--tools/guest-diag/guest_pin_stream.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/tools/guest-diag/guest_pin_stream.py b/tools/guest-diag/guest_pin_stream.py
index e98d851..3222a90 100644
--- a/tools/guest-diag/guest_pin_stream.py
+++ b/tools/guest-diag/guest_pin_stream.py
@@ -2201,6 +2201,42 @@ def scan_range(fd, lo, hi, out):
va += got * 0x1000
+def _pagemap_window_pin(pid, ev, off, ln, out):
+ """Direct client-pagemap pin for [ev, ev+ln) (window-wide r586 fallback).
+
+ SESSION 153-r1397: a strict anchor whose full-window content parse fails
+ (both the kernel-vmap candidates and the client-mem scan) used to set
+ strict_pending and thereby stall EVERY loose demand VA of its family via
+ the pend_bases deferral - the 60 216 B setup push's pages were demanded
+ individually by the host but suppressed, so the entry stayed unreadable
+ for the whole generation (r1396: entry 8 unreadable=1 on all gens while
+ its sibling entries read fine). The anchor VA is the host's own GPFIFO
+ entry VA: when the client maps the pushbuffer at the same VA (rw-s
+ /dev/nvidia mappings - the same premise as the r586 single-page pagemap
+ fallback proven for the non-family draws), a present page IS the
+ translation the host needs; no content gate and no family learn (so no
+ k/(area,adj) risk, no r1120 poisoning class). Partial presence is fine:
+ the anchor resend (~2 s) re-tries and the missing pages heal late.
+ """
+ pfd = os.open('/proc/%d/pagemap' % pid, os.O_RDONLY)
+ try:
+ sub = {}
+ vpg = ev & ~0xFFF
+ end = vpg + ((off + ln + 0xFFF) // 0x1000) * 0x1000
+ scan_range(pfd, vpg, end, sub)
+ if not sub:
+ dbg('strict-pagemap: 0x%x no present page (%u pages)'
+ % (vpg, (end - vpg) >> 12))
+ return False
+ for v, p in sorted(sub.items()):
+ out.append('0x%x,0x%x,1\n' % (v, p))
+ dbg('strict-pagemap: 0x%x -> %u/%u pages pinned'
+ % (vpg, len(sub), (end - vpg) >> 12))
+ return True
+ finally:
+ os.close(pfd)
+
+
def scan_vmas(fd, pid, out):
"""Present pages of the client's high-VA nvidia//dev/zero mappings.
@@ -2522,6 +2558,27 @@ def main():
ok = False
if ok:
got = got2
+ if not ok and pid and eln:
+ # SESSION 153-r1397: a failed content parse must
+ # not make the anchor's pages (and, via
+ # pend_bases, every loose demand VA of its
+ # family) unpinnable. Fall back to the direct
+ # client-pagemap window pin - the VA is the
+ # host's own entry VA, so a present page is by
+ # definition its translation (see
+ # _pagemap_window_pin). This un-deadlocks the
+ # family: on success the anchor counts as
+ # resolved and the deferral lifts; on failure
+ # the 'strict-pagemap:' line says the pages are
+ # not client-pagemap-present (kernel-resident).
+ got2 = []
+ try:
+ ok = _pagemap_window_pin(pid, ev, eoff, eln,
+ got2)
+ except Exception:
+ ok = False
+ if ok:
+ got = got2
if ok and got:
lines.extend(got)
for g in got: