summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 55c2170..43ab00f 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -5358,6 +5358,28 @@ static bool gsp_phys_mme_fast_sample(void __iomem *bar0, const char *tag,
gf_p = ioread32(bar0 + 0x00400504u);
tr_p = ioread32(bar0 + 0x00400704u);
/*
+ * SESSION 153-CONTINUED-109: the poison episode can already be
+ * latched when the sample's FIRST read happens. r1378's first
+ * window+live launch: `MME-FAST begin launch ... esr=badf1201
+ * ds=badf1201 grfifo=badf1201 trap=badf1201` with the very next
+ * read clean (`esr badf1201->80000000 ... grfifo badf1201->
+ * 00000001`). The historical detector only marks `poisoned` when a
+ * POST-entry read shows poison, so the episode was never handed to
+ * the WEDGE-RECOVER decision - no recovery ran, the prelude latch
+ * and live_gen stayed set, and every later calls-bearing window
+ * executed macro 57 against the wiped MME context: sked
+ * `mme_esr=80000004 (ILLEGAL_OPCODE) mme_mac=0x39`, then the FE
+ * parked at pc=513/mac=0xf1 and the stores stopped (0/905 after the
+ * 305-page burst). Treat an entry read of poison as the same
+ * witness; the FECS has already reset the context, so the recovery
+ * (latch clear + cursor rewind + live_gen invalidate) is exactly
+ * what is owed.
+ */
+ if (((gf_p & 0xffff0000u) == 0xbadf0000u) ||
+ ((esr_p & 0xffff0000u) == 0xbadf0000u) ||
+ ((ds_p & 0xffff0000u) == 0xbadf0000u))
+ poisoned = true;
+ /*
* SESSION 153-CONTINUED-84: FE_DECODE_STATE_EX(0)/(1) also drive a
* transition log - the MME's macro/generated witness can flip
* there without touching ESR/DS/grfifo, which is exactly the
@@ -22717,8 +22739,32 @@ gsp_phys_gr_fetch_miss_log(u32 h_object,
pr_info("vgsp-gr: FETCH-WIT %s h=0x%x slot=%u gpget %u->%u %s\n",
tag, h_object, sub->slot, sub->gpget, usr_gpget,
usr_gpget != sub->gpget ? "engine-fetched" :
- "GP_GET-frozen (NOT fetched: parked or over-cap block)");
- WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
+ "GP_GET-frozen (NOT fetched: parked or over-cap block)");
+ /*
+ * SESSION 153-CONTINUED-109: readback-free live promotion on the
+ * timeout path. The poll-break path promotes the generation whose
+ * final prelude part was carried when GP_GET advanced (the engine
+ * consumed the entry). A launch can also time out the w0/w1 release
+ * wait AFTER the engine fetched it (r1377: `FETCH-WIT timeout ...
+ * gpget 5->6 engine-fetched` on the load-only carriers - their
+ * releases only matched ~10 s later through the ladder), and the
+ * historical code cleared pending_gen here, permanently losing the
+ * promotion: live_gen never caught pl_gen, every later launch stayed
+ * window-elided, and the MME never got a calls-bearing launch
+ * (`pc_valid=0` on all samples). Promote on the same GP_GET witness
+ * the break path trusts; only a genuinely unfetched carrier clears.
+ */
+ if (usr_gpget != sub->gpget &&
+ READ_ONCE(gsp_phys_gr_mme_pending_gen)) {
+ pr_info("vgsp-gr: MME-LIVE promote via GP_GET advance (%s) gen=%u h=0x%x\n",
+ tag, READ_ONCE(gsp_phys_gr_mme_pending_gen),
+ h_object);
+ WRITE_ONCE(gsp_phys_gr_mme_live_gen,
+ READ_ONCE(gsp_phys_gr_mme_pending_gen));
+ WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
+ } else {
+ WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
+ }
}
/*
@@ -27913,6 +27959,32 @@ gr_page_unmapped:
* the owed re-preload.
*/
WRITE_ONCE(gsp_phys_gr_mme_pre_emit_off, 0);
+ /*
+ * SESSION 153-CONTINUED-109: rewind the PACK
+ * cursor too (the r1377 deadlock: recovery reset
+ * pre_emit_off but left pack_off at its end, so
+ * the split emitter hit `poff >= maxa` -> can=0
+ * -> packed=1 with zero words on every launch:
+ * `MME-PRELUDE part gen=3 off=0 words=0/3083`
+ * forever, latch never re-set, gates never
+ * release, MME never starts). The gate-fail
+ * path (gsp_phys_gr_mme_iram_gate_fail) already
+ * rewinds both cursor pairs.
+ */
+ WRITE_ONCE(gsp_phys_gr_mme_pack_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_sa, false);
+ /*
+ * SESSION 153-CONTINUED-109: the hard re-arm
+ * wiped the engine context, so the generation
+ * whose carrier executed is no longer resident.
+ * Invalidate it; the re-preload's own GP_GET
+ * advance (readback-free witness) re-promotes
+ * (fetch_miss/poll-break paths). Without this
+ * the stale live_gen would mark a wiped context
+ * live and the next window+calls launch would
+ * run against an unloaded MME.
+ */
+ WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
pr_warn("vgsp-gr: WEDGE-RECOVER after re-arm grfifo=0x%08x (%s); recovery #%u this boot; MME prelude latch cleared (context re-preload owed)\n",
g1,
(g1 & 0xffff0000u) == 0xbadf0000u ?
@@ -28242,6 +28314,9 @@ gr_page_unmapped:
if (!sp_ret) {
WRITE_ONCE(gsp_phys_gr_mme_prelude_gen, 0);
WRITE_ONCE(gsp_phys_gr_mme_pre_emit_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_sa, false);
+ WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
pr_warn("vgsp-gr: PARK-RECOVER #%u warm sem ALIVE after TSG preempt + resched; fresh-entry retries resume push=0x%llx\n",
park_rec_n, req->push_va);
} else {