summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 eada9ae..fe9a02a 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18679,6 +18679,32 @@ static bool gsp_phys_rmcall_gr_3d_reloc(u32 *up_w, u32 *lo_w,
const struct gsp_phys_gr_submit *req,
u32 *n_shadow);
+/*
+ * SESSION 153-CONTINUED-104: FE idle witness for the calls-kept gate.
+ * The r1358/r1359 A/B (identical config; only the fixed-CB seed value
+ * differed) exposes the r1222-class race directly:
+ * - r1358: the calls-kept launch was submitted with the FE settled
+ * (MME-FAST begin grfifo=0x00000001) and the whole real-call window
+ * executed - the macro emissions landed (the wall became the CB read
+ * FAULT_PTE at fixed-CB+0x4000, i.e. the raw constant path now works);
+ * - r1359: the same launch was submitted while the FE still showed
+ * grfifo=0x0d0d1602 (the previous prelude-carrying launch's SA/IR
+ * method runs still draining) and the first macro execution poisoned
+ * with a REAL MME ILLEGAL_OPCODE (ESR 0x404490=0x80000004).
+ * The MME consumes the prelude's SA/IR port runs asynchronously, so a
+ * CALL_MME_MACRO decoded while those writes are in flight fetches
+ * half-loaded IR. Hold the real CALL runs until 0x400504 reads the idle
+ * value (0x00000001): the held launches still retire (the proven-safe
+ * drop shape) and a later window retries; once idle the calls run
+ * against a settled program. Fail-open when BAR0 is unavailable.
+ */
+static bool gsp_phys_gr_fe_idle(void)
+{
+ void __iomem *bar0 = gsp_phys_gpu_bar0();
+
+ return !bar0 || ioread32(bar0 + 0x00400504u) == 0x00000001u;
+}
+
static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
const struct gsp_phys_gr_submit *req,
const u32 *qmd, u64 qmd_va,
@@ -18721,6 +18747,7 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
bool emit_prelude = false;
bool pre_done = false;
bool mme_hold_calls = false;
+ bool mme_hold_fe_busy = false;
bool latch_before = false;
u32 pre_words_out = 0;
const u32 *pl = NULL;
@@ -19573,6 +19600,16 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
mme_hold_calls = !latch_after ||
(pre_words_out && !latch_before);
+ /*
+ * CONT-104: also hold while the front-end is not
+ * settled (the r1359 MME ILLEGAL_OPCODE race; see
+ * gsp_phys_gr_fe_idle). The held launch retires and
+ * a later window retries once 0x400504 reads idle.
+ */
+ if (!mme_hold_calls && !gsp_phys_gr_fe_idle()) {
+ mme_hold_calls = true;
+ mme_hold_fe_busy = true;
+ }
}
/*
* SESSION 153-CONTINUED-63: emit the SA-RAM completion computed
@@ -19858,9 +19895,11 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
r += span;
}
if (held)
- pr_info("vgsp-gr: MME-CALL-HOLD %u word(s) of real CALL runs held (prelude gen=%u not latched for h=0x%x; window=%u->%u) push=0x%llx\n",
+ pr_info("vgsp-gr: MME-CALL-HOLD %u word(s) of real CALL runs held (prelude gen=%u not latched for h=0x%x; window=%u->%u) push=0x%llx%s\n",
held, pl_gen, req->h_object,
- win3d_n, w, req->push_va);
+ win3d_n, w, req->push_va,
+ mme_hold_fe_busy ?
+ " [FE-not-idle (CONT-104)]" : "");
p += w;
} else if (READ_ONCE(gsp_phys_rmcall_gr_mme_nop_pair)) {
/*