From 185324dd8d921281dc32e882884fb2150b429e85 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 10 Nov 2026 06:43:39 -0500 Subject: vgsp: family-aware GR ring scan + GR completion event post (CONT.400) 1. svc_gr_ram_ring_scan: the direct-GL client's kernel channels live in the RM low aperture (ring 0x4020000, pushes 0x4000000/0x4001004/0x4250000/ 0xcae2894). The scan rejected every one of them: entry VAs below SEMA_VA_LO (0x100000000), entry-1 outside +/-1MB of the ring, and the 1MB-alignment gate in svc_gr_entry_plausible. For the low family (gpfifo_va in [0x4000000,0x10000000) or h_object 0xbeef0xxx) accept any low-aperture push VA, drop the 1MB alignment to 4 bytes, and use the low aperture as the upper bound. High-family rules unchanged. 2. GR completion event: a launch completion is an RM event edge, not only a memory word. The guest client waits in the RM software event queue (NV_ESC_RM_GET_EVENT_DATA), populated only by a GSP 0x1003 EVENT_POST_EVENT record. Post it via gsp_rm_post_channel_event_force() after the release is visible, on both the hold success edge and the software/failure edge. Diagnostics added: VAS-PROMOTE walk results and the RING-VAS probe. Open (see handoff CONT.400): the beef ring VA is still not mapped by any registered VAS, not at guest PA 0x4020000, not at vidmem 0x4020000. The guest never publishes the channel's effective TSG/device-default VAS via SET_PAGE_DIRECTORY; all registered VASes come from COPY_SERVER_PDES. Guest screen is 100% black; glxgears 0.2 FPS. --- kernel/gsp_sema_service.c | 84 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index d2a1ffc..5c2001b 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -28152,6 +28152,10 @@ static bool svc_gr_ram_ring_scan(struct nv_vgpu_device *vgpu, * match no matter how good the entry contents were. */ u32 eoff = (u32)(ch->gpfifo_va & (SEMA_PAGE_SIZE - 1)); + /* CONT.400: the GL client's kernel channels use the RM low aperture. */ + bool low = (ch->gpfifo_va >= SVC_LOW_REL_VA_LO && + ch->gpfifo_va < 0x10000000ULL) || + ((ch->h_object & 0xfffff000u) == 0xbeef0000u); int i; unsigned long flags; @@ -28196,11 +28200,29 @@ static bool svc_gr_ram_ring_scan(struct nv_vgpu_device *vgpu, * pushbuffer above the ring on this boot; accept * both sides, still bounded to +/-1 MB of the ring). */ - if (va0 + SVC_GR_RAM_WIN / 2 < ch->gpfifo_va || - va0 > ch->gpfifo_va + SVC_GR_RAM_WIN / 2) - continue; - if (va0 < SEMA_VA_LO || va0 >= SEMA_VA_HI) - continue; + /* + * CONT.400: the direct-GL client's kernel channels live + * in the RM low aperture (ring 0x4020000, pushbuffers + * 0x4000000/0x4001004/0x4250000/0xcae2894). Those push + * VAs are far below SEMA_VA_LO and outside +/-1 MB of + * the ring, so the high-family window below rejected + * every one of them and the ring could never latch - + * the GL draw stream was never decoded. For the low + * family accept any push VA in the low aperture and a + * much wider ring window; keep the high-family rules + * exactly as they were. + */ + if (low) { + if (va0 < SVC_LOW_REL_VA_LO || + va0 >= SVC_LOW_REL_VA_LO + 0x10000000ULL) + continue; + } else { + if (va0 + SVC_GR_RAM_WIN / 2 < ch->gpfifo_va || + va0 > ch->gpfifo_va + SVC_GR_RAM_WIN / 2) + continue; + if (va0 < SEMA_VA_LO || va0 >= SEMA_VA_HI) + continue; + } if (len0 < 4 || len0 > 0x100000) continue; memcpy(&f0, buf + o + eoff + 8, 4); @@ -28215,9 +28237,15 @@ static bool svc_gr_ram_ring_scan(struct nv_vgpu_device *vgpu, * {push=0x1203c0000,len=32}). Never below entry0; * still bounded by the window above the ring. */ - if (va1 < va0 || - va1 > ch->gpfifo_va + SVC_GR_RAM_WIN / 2) - continue; + if (low) { + if (va1 < va0 || + va1 >= SVC_LOW_REL_VA_LO + 0x10000000ULL) + continue; + } else { + if (va1 < va0 || + va1 > ch->gpfifo_va + SVC_GR_RAM_WIN / 2) + continue; + } if (len1 < 4 || len1 > 0x100000) continue; /* @@ -28393,12 +28421,27 @@ static bool svc_gr_entry_plausible(const struct svc_channel *ch, u32 e0, { u64 eva = ((u64)(e1 & 0xff) << 32) | (u64)(e0 & 0xfffffffc); u32 elen = ((e1 >> 10) & 0x1fffff) << 2; + /* + * CONT.400: the low-aperture GL client's pushes are 4-byte granular + * (0x4001004, 0x4250000, 0xcae2894); the 1 MB alignment test below is + * a high-family convention and rejected every one of them. Keep it + * for the high family only. + */ + bool low = (ch->gpfifo_va >= SVC_LOW_REL_VA_LO && + ch->gpfifo_va < 0x10000000ULL) || + ((ch->h_object & 0xfffff000u) == 0xbeef0000u); - if ((eva & 0xfffff) || elen < 4 || elen > 0x10000) + if ((low ? (eva & 0x3u) : (eva & 0xfffffu)) || elen < 4 || + elen > 0x10000) return false; - if ((eva < SEMA_VA_LO || eva >= SEMA_VA_HI) && - !svc_gr_entry_win_ok(ch->gpfifo_va, eva)) + if (low) { + if (eva < SVC_LOW_REL_VA_LO || + eva >= SVC_LOW_REL_VA_LO + 0x10000000ULL) + return false; + } else if ((eva < SEMA_VA_LO || eva >= SEMA_VA_HI) && + !svc_gr_entry_win_ok(ch->gpfifo_va, eva)) { return false; + } return true; } @@ -33536,6 +33579,19 @@ static void svc_fwd_hold_gr_release(struct nv_vgpu_device *vgpu, svc_gr_sw_release(vgpu, ch ? ch->h_object : 0, svc_fwd_req.gr_rel_va, svc_fwd_req.gr_rel_payload); + /* + * CONT.400: a GR launch completion is an RM event edge, not only a + * memory word. The guest client waits in the RM software event queue + * (NV_ESC_RM_GET_EVENT_DATA), populated only by a GSP 0x1003 + * EVENT_POST_EVENT record. The release word alone leaves that waiter + * polling at its ~1 s retry cadence - the observed 0.2 FPS. Post the + * event AFTER the release is visible so the guest wakes immediately. + */ + if (ch && ch->h_object) { + gsp_rm_post_channel_event_force(vgpu, ch->h_object); + svc.post_hint_until = + jiffies + msecs_to_jiffies(SVC_POST_HINT_MS); + } } /* @@ -33730,6 +33786,12 @@ static void svc_fwd_outcome_check(struct nv_vgpu_device *vgpu) svc_fwd_req.gr_rel_va, svc_fwd_req.gr_rel_payload); svc.fwd_gr_stall_swrel++; + /* CONT.400: wake the RM-event waiter on this failure edge too. */ + if (svc_fwd_req.gr_h_object) { + gsp_rm_post_channel_event_force(vgpu, svc_fwd_req.gr_h_object); + svc.post_hint_until = + jiffies + msecs_to_jiffies(SVC_POST_HINT_MS); + } if (svc_fwd_req.hw_rc == -EBADMSG) { /* * SESSION 153-CONTINUED-60: the backend skipped an all-zero 3D -- cgit v1.2.3