summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 3a24550..c93ecc9 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -17042,6 +17042,45 @@ static void svc_gr_ring_autopin(struct nv_vgpu_device *vgpu,
return; /* wait until the CE channels are known */
/*
+ * SESSION 148 perf (r858 evidence): the RC-watchdog channel's ring
+ * page sits at (notifier_pa page + 0x400) in EVERY observed boot -
+ * r848: notif 0x11b689420 -> ring 0x11b689400; r853: 0x11b8a6420
+ * -> 0x11b8a6400; r858: 0x102e04420 -> 0x102e04400. The registered
+ * notifier PA is guest truth from the channel alloc, so this
+ * derivation is deterministic; the trusted walk resolved the same
+ * ring 14 s LATE on r858 (77280 registered, 77294 walk) and, on the
+ * failing boots, inside that window the driver's DMA test read
+ * zeros/garbage -> "Failed to initialize DMA" and guest vmap-lock
+ * livelocks followed. Content-gated by the standard candidate probe
+ * (entry0 + USERD validation), so a wrong derivation costs a failed
+ * probe, not a wrong pin.
+ */
+ if (ch->h_object == 0x31415900u && ch->notifier_pa) {
+ u64 rpa = (ch->notifier_pa & ~(u64)(SEMA_PAGE_SIZE - 1)) +
+ 0x400;
+
+ if (svc_gr_ring_candidate(vgpu, ch, rpa, SVC_APERTURE_SYS,
+ &va, &len, &put, &get)) {
+ svc_pin_store(ch->gpfifo_va, rpa, SVC_APERTURE_SYS);
+ svc_lat_store(ch->gpfifo_va, rpa, SVC_APERTURE_SYS);
+ if (ch->userd_reg)
+ ch->userd_ok = true;
+ else {
+ ch->userd_pa = rpa + SVC_GR_USERD_OFF;
+ ch->userd_as = SVC_APERTURE_SYS;
+ ch->userd_ok = true;
+ }
+ svc_gr_ring_base = rpa;
+ set_bit(ch->gr_index, &svc_gr_ring_done);
+ svc_ring_n++;
+ pr_info("sema-chan: auto-pinned GR ring h=0x%x rank=%u va=0x%llx -> pa=0x%llx ap=1 (notifier-derived; entry0 va=0x%llx len=%u put=%u get=%u)\n",
+ ch->h_object, ch->gr_index, ch->gpfifo_va,
+ rpa, va, len, put, get);
+ return;
+ }
+ }
+
+ /*
* Guest truth first: the channel registration carries the USERD
* memdesc base for THIS session's allocation, and the ring sits one
* USERD block before it (observed for every GR channel across