summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-02 00:40:05 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-02 00:40:05 -0500
commitdd65a3a3df06567d8491e6e1553245af0b4145aa (patch)
tree6d89a49154be515cfe55bdc82b77227257ed7502 /kernel
parentffaa39f3963e627fb4fe2162629febb4d70d2259 (diff)
downloadopen-iov-dd65a3a3df06567d8491e6e1553245af0b4145aa.tar.gz
open-iov-dd65a3a3df06567d8491e6e1553245af0b4145aa.zip
vgsp: CONT-106 - IR-word register FIX: every past info2_ir= read 0x404498=NV_PGRAPH_PRI_MME_CONFIG, real INFO2/3/4 = 0x40449c/0x4044a8/0x4044ac (tu104 dev_graphics_nobundle.h), fixed in gsp_phys_mme_fast_sample/mme_regs_log/fault_regs_log/gr_state_rb_log/sked sample[17]/reg-probe; MME-FAST budget 48->256 launches; sema_mme_post_ms post-timeout re-spin (2000/12000/20000); DS-FAST per-stage SPH/region snapshot at DS latch transition + DS-FAST2 report-mask clear 0x405844/c; MME_STATUS_MACRO 0x4044b4 - DECISIVE: at trap PC 0x364 (macro 57 entry) MME fetched IR words are ZERO (MME-FAST info=10000364 pc_valid=1 pc=868 mac=0x0 ir=00000000,00000000,00000000; MME-REGS timeout esr=80000000 pc=868 ir zeros) NOT the golden group 0x00000003,0x1a05834a,0x31c28300 - host-sided pack verified verbatim CONT-105; IRAM debug port 0x4044d0 also reads zero at 0x364 while r1364 same port read golden first words at PC=0 (port real); DS-FAST first-sight: ds a2040a00->badf1201 poison floods whole PRI incl macro-status=badf1201(mpc=513 run=1), clears ~1ms later; SPH bind falsified as DS wall (bind=0 r1364/65/68 poison SPH10+18 a2040800/a2040a00 M_PIPE_STAGE=VSA|PS vs bind=1 r1363 same); trap timing r1367: ILLEGAL_OPCODE relayed +14.0s after GR LAUNCH FAILED timeout 1500ms yet GUEST GR LAUNCH OK elapsed_ms=35870 ok=7 block completes gr_swrel=0 engine-authored release; GATE1 black 0/901 - next: after each prelude pack read back IRAM via 0x4044d0 (IRAM_PC<<15|RD=2 data in INFO4/3/2) and re-emit/gate pack until IRAM reads back golden words at slot entries (prime suspect: 0x114 pack writes issued while PRI block poisoned, capturable at every DS fault); once fetch at 0x364 returns golden words ILLEGAL_OPCODE vanishes and macro 57 completes - SESSION 153 r1364-r1368
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c171
1 files changed, 155 insertions, 16 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 0764e1b..a94bbef 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -5114,18 +5114,21 @@ static const char *gsp_phys_pbdma_type_name(u32 t)
*/
static void gsp_phys_mme_regs_log(void __iomem *bar0, const char *tag)
{
- u32 esr, info, info2, trapped;
+ u32 esr, info, info2, info3, info4, trapped;
if (!bar0)
return;
esr = ioread32(bar0 + 0x00404490u);
info = ioread32(bar0 + 0x00404494u);
- info2 = ioread32(bar0 + 0x00404498u);
+ /* SESSION 153-CONTINUED-106: INFO2 is 0x40449c (0x404498 is CONFIG). */
+ info2 = ioread32(bar0 + 0x0040449cu);
+ info3 = ioread32(bar0 + 0x004044a8u);
+ info4 = ioread32(bar0 + 0x004044acu);
trapped = ioread32(bar0 + 0x00400704u);
- pr_warn("vgsp-gr: MME-REGS %s esr=%08x(pc_valid=%u illegal=%u miss=%u extra=%u) pc=%u macro_addr=0x%x info2_ir=%08x trapped=%08x\n",
+ pr_warn("vgsp-gr: MME-REGS %s esr=%08x(pc_valid=%u illegal=%u miss=%u extra=%u) pc=%u macro_addr=0x%x ir=%08x,%08x,%08x trapped=%08x\n",
tag, esr, (info >> 28) & 1u, (esr >> 2) & 1u,
(esr >> 0) & 1u, (esr >> 1) & 1u, info & 0xfffu,
- (info >> 12) & 0xffu, info2, trapped);
+ (info >> 12) & 0xffu, info2, info3, info4, trapped);
}
/*
@@ -5150,6 +5153,19 @@ MODULE_PARM_DESC(sema_mme_fast_ms,
"Spin-sample the MME fault registers right after each GR launch doorbell for this many ms, logging every transition before the GSP-RM clears them (0 = off; default 400)");
/*
+ * SESSION 153-CONTINUED-106: post-timeout re-spin. The r1363 chronology
+ * shows the MME ILLEGAL_OPCODE relay arriving up to ~2.6 s AFTER the sem
+ * wait failed (launch failed 403088.34, ILLEGAL_OPCODE relayed 403090.96);
+ * every launch-window spin had already ended, so the latch was never seen
+ * with its INFO/IR. This bounded second spin runs on the first timeout
+ * exits of a boot, exactly where the r1363 trap sat.
+ */
+static u32 gsp_phys_mme_post_ms = 2000u;
+module_param_named(sema_mme_post_ms, gsp_phys_mme_post_ms, uint, 0644);
+MODULE_PARM_DESC(sema_mme_post_ms,
+ "Post-timeout MME fault-register re-spin length in ms on the first GR launch-timeout exits (0 = off; default 2000)");
+
+/*
* SESSION 153-CONTINUED-83: store-side emission forensics.
*
* The store wall: draws retire but `output retirement wait: 0/N pages
@@ -5261,16 +5277,24 @@ static void gsp_phys_store_side_log(void __iomem *bar0, const char *tag,
}
static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag,
- u32 h_object)
+ u32 h_object, u32 ms_override)
{
static u32 fast_boot_n;
- u32 ms = READ_ONCE(gsp_phys_mme_fast_ms);
+ u32 ms = ms_override ? ms_override : READ_ONCE(gsp_phys_mme_fast_ms);
u32 esr_p, ds_p, gf_p, tr_p, n = 0;
u32 fed0_p, fed1_p;
+ u32 ds_log_n = 0;
ktime_t t_end;
bool poisoned = false;
- if (!bar0 || !ms || fast_boot_n >= 48u)
+ /*
+ * SESSION 153-CONTINUED-106: the budget was 48, which a beef-lane boot
+ * with the wedged-engine relaunch train exhausts long before the
+ * first MME trap is relayed (r1363: 27 launch spins used by +300 s,
+ * trap traffic still arriving). Raised so every beef-family launch
+ * of a diagnostic boot keeps its spin.
+ */
+ if (!bar0 || !ms || fast_boot_n >= 256u)
return false;
/*
* Beef-family channels get the full budget (the draw-class windows
@@ -5308,10 +5332,29 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag,
fed0 != fed0_p || fed1 != fed1_p) {
if (n < 12u) {
u32 info = ioread32(bar0 + 0x00404494u);
- u32 info2 = ioread32(bar0 + 0x00404498u);
+ /*
+ * SESSION 153-CONTINUED-106: the IR word
+ * registers are 0x40449c (INFO2), 0x4044a8
+ * (INFO3), 0x4044ac (INFO4). The old read at
+ * 0x404498 was NV_PGRAPH_PRI_MME_CONFIG
+ * (RW), which is why every "info2_ir" line so
+ * far showed the shadow-filter enable, not the
+ * rejected instruction.
+ */
+ u32 info2 = ioread32(bar0 + 0x0040449cu);
+ u32 info3 = ioread32(bar0 + 0x004044a8u);
+ u32 info4 = ioread32(bar0 + 0x004044acu);
u32 mmeir = ioread32(bar0 + 0x0040a630u);
u32 mmeir1 = ioread32(bar0 + 0x0040a634u);
u32 mmedata = ioread32(bar0 + 0x00400708u);
+ /*
+ * SESSION 153-CONTINUED-106: the MME's own
+ * macro PC/state at the transition instant
+ * (0x4044b4: PC 11:0, MACRO 19:12, RUNNING
+ * 20) - the "is the MME mid-macro at the
+ * trap" witness.
+ */
+ u32 mmemac = ioread32(bar0 + 0x004044b4u);
/*
* r1151 (SESSION 153-CONTINUED-72):
@@ -5324,11 +5367,12 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag,
* the launch; slot 1 is the second
* lane of the same record set.
*/
- pr_warn("vgsp-gr: MME-FAST %s h=0x%x esr %08x->%08x info=%08x(pc_valid=%u pc=%u mac=0x%x) info2_ir=%08x ds %08x->%08x grfifo %08x->%08x trap=%08x data=%08x fed=%08x,%08x (pc0=%u mac0=0x%x gen0=%u) fe1=%08x (pc1=%u mac1=0x%x gen1=%u)\n",
+ pr_warn("vgsp-gr: MME-FAST %s h=0x%x esr %08x->%08x info=%08x(pc_valid=%u pc=%u mac=0x%x) ir=%08x,%08x,%08x ds %08x->%08x grfifo %08x->%08x trap=%08x data=%08x fed=%08x,%08x (pc0=%u mac0=0x%x gen0=%u) fe1=%08x (pc1=%u mac1=0x%x gen1=%u)\n",
tag, h_object, esr_p, esr,
info, (info >> 28) & 1u,
info & 0xfffu,
- (info >> 12) & 0xffu, info2,
+ (info >> 12) & 0xffu,
+ info2, info3, info4,
ds_p, ds, gf_p, gf, tr,
mmedata, mmeir, mmeir1,
mmeir & 0xfffu,
@@ -5338,6 +5382,82 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag,
fed1 & 0xfffu,
(fed1 >> 12) & 0x3ffu,
(fed1 >> 31) & 1u);
+ pr_warn("vgsp-gr: MME-FAST %s h=0x%x macro-status=%08x(mpc=%u mac=0x%x run=%u)\n",
+ tag, h_object, mmemac,
+ mmemac & 0xfffu,
+ (mmemac >> 12) & 0xffu,
+ (mmemac >> 20) & 1u);
+ }
+ /*
+ * SESSION 153-CONTINUED-106: when the DS latch CHANGES
+ * into a fault (the SPH validation miss at draw
+ * dispatch), read the per-stage SPH_INFO START/UPPER
+ * and PROGRAM_REGION pair IMMEDIATELY - the FECS
+ * clears the whole block within ~1 ms (r1364:
+ * 404004.338 poison seen, 404004.339 clean), so this
+ * is the only in-flight window that names the VA each
+ * failing stage fetched.
+ */
+ if (ds != ds_p && (ds & 0x7fffffffu) && ds_log_n < 8u) {
+ ds_log_n++;
+ u32 s0 = ioread32(bar0 + 0x00405c00u);
+ u32 s1 = ioread32(bar0 + 0x00405c04u);
+ u32 s2 = ioread32(bar0 + 0x00405c08u);
+ u32 s3 = ioread32(bar0 + 0x00405c0cu);
+ u32 s4 = ioread32(bar0 + 0x00405c10u);
+ u32 s5 = ioread32(bar0 + 0x00405c14u);
+ u32 u0 = ioread32(bar0 + 0x00405c24u);
+ u32 u1 = ioread32(bar0 + 0x00405c28u);
+ u32 u2 = ioread32(bar0 + 0x00405c2cu);
+ u32 u3 = ioread32(bar0 + 0x00405c30u);
+ u32 u4 = ioread32(bar0 + 0x00405c34u);
+ u32 u5 = ioread32(bar0 + 0x00405c38u);
+ u32 rr_a = ioread32(bar0 + 0x00405c1cu);
+ u32 rr_b = ioread32(bar0 + 0x00405c20u);
+
+ pr_warn("vgsp-gr: DS-FAST %s h=0x%x ds %08x->%08x stage=%08x,%08x,%08x,%08x,%08x,%08x upper=%02x,%02x,%02x,%02x,%02x,%02x region=%08x,%08x esr=%08x\n",
+ tag, h_object, ds_p, ds,
+ s0, s1, s2, s3, s4, s5,
+ u0 & 0xffu, u1 & 0xffu, u2 & 0xffu,
+ u3 & 0xffu, u4 & 0xffu, u5 & 0xffu,
+ rr_a, rr_b,
+ ioread32(bar0 + 0x00404490u));
+ /*
+ * SESSION 153-CONTINUED-106: the pending DS
+ * report poisons the whole PRI block
+ * (every register reads 0xbadf1201 - the
+ * first-capture above shows exactly that).
+ * Clear the report masks and re-read: the
+ * CONT-91 rule says a DS miss with the masks
+ * cleared latches without the poison, so the
+ * per-stage SPH snapshot should become
+ * readable.
+ */
+ {
+ u32 m0 = ioread32(bar0 + 0x00405844u);
+ u32 m2 = ioread32(bar0 + 0x0040584cu);
+
+ iowrite32(0u, bar0 + 0x00405844u);
+ iowrite32(0u, bar0 + 0x0040584cu);
+ udelay(80);
+ pr_warn("vgsp-gr: DS-FAST2 %s h=0x%x masks=%08x/%08x ds_after=%08x stage=%08x,%08x,%08x,%08x,%08x,%08x upper=%02x,%02x,%02x,%02x,%02x,%02x region=%08x,%08x\n",
+ tag, h_object, m0, m2,
+ ioread32(bar0 + 0x00405840u),
+ ioread32(bar0 + 0x00405c00u),
+ ioread32(bar0 + 0x00405c04u),
+ ioread32(bar0 + 0x00405c08u),
+ ioread32(bar0 + 0x00405c0cu),
+ ioread32(bar0 + 0x00405c10u),
+ ioread32(bar0 + 0x00405c14u),
+ ioread32(bar0 + 0x00405c24u) & 0xffu,
+ ioread32(bar0 + 0x00405c28u) & 0xffu,
+ ioread32(bar0 + 0x00405c2cu) & 0xffu,
+ ioread32(bar0 + 0x00405c30u) & 0xffu,
+ ioread32(bar0 + 0x00405c34u) & 0xffu,
+ ioread32(bar0 + 0x00405c38u) & 0xffu,
+ ioread32(bar0 + 0x00405c1cu),
+ ioread32(bar0 + 0x00405c20u));
+ }
}
n++;
esr_p = esr;
@@ -5539,7 +5659,8 @@ static void gsp_phys_fault_regs_log(u32 except_type)
frl_n++;
esr = ioread32(bar0 + 0x00404490u);
info = ioread32(bar0 + 0x00404494u);
- info2 = ioread32(bar0 + 0x00404498u);
+ /* SESSION 153-CONTINUED-106: INFO2 is 0x40449c (0x404498 is CONFIG). */
+ info2 = ioread32(bar0 + 0x0040449cu);
ds = ioread32(bar0 + 0x00405840u);
ds2 = ioread32(bar0 + 0x00405848u);
for (si = 0; si < 6u; si++)
@@ -22232,7 +22353,8 @@ static noinline void gsp_phys_gr_state_rb_log(u32 h_object)
fed3 = ioread32(bar0 + 0x0040a63cu);
esr = ioread32(bar0 + 0x00404490u);
info = ioread32(bar0 + 0x00404494u);
- ir2 = ioread32(bar0 + 0x00404498u);
+ /* SESSION 153-CONTINUED-106: INFO2 is 0x40449c (0x404498 is CONFIG). */
+ ir2 = ioread32(bar0 + 0x0040449cu);
trap = ioread32(bar0 + 0x00400704u);
data = ioread32(bar0 + 0x00400708u);
ds = ioread32(bar0 + 0x00405840u);
@@ -24883,6 +25005,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
u8 *qmd_dst_mem = NULL;
u32 qmd_rel_off = 0, ch_rel_off = 0;
u32 poll = 0, w0 = 0, w1 = 0, grpoll_n = 0;
+ static u32 post_spin_n;
bool sem_gated = false;
static u32 sked_prev[28];
static u32 sked_sample[28];
@@ -27173,7 +27296,7 @@ gr_page_unmapped:
*/
if (stream3d && bar0)
fast_poison = gsp_phys_mme_fast_sample(bar0, "launch",
- req->h_object);
+ req->h_object, 0);
poll_start_us = (u32)ktime_to_us(ktime_get());
deadline = jiffies + msecs_to_jiffies(poll_ms);
@@ -27218,7 +27341,8 @@ gr_page_unmapped:
* The DS shader-program-header error latch (0x405840),
* the MME exception latch (0x404490) with its PC/macro
* address (0x404494) and instruction register
- * (0x404498) are cleared by the real RM within ~ms of
+ * (0x40449c, fixed in SESSION 153-CONTINUED-106) are
+ * cleared by the real RM within ~ms of
* the fault, so the post-timeout reads are all clean.
* Sampling them every poll tick records the faulting
* values at the first change.
@@ -27226,7 +27350,8 @@ gr_page_unmapped:
sked_sample[14] = ioread32(bar0 + 0x00405840u);
sked_sample[15] = ioread32(bar0 + 0x00404490u);
sked_sample[16] = ioread32(bar0 + 0x00404494u);
- sked_sample[17] = ioread32(bar0 + 0x00404498u);
+ /* SESSION 153-CONTINUED-106: INFO2 0x40449c (was CONFIG). */
+ sked_sample[17] = ioread32(bar0 + 0x0040449cu);
/*
* SESSION 153-CONTINUED-52: the PBDMA host-software
* METHOD latch (NV_PPBDMA_METHOD0 0x4000c0: ADDR
@@ -27542,6 +27667,20 @@ gr_page_unmapped:
gsp_phys_gr_fetch_miss_log(req->h_object, &sub,
"timeout");
/*
+ * SESSION 153-CONTINUED-106: the r1363 trap sat in the
+ * ~2.6 s window AFTER this timeout (launch failed
+ * 403088.34, ILLEGAL_OPCODE relayed 403090.96). Re-spin
+ * once here, bounded to the first few timeouts of the
+ * boot, so the latch is caught at first sight with its
+ * INFO/IR word instead of being missed between spins.
+ */
+ if (gsp_phys_mme_post_ms && post_spin_n < 8u) {
+ post_spin_n++;
+ (void)gsp_phys_mme_fast_sample(bar0, "post",
+ req->h_object,
+ gsp_phys_mme_post_ms);
+ }
+ /*
* F4-b: one-shot deposit readback at the FIRST timeout
* (the old post-mortem only ran after attempt 3, which
* a recovered launch never reached). Reading the
@@ -31519,7 +31658,7 @@ static int gsp_phys_reg_probe_show(struct seq_file *m, void *unused)
0x00404494u);
(void)gsp_phys_reg_probe_line(m, bar0,
"PGRAPH_PRI_MME_HWW_ESR_INFO2",
- 0x00404498u);
+ 0x0040449cu);
fe_chip_def = gsp_phys_reg_probe_line(m, bar0, "FE_CHIP_DEF_INFO",
0x00404030u);
fe_go_idle = gsp_phys_reg_probe_line(m, bar0, "FE_GO_IDLE_INFO",