diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 5c638a5..12c6afd 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -24714,7 +24714,7 @@ static bool svc_fb_userd_pristine_scan(struct nv_vgpu_device *vgpu, if (!base || !ch->gpfifo_entries) return false; - lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x2000000ULL); + lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x20000000ULL); for (off = 0; off + 0x100 <= lim; off += 0x1000) { u32 hp, hg; @@ -25488,10 +25488,18 @@ ce_fb_scan: * unwritten hole is not a window * failure for a CE channel. */ - if (!eva && !elen && ch->engine_type) + if (!eva && !elen && + (ch->engine_type || + (ch->h_object & 0xfffff000u) == + 0xbeef0000u)) continue; - if (!eva || !svc_gr_entry_win_ok( - ch->gpfifo_va, eva) || + if (!eva || + (!svc_gr_entry_win_ok( + ch->gpfifo_va, eva) && + !((ch->h_object & 0xfffff000u) == + 0xbeef0000u && + eva >= SEMA_VA_LO && + eva < SEMA_VA_HI)) || elen < 4 || elen > 0x100000) { ok = false; rck = (int)k; @@ -28592,8 +28600,13 @@ static bool svc_gr_ram_userd_scan(struct nv_vgpu_device *vgpu, eva = ((u64)(a1 & 0xff) << 32) | (u64)(a0 & 0xfffffffc); elen = ((a1 >> 10) & 0x1fffff) << 2; + if (!eva && !elen && + (ch->h_object & 0xfffff000u) == 0xbeef0000u) + continue; if (!eva || - !svc_gr_entry_win_ok(ch->gpfifo_va, eva) || + (!svc_gr_entry_win_ok(ch->gpfifo_va, eva) && + !((ch->h_object & 0xfffff000u) == 0xbeef0000u && + eva >= SEMA_VA_LO && eva < SEMA_VA_HI)) || elen < 4 || elen > 0x100000) { ok = false; break; @@ -40856,6 +40869,48 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) rrc = svc_lookup(vgpu, ch->gpfifo_va, &ring_pa, &ring_ap); + /* + * r1682 (CONT.393): the GL client's GR kernel ring lives in + * the RM low aperture (0x4000000..0xfffffff), an identity- + * mapped kernel window (GPU VA == guest PA). No published + * client VAS directory maps it, so the walk - and every + * ring-gated USERD discovery below - fails with ring_pa=0. + * For the 0xbeef0000 GR family, prove the ring content with a + * raw PA read (PA==VA) and adopt that identity translation. + * Re-run every pass: the ring VA churns, so a new VA simply + * re-proves on the next turn (the stale pin is keyed to the + * old VA and is ignored). + */ + if (rrc && !ch->engine_type && + (ch->h_object & 0xfffff000u) == 0xbeef0000u && + ch->gpfifo_va >= SVC_LOW_REL_VA_LO && + ch->gpfifo_va < 0x10000000ULL) { + u8 e[2 * SVC_GPFIFO_ENTRY_SIZE]; + u32 e0, e1; + + if (!svc_read(vgpu, ch->gpfifo_va, e, sizeof(e))) { + memcpy(&e0, e, 4); + memcpy(&e1, e + 4, 4); + if ((e0 || e1) && + svc_gr_entry_plausible(ch, e0, e1)) { + svc_pin_store(ch->gpfifo_va, + ch->gpfifo_va, + SVC_APERTURE_SYS); + svc_lat_store(ch->gpfifo_va, + ch->gpfifo_va, + SVC_APERTURE_SYS); + ring_pa = ch->gpfifo_va; + ring_ap = SVC_APERTURE_SYS; + rrc = 0; + if (gsp_sema_dbg) + pr_info("vgsp-sema: low-ring identity h=0x%x va=0x%llx\n", + ch->h_object, + (unsigned long long) + ch->gpfifo_va); + } + } + } + if (!rrc) svc_pb_pair(vgpu, ch); if (!rrc && ring_pa) { |
