summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c76
1 files changed, 68 insertions, 8 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index c04ae70..8c1f558 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -19248,6 +19248,26 @@ static u32 gsp_phys_gr_mme_prelude_h;
static u32 gsp_phys_gr_mme_pre_full_dump;
/*
+ * CONT-118: one-launch-delay release for the real CALL runs. The known
+ * poison class is the first calls-kept launch after a fresh split pack
+ * completes (the r1359 half-loaded-IR race): the drain-completing carrier
+ * holds itself (the r1222 clause), but the very next window would run the
+ * real calls against a program whose carrier only just executed. With this
+ * knob that first post-latch launch is held too - it arms the release - so
+ * the real calls resume one full launch AFTER the completing carrier in
+ * every case (the r1443b first-generation shape, reproduced for recreated
+ * generations too). Default 1; A/B with 0 to release on the first
+ * post-latch launch (legacy behavior).
+ */
+static u32 gsp_phys_gr_mme_release_gen;
+static u32 gsp_phys_gr_mme_release_h;
+static bool gsp_phys_rmcall_gr_mme_hold_settle = true;
+module_param_named(sema_gl_mme_hold_settle,
+ gsp_phys_rmcall_gr_mme_hold_settle, bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_hold_settle,
+ "CONT-118: hold real CALL runs for one extra launch after a generation's split prelude latches (default 1; 0 = release on the first post-latch launch)");
+
+/*
* SESSION 153-CONTINUED-107: readback-failure counter + give-up bound for
* the load-only starvation (see the mme_load_only comment). 0 = unlimited;
* default 24.
@@ -19272,6 +19292,12 @@ static void gsp_phys_gr_mme_iram_gate_fail(void)
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);
+ /*
+ * CONT-118: residency is unproven again, so a settled release armed
+ * for this generation is void; the re-emission re-earns it.
+ */
+ WRITE_ONCE(gsp_phys_gr_mme_release_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_release_h, 0);
}
module_param_named(sema_gl_mme_iram_gate_max,
@@ -20032,13 +20058,13 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
*p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM << 29) |
(1u << 16) | (0x3460u >> 2);
*p++ = sv;
- if (mme_seed_log < 16u) {
+ if (mme_seed_log < 64u) {
mme_seed_log++;
pr_info("vgsp-gr: MME-SEED scratch 0x18 <- 0x%08x (va=0x%llx xlat=%u) h=0x%x push=0x%llx\n",
sv, va, xl, req->h_object,
req->push_va);
}
- } else if (mme_seed_log < 16u) {
+ } else if (mme_seed_log < 64u) {
mme_seed_log++;
pr_info("vgsp-gr: MME-SEED no value (client 0x3460 not seen yet; set sema_gl_mme_seed_val) h=0x%x\n",
req->h_object);
@@ -20094,7 +20120,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
<< 29) |
(1u << 16) | (0x3464u >> 2);
*p++ = sv;
- if (mme_state_d19_log < 16u) {
+ if (mme_state_d19_log < 64u) {
mme_state_d19_log++;
pr_info("vgsp-gr: MME-STATE-SEED d19=0x%08x (va=0x%llx xlat=%u) h=0x%x push=0x%llx\n",
sv, va, xl,
@@ -20152,7 +20178,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
<< 29) |
(1u << 16) | (0x3490u >> 2);
*p++ = sv;
- if (mme_state_d24_log < 16u) {
+ if (mme_state_d24_log < 64u) {
mme_state_d24_log++;
pr_info("vgsp-gr: MME-STATE-SEED d24=0x%08x (va=0x%llx xlat=%u) h=0x%x push=0x%llx\n",
sv, va, xl,
@@ -20204,7 +20230,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
<< 29) |
(1u << 16) | (0x3494u >> 2);
*p++ = sv;
- if (mme_state_d25_log < 16u) {
+ if (mme_state_d25_log < 64u) {
mme_state_d25_log++;
pr_info("vgsp-gr: MME-STATE-SEED d25=0x%08x (va=0x%llx xlat=%u) h=0x%x push=0x%llx\n",
sv, va, xl,
@@ -20242,7 +20268,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
((0x3498u + 4u * mi) >> 2);
*p++ = mv[mi];
}
- if (mme_state_seed_log < 16u) {
+ if (mme_state_seed_log < 64u) {
mme_state_seed_log++;
pr_info("vgsp-gr: MME-STATE-SEED d26=%08x d27=%08x d28=%08x d29=%08x d2a=%08x h=0x%x push=0x%llx\n",
mv[0], mv[1], mv[2], mv[3],
@@ -20761,8 +20787,34 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
bool latch_after = (pl_gen == lg &&
req->h_object == lh);
- mme_hold_calls = !latch_after ||
- (pre_words_out && !latch_before);
+ {
+ u32 rg = READ_ONCE(gsp_phys_gr_mme_release_gen);
+ u32 rh = READ_ONCE(gsp_phys_gr_mme_release_h);
+ bool settle = READ_ONCE(
+ gsp_phys_rmcall_gr_mme_hold_settle);
+
+ mme_hold_calls = !latch_after ||
+ (pre_words_out && !latch_before) ||
+ (settle &&
+ !(rg == pl_gen &&
+ rh == req->h_object));
+ /*
+ * CONT-118: a launch that carries no prelude
+ * words but sees a valid latch is the first
+ * settled launch; arm the release so the NEXT
+ * launch runs the real calls. The completing
+ * carrier (pre_words_out > 0) must not arm it
+ * (the r1222 clause already holds it).
+ */
+ if (settle && latch_after && !pre_words_out) {
+ WRITE_ONCE(
+ gsp_phys_gr_mme_release_gen,
+ pl_gen);
+ WRITE_ONCE(
+ gsp_phys_gr_mme_release_h,
+ req->h_object);
+ }
+ }
/*
* CONT-104: also hold while the front-end is not
* settled (the r1359 MME ILLEGAL_OPCODE race; see
@@ -28461,6 +28513,8 @@ gr_page_unmapped:
* run against an unloaded MME.
*/
WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_release_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_release_h, 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 ?
@@ -28793,6 +28847,12 @@ gr_page_unmapped:
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);
+ WRITE_ONCE(
+ gsp_phys_gr_mme_release_gen,
+ 0);
+ WRITE_ONCE(
+ gsp_phys_gr_mme_release_h,
+ 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 {