diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-01 21:42:00 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-01 21:42:00 -0500 |
| commit | d61bf4e99e5119f7a6b8ee43e745fbbf4fd5c4ef (patch) | |
| tree | dec545929515d600b7a9e2b8fc43d29233dd4047 /kernel | |
| parent | f7bc705a8a61e6ad11cd23b5fabd5a86e62ae34c (diff) | |
| download | open-iov-d61bf4e99e5119f7a6b8ee43e745fbbf4fd5c4ef.tar.gz open-iov-d61bf4e99e5119f7a6b8ee43e745fbbf4fd5c4ef.zip | |
vgsp: CONT-101 - sema-scratch18 watch (scan every decoded push on every channel for 0x3460 SET_MME_SHADOW_SCRATCH(0x18), log up to 24 hits, publish first value via gsp_sema_mme_scratch18_get) + sema_gl_mme_seed/seed_val/seed_xlat (emit [op1 cnt1 m=0x3460][value] ahead of every replayed 3D window; xlat translates value page through launch shadow mapper before >>8) - DECISIVE: client NEVER writes 0x3460 (0 hits across r1348-52 all channels); seed works end-to-end (MME-SEED scratch 0x18 <- 0x000a0000 va=0xa000000 xlat=1) but wall not cleared: MME-FAST trap=80002058 data=019b0900 grfifo 04041602->00000001 park events=2 - trap is window's own relocated program pair (pair addr=0x2054 va=0x4350900 -> 0x19b0900) and fires BEFORE MME consumes seed; DESIGNED FIX WORKS LIVE: sema_gl_prog_guest_va=Y -> PROG-GUEST-VA keep addr=0x2054 va=0x4400900 (Tier-1 identity; operand verbatim) -> ZERO trap=80002058 thereafter; r1352 (keep from boot) got session's FIRST MME-generated evidence (gen0=1) then lottery outcome events=4 (poison) esr->0xbadf1201 WEDGE-REARM engine still wedged; GATE1 black 0/900 pages NO-STORES - next: boot r1347 richest config (nop_drop=1<<0 slot 0 dropped) PLUS sema_gl_prog_guest_va=1 from insmod (removes 0x2058 trap class the seed cannot touch); check stores before re-arming slot 0 with seed; 0xd18 golden value open but subordinate (vGPU client never emits it) - SESSION 153 r1348-r1352
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 100 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.c | 86 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.h | 10 |
3 files changed, 194 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 42fb8f2..663f276 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -18228,6 +18228,41 @@ MODULE_PARM_DESC(sema_sph_region_base, "Program-region base override (0 = launch program family page; nonzero = explicit engine-side base)"); /* + * SESSION 153-CONTINUED-101: MME fixed-constant-buffer scratch seed + * (SET_MME_SHADOW_SCRATCH(0x18), method 0x3460). + * + * mmeCodeOGL_C597_SETUP_FIXED_CONST (macro slot 0) reads shadow scratch + * 0x18/0xd18 via STATE and unconditionally emits its high/low halves as + * SET_CONSTANT_BUFFER_SELECTOR_B/C (the compiled C597 form carries NO + * bug2548370 branch: the config table says no972630). With the replay + * context's scratch at 0 the macro emits selector B/C = 0 and the draw's + * constant fetch has no address. The client's own write (gf100Init- + * ConstantBuffers: (u32)(fixed CB VA >> 8)) is a once-per-channel event + * the ladder never receives, so the builder seeds it ahead of the + * window. Value source: sema_gl_mme_seed_val when nonzero, else the + * client's own captured write (gsp_sema_mme_scratch18_get). With + * sema_gl_mme_seed_xlat (default 1) the page is translated through the + * launch's own page set / shadow mapping first (the same relocator the + * window operand pairs use) so the emitted selector resolves in the + * engine's address space; on MISS the raw value is emitted (the A/B + * control). Default off; live-tunable. + */ +static bool gsp_phys_rmcall_gr_mme_seed; +module_param_named(sema_gl_mme_seed, gsp_phys_rmcall_gr_mme_seed, bool, 0644); +MODULE_PARM_DESC(sema_gl_mme_seed, + "Seed MME shadow scratch 0x18 (method 0x3460) with the fixed-CB base>>8 ahead of replayed 3D windows (default 0)"); +static u32 gsp_phys_rmcall_gr_mme_seed_val; +module_param_named(sema_gl_mme_seed_val, gsp_phys_rmcall_gr_mme_seed_val, + uint, 0644); +MODULE_PARM_DESC(sema_gl_mme_seed_val, + "Explicit scratch 0x18 value (fixed CB VA>>8); 0 = use the client's captured 0x3460 write"); +static bool gsp_phys_rmcall_gr_mme_seed_xlat = true; +module_param_named(sema_gl_mme_seed_xlat, gsp_phys_rmcall_gr_mme_seed_xlat, + bool, 0644); +MODULE_PARM_DESC(sema_gl_mme_seed_xlat, + "Translate the seed value's page to the engine-side shadow/identity VA before emitting (default 1; 0 = raw)"); + +/* * SESSION 153-CONTINUED-93: additionally emit the legacy program-region * pair (0x1608/0x160c) beside the MME shadow pair (see the emission site). * Default 0 (A/B; the DS snapshot registers share the legacy pair's names). @@ -18558,8 +18593,7 @@ MODULE_PARM_DESC(sema_gl_surf_prelude, * seen on the client's 0x402094c push) does not count - the surface * prelude is injected for it too. */ -static bool gsp_phys_gr_window_has_surface(const u32 *win, u32 n) -{ +static bool gsp_phys_gr_window_has_surface(const u32 *win, u32 n){ u32 off = 0; while (off < n) { @@ -18597,6 +18631,13 @@ static bool gsp_phys_gr_window_has_surface(const u32 *win, u32 n) * channel long before the launch), so the replay must not either. * Returns the block size in dwords. */ +/* SESSION 153-CONTINUED-101: forward declaration - the seed emission in + * gsp_phys_rmcall_build_gr_launch (below) translates the seed page through + * the same relocator the window operand pairs use (defined further down). */ +static bool gsp_phys_rmcall_gr_3d_reloc(u32 *up_w, u32 *lo_w, + const struct gsp_phys_gr_submit *req, + u32 *n_shadow); + static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb, const struct gsp_phys_gr_submit *req, const u32 *qmd, u64 qmd_va, @@ -19112,6 +19153,61 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb, } } /* + * SESSION 153-CONTINUED-101: MME fixed-constant-buffer scratch + * seed (see the sema_gl_mme_seed* knobs). mmeCodeOGL_C597_ + * SETUP_FIXED_CONST (slot 0) emits SET_CONSTANT_BUFFER_ + * SELECTOR_B/C from shadow scratch 0x18/0xd18; the replay + * context never received the client's once-per-channel write + * (gf100InitConstantBuffers pushes method 0x3460), so the + * macro read 0 and the selector went empty. Emit the seed + * ahead of the window; the value is the fixed CB address>>8, + * page-translated to the launch's shadow/identity mapping when + * sema_gl_mme_seed_xlat is set (see gsp_phys_rmcall_gr_3d_ + * reloc - same machinery as the operand pairs). + */ + if (READ_ONCE(gsp_phys_rmcall_gr_mme_seed)) { + static u32 mme_seed_log; + u32 sv = READ_ONCE(gsp_phys_rmcall_gr_mme_seed_val); + bool have = sv != 0u; + + if (!have) + have = gsp_sema_mme_scratch18_get(&sv); + if (have && sv && + (u32)(p - pb) + 8u < GSP_PHYS_RMCALL_GR_METHOD_WORDS) { + u64 va = (u64)sv << 8; + bool xl = false; + + if (READ_ONCE(gsp_phys_rmcall_gr_mme_seed_xlat) + && va) { + u32 up_w = (u32)((va >> 32) & 0xffu); + u32 lo_w = (u32)va & 0xfffffffcu; + u32 n_sh = 0; + + if (gsp_phys_rmcall_gr_3d_reloc( + &up_w, &lo_w, req, &n_sh)) { + va = ((u64)(up_w & 0xffu) + << 32) | + (u64)(lo_w & 0xfffffffcu); + sv = (u32)(va >> 8); + xl = true; + } + } + *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM << 29) | + (1u << 16) | (0x3460u >> 2); + *p++ = sv; + if (mme_seed_log < 16u) { + 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) { + 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); + } + } + /* * SESSION 153-CONTINUED-93: the LEGACY program-region pair * (0x1608/0x160c = the pre-Volta SET_PROGRAM_REGION_A/B whose * names the DS's own snapshot registers diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 234932c..a3ee6f3 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -14738,6 +14738,88 @@ static void svc_mme_census(const u8 *buf, u32 len, u64 push_va, u32 h_object) } /* + * SESSION 153-CONTINUED-101: MME fixed-constant-buffer scratch watch. + * + * mmeCodeOGL_C597_SETUP_FIXED_CONST (macro slot 0) is the only reader of + * MME shadow scratch 0x18/0xd18 (MME_SCRATCH_FIXED_CONSTANT_BUFFER = + * 0x10 + RM_MME_FIRST_USABLE_SHADOW_SCRATCH); its compiled C597 form DOES + * NOT include the bug2548370 branch, so it unconditionally emits + * SET_CONSTANT_BUFFER_SELECTOR_B/C = cbAddr[31:24]/[23:0]<<8 from that + * scratch. The value is written once per channel/context by the client's + * own gf100InitConstantBuffers: method 0x3460 (SET_MME_SHADOW_SCRATCH + * (0x18)) <- (u32)(fixed constant buffer VA >> 8). The replayed ladder + * context never receives that once-per-channel write, so the macro reads + * 0 and emits an empty CB selector; the draw then fetches constants from + * address 0. This watch records the client's own write (any channel, any + * push that decodes) and publishes the first value so the GR launch + * builder can seed scratch 0x18 ahead of the window (sema_gl_mme_seed). + * Value is stored exactly as pushed (client VA >> 8). Read-only. + */ +static u32 svc_scratch18_val; +static bool svc_scratch18_seen; +static u32 svc_scratch18_log; + +bool gsp_sema_mme_scratch18_get(u32 *val) +{ + if (svc_scratch18_seen && val) + *val = READ_ONCE(svc_scratch18_val); + return svc_scratch18_seen; +} + +static void svc_scratch18_watch(const u8 *buf, u32 len, u64 push_va, + u32 h_object) +{ + u32 off = 0; + + if (svc_scratch18_seen && svc_scratch18_log >= 24u) + return; + while (off + 4u <= len) { + u32 hdr, op, cnt, addr; + + memcpy(&hdr, buf + off, 4); + op = (hdr >> 29) & 7u; + cnt = (hdr >> 16) & 0xfffu; + addr = (hdr & 0xfffu) << 2; + if ((op == 1u || op == 3u || op == 5u) && cnt && + off + 4u + cnt * 4u <= len) { + if (addr == 0x3460u) { + u32 val; + + memcpy(&val, buf + off + 4, 4); + if (!svc_scratch18_seen) { + svc_scratch18_seen = true; + WRITE_ONCE(svc_scratch18_val, val); + } + if (svc_scratch18_log < 24u) { + svc_scratch18_log++; + pr_info("sema-scratch18: h=0x%x va=0x%llx off=0x%x op=%u cnt=%u val=0x%08x (SET_MME_SHADOW_SCRATCH(0x18); fixed-CB base>>8)\n", + h_object, push_va, off, op, cnt, + val); + } + off += 4u + cnt * 4u; + continue; + } + off += 4u + cnt * 4u; + continue; + } + if (op == 4u && addr == 0x3460u) { + u32 val = (hdr >> 16) & 0x1fffu; + + if (!svc_scratch18_seen) { + svc_scratch18_seen = true; + WRITE_ONCE(svc_scratch18_val, val); + } + if (svc_scratch18_log < 24u) { + svc_scratch18_log++; + pr_info("sema-scratch18: h=0x%x va=0x%llx off=0x%x op=4 immd val=0x%08x (SET_MME_SHADOW_SCRATCH(0x18))\n", + h_object, push_va, off, val); + } + } + off += 4u; + } +} + +/* * SESSION 153-CONTINUED-94: client init-push capture + local-memory census. * * CONT-93's "single most concrete next fix" was that the GL driver's @@ -16241,6 +16323,10 @@ static void svc_decode_stream(struct nv_vgpu_device *vgpu, const u8 *buf, if (ch) svc_mme_census(buf, len, push_va, ch->h_object); + /* SESSION 153-CONTINUED-101: fixed-CB scratch (0x3460) watch, any channel. */ + if (ch) + svc_scratch18_watch(buf, len, push_va, ch->h_object); + /* SESSION 153-CONTINUED-94: init-push capture + local-memory census. */ if (ch) svc_init_push_scan(buf, len, push_va, ch->h_object); diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h index f2a40ee..7efc2f3 100644 --- a/kernel/gsp_sema_service.h +++ b/kernel/gsp_sema_service.h @@ -558,6 +558,16 @@ bool gsp_sema_gr_surf_recs(u64 *va, u32 *n); u64 gsp_sema_mme_sa_get(u32 *entries, u32 n); /* + * SESSION 153-CONTINUED-101: the client's own SET_MME_SHADOW_SCRATCH(0x18) + * write (method 0x3460) - mmeCodeOGL_C597_SETUP_FIXED_CONST (slot 0) reads + * shadow scratch 0x18/0xd18 via STATE and emits it as the fixed-function + * constant-buffer selector (SET_CONSTANT_BUFFER_SELECTOR_B/C). Returns + * true (and stores the value exactly as pushed: fixed-CB address >> 8) + * once any decoded client push carried the write. false until then. + */ +bool gsp_sema_mme_scratch18_get(u32 *val); + +/* * SESSION 153-CONTINUED-87: the SPH VERSION of the live program images * (sema_gl_vs/ps_hex blobs), so the GR launch builder emits a * SET_SPH_VERSION window that MATCHES the images the engine will fetch |
