summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c87
1 files changed, 86 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 748eae9..2b8b422 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -14212,6 +14212,18 @@ static void svc_mme_census(const u8 *buf, u32 len, u64 push_va, u32 h_object)
* next window re-preplays. The writer is the single service thread and
* appends strictly in order; the generation only increments after a
* capture that appended, giving the booter a seqcheck against torn views.
+ *
+ * SESSION 153-CONTINUED-68: the capture can DROP runs once the buffer is
+ * full ("buffer full=N words=1023" on r1126) - e.g. a second GL program
+ * whose content never entered the replay - while the SA table (recorded
+ * unbounded, last-wins) still points slots at those never-replayed IR
+ * addresses; a call then fetches macro data that is not there (Graphics
+ * Exception: MISSING_MACRO_DATA). The coverage bitmap
+ * (svc_mme_ir_cov, instruction granularity) records exactly which IR
+ * instructions the REPLAY holds so the launch builder can stub every
+ * called slot whose entry is outside that set (see
+ * gsp_sema_mme_ir_covered). The buffer cap itself stays 1024 words: the
+ * launch method block is 2048 words and must also carry the window.
*/
#define SVC_MME_PRELUDE_WORDS 1024u
#define SVC_MME_PRELUDE_SIGS 512u
@@ -14253,6 +14265,39 @@ static u64 svc_mme_sa_present;
static u32 svc_mme_sa_entry[64];
static u32 svc_mme_sa_log;
+/*
+ * SESSION 153-CONTINUED-68: furthest IR instruction any CAPTURED 0x114
+ * upload covers (pc + ceil(code words / 3); the client's upload addresses
+ * are instruction units - slot N's pc equals slot N-1's pc + its code
+ * instructions, verified across the r1099/r1116 captures). The launch
+ * builder's MME stub must land BEYOND the replayed program: a fixed stub
+ * PC inside a captured macro's body would clobber that macro's code (the
+ * window calls covered slots too). Recorded only for runs that entered the
+ * replay buffer, so the value always describes the replayed IR extent.
+ */
+static u32 svc_mme_ir_end;
+
+u32 gsp_sema_mme_ir_end_get(void)
+{
+ return READ_ONCE(svc_mme_ir_end);
+}
+
+/*
+ * SESSION 153-CONTINUED-68: instruction-granular coverage of the IR the
+ * REPLAY buffer actually holds (marked for every 0x114 run that entered
+ * svc_mme_prelude_buf). Values >= SVC_MME_IR_BITS are treated as covered
+ * "elsewhere" so an overflow cannot force every slot to be stubbed.
+ */
+#define SVC_MME_IR_BITS 8192u
+static u8 svc_mme_ir_cov[SVC_MME_IR_BITS / 8u];
+
+bool gsp_sema_mme_ir_covered(u32 pc)
+{
+ if (pc >= SVC_MME_IR_BITS)
+ return true;
+ return !!(svc_mme_ir_cov[pc >> 3] & (1u << (pc & 7u)));
+}
+
u64 gsp_sema_mme_sa_get(u32 *entries, u32 n)
{
u32 i;
@@ -14378,9 +14423,31 @@ static void svc_mme_prelude_capture(const u8 *buf, u32 len, u64 push_va,
* the 0x114 instruction-RAM uploads are the only runs that
* make the prelude functionally complete; the maturity gate
* keys on them.
+ *
+ * SESSION 153-CONTINUED-68: also track the furthest covered
+ * IR instruction (see svc_mme_ir_end) so the builder's stub
+ * lands beyond the replayed program.
*/
- if (addr == 0x114u && span > 1u)
+ if (addr == 0x114u && span > 1u) {
+ u32 pc = 0, code_words = span - 2u, ir_end, k;
+
+ if (span >= 2u)
+ memcpy(&pc, buf + off + 4u, 4);
+ ir_end = pc + (code_words + 2u) / 3u;
+ if (ir_end > READ_ONCE(svc_mme_ir_end))
+ WRITE_ONCE(svc_mme_ir_end, ir_end);
+ /*
+ * SESSION 153-CONTINUED-68: mark the instructions this
+ * replayed run covers (see svc_mme_ir_cov).
+ */
+ for (k = 0; k < (code_words + 2u) / 3u; k++) {
+ u32 a = pc + k;
+
+ if (a < SVC_MME_IR_BITS)
+ svc_mme_ir_cov[a >> 3] |= 1u << (a & 7u);
+ }
svc_mme_prelude_code_words += span - 1u;
+ }
svc_mme_prelude_n += span;
svc_mme_prelude_sigs[svc_mme_prelude_sig_n++] = sig;
added++;
@@ -21152,6 +21219,24 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch,
ch->userd_ok = true;
*put = best_put;
*get = best_get;
+ /*
+ * SESSION 153-CONTINUED-68: deliberately do NOT
+ * seed the speculative latch here. Seeding
+ * armed the pump's judge on channels that
+ * previously accepted the VRAM candidate
+ * quietly; a pool block whose PUT advances in
+ * jumps (r1133: 219 -> 996) or a stale seed
+ * from an earlier RAM-scan candidate (r1132:
+ * latch=2 vs put=6) then rejected on every
+ * pass - adopt/reject spin at ~10 Hz (4638
+ * REJECTED lines on r1132, the guest's Xorg
+ * soft-locked, glxgears starved). The r1129-
+ * r1131 good boots show the intended shape:
+ * VRAM adopts logged, no rejects, ring
+ * consumption via the walk.
+ */
+ ch->gr_ram_userd_latch_at = 0;
+ ch->gr_ram_userd_confirmed = false;
pr_info("sema-chan: GR USERD h=0x%x rank=%u found by VRAM shape scan at fb 0x%llx (put=%u get=%u%s, ring-validated)\n",
ch->h_object, ch->gr_index, best,
best_put, best_get,