summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c137
1 files changed, 134 insertions, 3 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index df78841..bfc9149 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -1191,6 +1191,16 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_VA_PB4 (GSP_PHYS_RMCALL_VA_BASE + 4 * GSP_PHYS_PAGE_SIZE)
#define GSP_PHYS_RMCALL_VA_DST (GSP_PHYS_RMCALL_VA_BASE + 0xB000ULL)
#define GSP_PHYS_RMCALL_VA_SEM (GSP_PHYS_RMCALL_VA_BASE + 0xC000ULL)
+/*
+ * eng39: scratch slot for redirected client report-semaphore/notification
+ * targets. The module semaphore page (VA_SEM) holds the ladder's own
+ * release witness at offset 0 and the channel release pair at +4; offset
+ * 0x800 is unused and inside the same always-mapped small PTE, so the
+ * engine's 16-byte notification/semaphore writes land harmlessly there
+ * (see gsp_phys_gr_reportsem_scratch).
+ */
+#define GSP_PHYS_RMCALL_VA_REPORT_SCRATCH \
+ (GSP_PHYS_RMCALL_VA_SEM + 0x800ULL)
/* SESSION 153-CONTINUED-66: CE SRC moved off the pushbuffer's second page. */
#define GSP_PHYS_RMCALL_VA_SRC (GSP_PHYS_RMCALL_VA_BASE + 0x9000ULL)
/* SESSION 153-CONTINUED-66: warm-semaphore probe page (own PTE, no sharing). */
@@ -19384,6 +19394,27 @@ MODULE_PARM_DESC(sema_gl_mme_partial_keep_window,
"Keep the window (calls-held) on a launch that emits only a PART of the packed MME program; only the final-part launch stays a windowless load carrier (default 0 = legacy drop-everything)");
/*
+ * eng39: keep the packed-part cursor across a prelude-generation change when
+ * the packed image is deterministic (golden overlay forced). The multi-part
+ * beef program cannot complete while an interleaved client state push extends
+ * the capture: each capture bumps svc_mme_prelude_gen, the builder's
+ * generation-change edge rewinds gsp_phys_gr_mme_pack_off to 0, and the next
+ * beef window re-emits part 1 (c437: gen=2 part 1692/2799, then the 728-B
+ * state push bumped to gen=5 and the very next part restarted at off=0
+ * 1596/2799 - no completion, no live_gen promote). With
+ * sema_gl_mme_golden_force=1 the overlay overwrites every slot from the
+ * golden library, so the packed image is byte-identical across capture
+ * generations and continuing the cursor is safe. Without the forced overlay
+ * the image depends on the capture and the legacy rewind stays. Default 0
+ * (A/B; enable in params for the beef lane).
+ */
+static bool gsp_phys_rmcall_gr_mme_pack_keep_gen;
+module_param_named(sema_gl_mme_pack_keep_gen,
+ gsp_phys_rmcall_gr_mme_pack_keep_gen, bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_pack_keep_gen,
+ "Keep the packed-part cursor across prelude-generation changes when the golden overlay is forced (deterministic image; lets a multi-part beef program complete across interleaved state captures; default 0)");
+
+/*
* SESSION 153-CONTINUED-107: separate knob for the per-launch chronology
* probe lines. They write the MME debug port DURING a live launch, and the
* first three probe-bearing cycles (r1369..r1371) all parked the engine on
@@ -21001,6 +21032,81 @@ static void gsp_phys_gr_stream_damage_clear(u64 push_va)
}
}
+/*
+ * eng39: client report-semaphore / notification scratch redirect.
+ *
+ * The replayed C597 windows carry the client's own completion methods:
+ * SET_REPORT_SEMAPHORE A..D (0x1b00..0x1b0c) and SET_NOTIFY_A/B + NOTIFY
+ * (0x104/0x108/0x10c). Their target VAs are client-VAS addresses in the
+ * 0x04xxxxxx band (c398: notify 0x41a0020; report-sems 0x41a6bb0,
+ * 0x41a6c30, 0x4238070). The forwarded launch executes on the ladder
+ * channel whose root/PD2/PD1 chain carries the host's guest-scratch PT
+ * pool at PD0 entries 32..79 (VA 0x04000000..), where every PTE starts
+ * invalid until a P6b guest-copy line fills it. The FE's notification/
+ * semaphore WRITE therefore takes an MMU FAULT_PTE (c398: `FAULT_PTE
+ * ACCESS_TYPE_VIRT_WRITE @ 0x0_041a0000`, 12 ms after the part launch)
+ * and the FECS priv-error poison (0xbadf1201) wipes the MME context,
+ * clears the prelude latch and restarts every multi-part pack from part 1
+ * - the eng38 part-launch poison.
+ *
+ * The host already applies the release itself (the push decoder's
+ * svc_rel_apply_reportsem runs on the same push), so the engine's write is
+ * redundant. Redirect A/B to a scratch slot inside the always-mapped
+ * module semaphore page (VA_SEM + 0x800) and force the operation word to
+ * RELEASE so an acquire can never wait on a value the engine does not
+ * author. Returns the number of words rewritten. Knob
+ * sema_gl_report_sem_scratch (default 1; A/B with 0 keeps verbatim).
+ */
+static bool gsp_phys_rmcall_gr_report_sem_scratch = true;
+module_param_named(sema_gl_report_sem_scratch,
+ gsp_phys_rmcall_gr_report_sem_scratch, bool, 0644);
+MODULE_PARM_DESC(sema_gl_report_sem_scratch,
+ "Redirect client SET_REPORT_SEMAPHORE/SET_NOTIFY targets in replayed 3D windows to the mapped module scratch slot (prevents the FE MMU FAULT_PTE poison; default 1)");
+
+static u32 gsp_phys_gr_reportsem_scratch(u32 *w, u32 n, u32 h_object,
+ u64 push_va)
+{
+ u32 r = 0, fixed = 0;
+
+ if (!READ_ONCE(gsp_phys_rmcall_gr_report_sem_scratch))
+ return 0;
+ while (r < n) {
+ u32 h = w[r];
+ u32 op = (h >> 29) & 7u;
+ u32 cnt = (h >> 16) & 0xfffu;
+ u32 span = 1u, m0, i;
+
+ if ((op == 1u || op == 3u || op == 5u) && cnt &&
+ r + 1u + cnt <= n)
+ span = 1u + cnt;
+ m0 = (h & 0xfffu) << 2;
+ if ((op == 1u || op == 3u) && span > 1u) {
+ for (i = 0; i + 1u < span; i++) {
+ u32 m = (op == 1u) ? m0 + 4u * i : m0;
+ u32 *d = &w[r + 1u + i];
+
+ if (m == 0x104u || m == 0x1b00u) {
+ *d = 0u;
+ fixed++;
+ } else if (m == 0x108u || m == 0x1b04u) {
+ *d = (u32)GSP_PHYS_RMCALL_VA_REPORT_SCRATCH;
+ fixed++;
+ } else if (m == 0x1b0cu && (*d & 3u)) {
+ *d &= ~3u;
+ fixed++;
+ }
+ }
+ }
+ r += span;
+ }
+ if (fixed)
+ pr_info_ratelimited("vgsp-gr: REPORT-SEM-SCRATCH %u word(s) redirected to VA=0x%llx (h=0x%x push=0x%llx)\n",
+ fixed, (unsigned long long)
+ GSP_PHYS_RMCALL_VA_REPORT_SCRATCH,
+ h_object, push_va);
+ return fixed;
+}
+
static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb,
const struct gsp_phys_gr_submit *req,
const u32 *qmd, u64 qmd_va,
@@ -21399,10 +21505,23 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
* restart edge; reset its cursor too so a
* wedged-recover latch clear replays the
* whole packed stream.
+ *
+ * eng39: except under the forced golden
+ * overlay - the packed image is then
+ * deterministic across capture
+ * generations, so a generation bump from
+ * an interleaved state capture must not
+ * restart a multi-part pack (c437 gen
+ * 2->5 rewinded part 2 to part 1).
*/
- WRITE_ONCE(gsp_phys_gr_mme_pack_off, 0);
- WRITE_ONCE(gsp_phys_gr_mme_pack_sa,
- false);
+ if (!(READ_ONCE(
+ gsp_phys_rmcall_gr_mme_pack_keep_gen) &&
+ READ_ONCE(
+ gsp_phys_rmcall_gr_mme_golden_force))) {
+ WRITE_ONCE(gsp_phys_gr_mme_pack_off, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_sa,
+ false);
+ }
}
/*
* c220 (eng11): pl_room is clamped to pl_n
@@ -23298,6 +23417,18 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
}
}
/*
+ * eng39: neutralize the client's own notify/report-semaphore
+ * targets in the FINAL emitted window (after the CALL/pair
+ * elisions above, before the ladder's own release tail below
+ * - that tail must keep its mapped VA_SEM target). Unmapped
+ * client targets poison the lane with an MMU FAULT_PTE on the
+ * FE's write; see gsp_phys_gr_reportsem_scratch.
+ */
+ if ((u32)(p - pb) > win_emit_off)
+ gsp_phys_gr_reportsem_scratch(&pb[win_emit_off],
+ (u32)(p - pb) - win_emit_off,
+ req->h_object, req->push_va);
+ /*
* r1453 PAIR-CHAIN: the install proof for the held-call
* elision extension. Recomputed from the FINAL emitted window
* (after the CALL/pair elision branches above), so a launch