summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-30 18:59:02 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-30 18:59:02 -0400
commit837d640e2e00c5bfdec610087c0ab12cd9726177 (patch)
tree769af1d8ac722e198f3d1f3f9f9b20640726f178 /kernel/gsp_phys_booter.c
parent94d10b71781d52d52a40a6ebbf33cbb862931e73 (diff)
downloadopen-iov-837d640e2e00c5bfdec610087c0ab12cd9726177.tar.gz
open-iov-837d640e2e00c5bfdec610087c0ab12cd9726177.zip
vgsp: 3D flush gate fix (built-in chunk bound, not bisect knob), pushzero zero-content rescue (probe PROMOTE_CTX, src=9), CHUNK1 dump, SET_INDEX_BUFFER+vertex-stream collection; publish GPFIFO entry at engine GP_GET (PUT-GET=1); win_drop 0x parser fix - beef chunks still PBDMA-stop at 0x1160 attr run (hdr=20030458 INC m=0x1160 cnt=3) while X retires ch_rel=0xc0ffee02 same boot - SESSION 153 r1034-r1041
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index b7476b3..d78e0df 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -15260,7 +15260,35 @@ static int gsp_phys_rmcall_publish_locked(void __iomem *bar0, u64 pb_gpu_va,
gpput, GSP_PHYS_RMCALL_GPFIFO_ENTRIES);
return -EIO;
}
- slot = gpput;
+ /*
+ * SESSION 153-CONTINUED-46: publish at the ENGINE's GP_GET, not at
+ * the raw GP_PUT. Observed on every stalled beef boot: the USERD
+ * drifts (GPGet=5 while GPPut cycles 1/2/4/7 - the engine's GET ran
+ * past the publisher's PUT, e.g. after a wrapped or otherwise
+ * deranged ring), and a ring is MODULO: PUT < GET numerically means
+ * (PUT-GET) mod ENTRIES pending entries - hundreds - so the PBDMA
+ * walks stale slots, executes garbage method blocks and the launch
+ * never retires (the trapped=0x8000022c / no-dispatch class). The
+ * forwarded channel is strictly single-inflight, so the engine's
+ * GET names exactly the next free slot: write our entry there and
+ * advance PUT to GET+1 so the PBDMA sees exactly one pending entry -
+ * ours. When GP_GET is out of range (uninitialised USERD), fall back
+ * to the old PUT-derived slot.
+ */
+ slot = (gpget < GSP_PHYS_RMCALL_GPFIFO_ENTRIES) ? gpget : gpput;
+ {
+ static u32 slotfix_log;
+
+ if (gpget != gpput && slotfix_log < 64) {
+ slotfix_log++;
+ pr_info("vgsp-boot: rm-call: publish at engine GP_GET=%u (raw GP_PUT=%u was %s; pending-would-be=%u)\n",
+ gpget, gpput,
+ gpput == gpget ? "equal" :
+ (gpput > gpget ? "ahead" : "behind"),
+ (gpput + GSP_PHYS_RMCALL_GPFIFO_ENTRIES - gpget) %
+ GSP_PHYS_RMCALL_GPFIFO_ENTRIES);
+ }
+ }
/*
* e0: bits 31:2 hold the GET field, which itself is (fetch address
@@ -15287,8 +15315,10 @@ static int gsp_phys_rmcall_publish_locked(void __iomem *bar0, u64 pb_gpu_va,
* GP_PUT advances on the client sysmem USERD chunk, which is the
* channel's hardware USERD because the params carry that same chunk;
* the host write is therefore what the engine polls (cycle 21).
+ * CONT-46: PUT = slot+1 (slot was chosen from GP_GET above), so the
+ * single new entry is the entire pending set.
*/
- put_unaligned_le32((gpput + 1) % GSP_PHYS_RMCALL_GPFIFO_ENTRIES,
+ put_unaligned_le32((slot + 1) % GSP_PHYS_RMCALL_GPFIFO_ENTRIES,
(u8 *)userd + gsp_phys_rmcall_userd_ctl_off() + GSP_PHYS_RMCALL_USERD_GPPUT_OFF);
/*
* Doorbell value: workSubmitToken = ((runlistId << 16) & 0x7f00000) |
@@ -19601,6 +19631,15 @@ static bool gsp_phys_rmcall_gr_win_drop_match(u32 addr)
while (*p == ' ' || *p == ',' || *p == ':' || *p == ';')
p++;
+ /*
+ * SESSION 153-CONTINUED-46: accept an optional 0x/0X prefix.
+ * The original parser scanned hex digits only, so the natural
+ * "0x3810,0x39c8" input parsed as 0 (the 'x' ended the digit
+ * run after the leading '0') and silently never matched -
+ * cost a full bisect round.
+ */
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p += 2;
for (;;) {
char c = *p;
u32 d;