diff options
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 87 |
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, |
