diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 118 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.c | 101 | ||||
| -rw-r--r-- | kernel/gsp_sema_service.h | 17 |
3 files changed, 235 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index ab52e06..c04ae70 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -18912,6 +18912,14 @@ static u32 gsp_phys_rmcall_gr_mme_state_d19; module_param_named(sema_mme_state_d19, gsp_phys_rmcall_gr_mme_state_d19, uint, 0644); MODULE_PARM_DESC(sema_mme_state_d19, "Seed value for STATE 0xD19 CONSTANT_BUFFER_SELECTOR_B_C (method 0x3464, CB VA>>8); 0 = use the client's captured 0x3464 write"); +static u32 gsp_phys_rmcall_gr_mme_state_d24; +module_param_named(sema_mme_state_d24, gsp_phys_rmcall_gr_mme_state_d24, + uint, 0644); +MODULE_PARM_DESC(sema_mme_state_d24, "Seed value for STATE 0xD24 slow-path input (method 0x3490); 0 = use the client's captured 0x3490 write"); +static u32 gsp_phys_rmcall_gr_mme_state_d25; +module_param_named(sema_mme_state_d25, gsp_phys_rmcall_gr_mme_state_d25, + uint, 0644); +MODULE_PARM_DESC(sema_mme_state_d25, "Seed value for STATE 0xD25 slow-path input (method 0x3494); 0 = use the client's captured 0x3494 write"); /* * SESSION 153-CONTINUED-105: split the packed MME prelude emission across @@ -20097,6 +20105,116 @@ if (gsp_phys_gr_slot_kept(j, sa_mask, } } /* + * SESSION 153-CONTINUED-116: STATE 0xD24 seed (shadow scratch + * 0x24, method 0x3490 = SET_MME_SHADOW_SCRATCH(0x24)). The + * bug2548370 slow path reads the 0x349x family beside the d19 + * selector; the replay context never received the client's + * once-per-channel 0x3490 write, so d24 read whatever the + * replay left (r1440: ILLEGAL_OPCODE in the same post-slot-57 + * window). Value: sema_mme_state_d24 when nonzero, else the + * captured write (0x3490); fail-closed - a missed shadow + * translation skips the emission instead of writing an + * untranslated value. Gated by sema_gl_mme_state_seed. + */ + if (READ_ONCE(gsp_phys_rmcall_gr_mme_state_seed)) { + static u32 mme_state_d24_log; + u32 sv = READ_ONCE(gsp_phys_rmcall_gr_mme_state_d24); + bool have = sv != 0u; + + if (!have) + have = gsp_sema_mme_scratch24_get(&sv); + if (have && sv && + (u32)(p - pb) + 8u < GSP_PHYS_RMCALL_GR_METHOD_WORDS) { + u64 va = (u64)sv << 8; + bool xl = false; + bool ok = true; + + 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; + } else { + ok = false; + } + } + if (ok) { + *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM + << 29) | + (1u << 16) | (0x3490u >> 2); + *p++ = sv; + if (mme_state_d24_log < 16u) { + 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, + req->h_object, + req->push_va); + } + } + } + } + /* + * SESSION 153-CONTINUED-116: STATE 0xD25 seed (shadow scratch + * 0x25, method 0x3494 = SET_MME_SHADOW_SCRATCH(0x25)), the + * next unseeded input on the same slow path; same value + * policy, translation and fail-closed rule as d24 above. + */ + if (READ_ONCE(gsp_phys_rmcall_gr_mme_state_seed)) { + static u32 mme_state_d25_log; + u32 sv = READ_ONCE(gsp_phys_rmcall_gr_mme_state_d25); + bool have = sv != 0u; + + if (!have) + have = gsp_sema_mme_scratch25_get(&sv); + if (have && sv && + (u32)(p - pb) + 8u < GSP_PHYS_RMCALL_GR_METHOD_WORDS) { + u64 va = (u64)sv << 8; + bool xl = false; + bool ok = true; + + 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; + } else { + ok = false; + } + } + if (ok) { + *p++ = ((u32)GSP_PHYS_RMCALL_METHOD_IMM + << 29) | + (1u << 16) | (0x3494u >> 2); + *p++ = sv; + if (mme_state_d25_log < 16u) { + 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, + req->h_object, + req->push_va); + } + } + } + } + /* * SESSION 153-CONTINUED-105: golden MME runtime state seed * (see the sema_gl_mme_state_seed comment). Five idempotent * shadow-scratch writes ahead of the window so the diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 08f2309..532f89d 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -14790,13 +14790,52 @@ bool gsp_sema_mme_scratch19_get(u32 *val) return svc_scratch19_seen; } +/* + * SESSION 153-CONTINUED-116: companion captures for the bug2548370 slow-path + * state family. STATE 0xD24 / shadow scratch 0x24 (method 0x3490 = + * SET_MME_SHADOW_SCRATCH(0x24)) is read by the macro body alongside the d19 + * selector; the replayed context never received the client's + * once-per-channel write, so the value resolves to whatever the replay left. + * The value is stored exactly as pushed (first write wins); the GR launch + * builder can fall back to sema_mme_state_d24 when this never fires. + */ +static u32 svc_scratch24_val; +static bool svc_scratch24_seen; +static u32 svc_scratch24_log; + +bool gsp_sema_mme_scratch24_get(u32 *val) +{ + if (svc_scratch24_seen && val) + *val = READ_ONCE(svc_scratch24_val); + return svc_scratch24_seen; +} + +/* + * SESSION 153-CONTINUED-116: companion of scratch 0x24 above - STATE 0xD25 / + * shadow scratch 0x25 (method 0x3494 = SET_MME_SHADOW_SCRATCH(0x25)), the + * next unseeded input on the same slow path. Same first-write-wins capture + * and builder fallback (sema_mme_state_d25). + */ +static u32 svc_scratch25_val; +static bool svc_scratch25_seen; +static u32 svc_scratch25_log; + +bool gsp_sema_mme_scratch25_get(u32 *val) +{ + if (svc_scratch25_seen && val) + *val = READ_ONCE(svc_scratch25_val); + return svc_scratch25_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 && - svc_scratch19_seen && svc_scratch19_log >= 24u) + svc_scratch19_seen && svc_scratch19_log >= 24u && + svc_scratch24_seen && svc_scratch24_log >= 24u && + svc_scratch25_seen && svc_scratch25_log >= 24u) return; while (off + 4u <= len) { u32 hdr, op, cnt, addr; @@ -14841,6 +14880,40 @@ static void svc_scratch18_watch(const u8 *buf, u32 len, u64 push_va, off += 4u + cnt * 4u; continue; } + if (addr == 0x3490u) { + u32 val; + + memcpy(&val, buf + off + 4, 4); + if (!svc_scratch24_seen) { + svc_scratch24_seen = true; + WRITE_ONCE(svc_scratch24_val, val); + } + if (svc_scratch24_log < 24u) { + svc_scratch24_log++; + pr_info("sema-scratch24: h=0x%x va=0x%llx off=0x%x op=%u cnt=%u val=0x%08x (SET_MME_SHADOW_SCRATCH(0x24); slow-path state d24)\n", + h_object, push_va, off, op, cnt, + val); + } + off += 4u + cnt * 4u; + continue; + } + if (addr == 0x3494u) { + u32 val; + + memcpy(&val, buf + off + 4, 4); + if (!svc_scratch25_seen) { + svc_scratch25_seen = true; + WRITE_ONCE(svc_scratch25_val, val); + } + if (svc_scratch25_log < 24u) { + svc_scratch25_log++; + pr_info("sema-scratch25: h=0x%x va=0x%llx off=0x%x op=%u cnt=%u val=0x%08x (SET_MME_SHADOW_SCRATCH(0x25); slow-path state d25)\n", + h_object, push_va, off, op, cnt, + val); + } + off += 4u + cnt * 4u; + continue; + } off += 4u + cnt * 4u; continue; } @@ -14870,6 +14943,32 @@ static void svc_scratch18_watch(const u8 *buf, u32 len, u64 push_va, h_object, push_va, off, val); } } + if (op == 4u && addr == 0x3490u) { + u32 val = (hdr >> 16) & 0x1fffu; + + if (!svc_scratch24_seen) { + svc_scratch24_seen = true; + WRITE_ONCE(svc_scratch24_val, val); + } + if (svc_scratch24_log < 24u) { + svc_scratch24_log++; + pr_info("sema-scratch24: h=0x%x va=0x%llx off=0x%x op=4 immd val=0x%08x (SET_MME_SHADOW_SCRATCH(0x24))\n", + h_object, push_va, off, val); + } + } + if (op == 4u && addr == 0x3494u) { + u32 val = (hdr >> 16) & 0x1fffu; + + if (!svc_scratch25_seen) { + svc_scratch25_seen = true; + WRITE_ONCE(svc_scratch25_val, val); + } + if (svc_scratch25_log < 24u) { + svc_scratch25_log++; + pr_info("sema-scratch25: h=0x%x va=0x%llx off=0x%x op=4 immd val=0x%08x (SET_MME_SHADOW_SCRATCH(0x25))\n", + h_object, push_va, off, val); + } + } off += 4u; } } diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h index 5b993a8..1e0dac6 100644 --- a/kernel/gsp_sema_service.h +++ b/kernel/gsp_sema_service.h @@ -579,6 +579,23 @@ bool gsp_sema_mme_scratch18_get(u32 *val); bool gsp_sema_mme_scratch19_get(u32 *val); /* + * SESSION 153-CONTINUED-116: the client's own SET_MME_SHADOW_SCRATCH(0x24) + * write (method 0x3490) - STATE 0xD24, the next unseeded slow-path input the + * bug2548370 macro body reads beside the d19 selector. Companion of scratch + * 0x19 above; returns true (and stores the value exactly as pushed) once any + * decoded client push carried the write; sema_mme_state_d24 can supply the + * seed value instead. + */ +bool gsp_sema_mme_scratch24_get(u32 *val); + +/* + * SESSION 153-CONTINUED-116: the client's own SET_MME_SHADOW_SCRATCH(0x25) + * write (method 0x3494) - STATE 0xD25. Same first-write-wins capture and + * builder fallback (sema_mme_state_d25) as scratch 0x24 above. + */ +bool gsp_sema_mme_scratch25_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 |
