From 9edeefe52936211744fb7f4d37d2ccc3641f8af5 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 11 Nov 2026 18:20:56 -0500 Subject: vgsp: pdb neighbourhood discovery + injected shared-surface pin sync - when a content-verified ring pair is known, also scan a bounded window around every COPY_SERVER_PDES candidate pdb for a root that reproduces the pair; register the found root under the candidate's VAS handle so the channel's own VAS lookup resolves the ring even when the offered pdb is a stale incarnation - the periodic shared-surface watchdog now also honours an operator-injected shared-surface pin (sema_map_add): read lastKickoffRefCount at +0x880 and author it into gpuRefCount at +0x800, forward-only and validated Live receipt (r1780 c14): with the strict shared-surface signature page injected, the pin sync advanced gpuRefCount 1420471 -> 1420488 (== lkr), the DDX idle warning did not repeat, and GZDoom reached V_Init with X alive. Next walls observed: the DDX push-buffer idle wait (W2) at teardown and a guest OOM that kills gzdoom. --- kernel/gsp_sema_service.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index d3f73c4..dcc998b 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -6317,6 +6317,55 @@ MODULE_PARM_DESC(sema_gl_shsurf_kick, #define SVC_GLSHSURF_VA 0x420a00800ULL +/* + * r1780 (CONT.431b): direct sync of an operator-injected shared-surface page + * (sema_map_add). The VAS walk cannot always name the client incarnation, but + * a verified {known shared-surface VA -> page} pin is authoritative: read the + * page's lastKickoffRefCount and author it into gpuRefCount[0] forward-only. + * This is the live unblock for the DDX idle wait when the page has already + * been identified by the strict signature scan. + */ +static void svc_gl_shsurf_pin_sync(struct nv_vgpu_device *vgpu) +{ + u64 lkr = 0, pa = 0; + u32 cur = 0, want; + int ap = SVC_APERTURE_SYS; + static u32 log; + + /* + * svc_pin_lookup_any returns 0 on a hit (Linux convention); try the + * exact VA first, then the page-aligned form the commands use. + */ + if (!svc_pin_lookup_any(SVC_GLSHSURF_VA, &pa, &ap)) { + /* exact VA hit: use its translation */ + } else if (!svc_pin_lookup_any(SVC_GLSHSURF_VA & ~0xfffULL, + &pa, &ap)) { + /* page-aligned hit: use its translation */ + } else { + return; + } + if (svc_read_ap(vgpu, (pa & ~0xfffULL) | 0x880ULL, ap, + &lkr, sizeof(lkr))) + return; + if ((lkr >> 32) || !(lkr & 0xffffffffULL) || + (lkr & 0xffffffffULL) > 0x1000000ULL) + return; + want = (u32)lkr; + if (svc_read_ap(vgpu, (pa & ~0xfffULL) | 0x800ULL, ap, &cur, + sizeof(cur))) + return; + if (cur >= want) + return; + if (svc_write_ap(vgpu, (pa & ~0xfffULL) | 0x800ULL, ap, &want, + sizeof(want))) + return; + if (log < 64) { + log++; + pr_info("sema-gl: shsurf-pin-sync pa=0x%llx cur=%u lkr=0x%llx\n", + pa, cur, lkr); + } +} + static bool svc_gl_shsurf_sync(struct nv_vgpu_device *vgpu, u32 h, u64 va, u32 val) { @@ -31111,6 +31160,62 @@ static void svc_xvas_pdb_discover(struct nv_vgpu_device *vgpu, u64 ring_va, return; } } + /* + * r1780 (CONT.431): the COPY_SERVER_PDES candidates are the only + * known addresses of the client's page-directory incarnations, and + * the correct incarnation is frequently allocated next to an + * offered one (the driver rebuilds the directory in the same pool). + * Scan a bounded window around every candidate pdb for a root that + * reproduces the verified ring pair and register it under the + * candidate's VAS handle, so the channel's own VAS lookup resolves + * the ring even when the offered pdb itself is stale. The walk is + * the proof; a wrong page cannot register. + */ + { + static const u32 cand_ent[] = { 4, 8, 16, 32 }; + u32 ci, ei2; + + for (ci = 0; ci < SVC_VAS_CAND_MAX; ci++) { + u64 base = svc_vas_cand[ci].pdb; + u64 lo, hi, poff; + u32 hvas = svc_vas_cand[ci].h_vaspace; + + if (!base) + continue; + lo = (base > 0x400000ULL) ? base - 0x400000ULL + : 0x1000ULL; + hi = base + 0x400000ULL; + if (hi > svc_pa_max()) + hi = svc_pa_max(); + for (poff = lo & ~0xfffULL; poff < hi; + poff += 0x1000ULL) { + for (ei2 = 0; ei2 < ARRAY_SIZE(cand_ent); + ei2++) { + if (!svc_xvas_try_root(vgpu, poff, + cand_ent[ei2], + false, ring_va, + ring_pa)) + continue; + if (hvas) { + struct sema_vaspace_desc d; + + memset(&d, 0, sizeof(d)); + d.h_vaspace = hvas; + d.pdb = poff; + d.num_entries = cand_ent[ei2]; + d.b_vidmem = false; + d.verified = true; + gsp_sema_service_vaspace_add(&d); + pr_info("sema-svc: VAS 0x%x registered from candidate-neighbourhood pdb=0x%llx entries=%u (ring 0x%llx -> 0x%llx verified)\n", + hvas, poff, + cand_ent[ei2], + ring_va, ring_pa); + } + return; + } + } + } + } } /* @@ -43240,6 +43345,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) if (sva != SVC_GLSHSURF_VA) (void)svc_gl_shsurf_sync(vgpu, 0, SVC_GLSHSURF_VA, 0); + svc_gl_shsurf_pin_sync(vgpu); } } /* Only ever called from the service thread. */ -- cgit v1.2.3