summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index f98fa98..1b77ea0 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -45330,6 +45330,39 @@ static void svc_scrub_pass(struct nv_vgpu_device *vgpu)
if (!s)
return;
+ /*
+ * r1665: the guest scanner never registered the scrubber's finish
+ * payload, so the X DDX's vidheap scrub wait (channelFillPbFastScrub
+ * / channelWaitForFinishPayload) never completed. The channel buffer
+ * is pb (0x64000) + GPFIFO (entries*8) + sema (4) + finish (4); the
+ * scrubber's gpfifo VA = pb + pbSize, so hsem = gpfifo_va +
+ * entries*8 and fin = hsem + 4. Resolve them through the learned map
+ * or the VAS walk and register in place.
+ */
+ if (s->userd_ok && !s->pa_ok && s->gpfifo_va && s->entries) {
+ u64 hva = s->gpfifo_va + (u64)s->entries * 8;
+ u64 pa = 0;
+ int ap = SVC_APERTURE_SYS;
+
+ if (svc_lookup(vgpu, hva, &pa, &ap) || !pa) {
+ if (svc_walk_vaspaces(vgpu, hva, &pa, &ap) || !pa)
+ pa = 0;
+ }
+ /* The scrub words are guest RAM; an FB translation is not. */
+ if (pa && svc_ap_of(ap) != SVC_APERTURE_SYS)
+ pa = 0;
+ if (pa) {
+ s->hsem_pa = pa;
+ s->fin_pa = pa + 4;
+ s->pa_ok = true;
+ if (s->log_budget < 16) {
+ s->log_budget++;
+ pr_info("sema-svc: scrub geometry hsem_va=0x%llx fin_va=0x%llx -> hsem_pa=0x%llx fin_pa=0x%llx\n",
+ hva, hva + 4, s->hsem_pa,
+ s->fin_pa);
+ }
+ }
+ }
if (!s->userd_ok || !s->pa_ok || !s->entries) {
/* m112b: silent-return diagnostic (bounded per boot). */
if (s->log_budget < 8) {