summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-10 06:43:39 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-10 06:43:39 -0500
commit185324dd8d921281dc32e882884fb2150b429e85 (patch)
tree1babfb8c4498bb8e0547d757c4c7facc4a9ceeef /kernel
parentd496a19ed03cb173432105a3f300fc654d69876d (diff)
downloadopen-iov-185324dd8d921281dc32e882884fb2150b429e85.tar.gz
open-iov-185324dd8d921281dc32e882884fb2150b429e85.zip
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.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c84
1 files changed, 73 insertions, 11 deletions
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