From c332445746b8a8ef46869c3b47e165c375bb1f8d Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 3 Nov 2026 17:43:19 -0500 Subject: vgsp-sph: C4 - capture scratch 0x19 (CB selector, mthd 0x3464) + seed STATE 0xD19 emission (param sema_mme_state_d19 > captured, 3d-reloc, fail-closed) - the d28-forced slow path reads an unseeded d19 and faults the consumer at VA 0 (HUBCLIENT_PD); +129/-1 --- kernel/gsp_sema_service.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'kernel/gsp_sema_service.c') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 4546bb0..08f2309 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -14768,12 +14768,35 @@ bool gsp_sema_mme_scratch18_get(u32 *val) return svc_scratch18_seen; } +/* + * SESSION 153-CONTINUED-115: companion capture for the bug2548370 slow-path + * selector. STATE 0xD19 / shadow scratch 0x19 (method 0x3464 = + * SET_MME_SHADOW_SCRATCH(0x19)) is the constant-buffer selector B/C + * (address>>8) the macro's in-band update emits from once the fast path is + * refused (d28 forced); when the replay context never receives the client's + * once-per-channel write the selector resolves to 0 and the consumer fetches + * constants from address 0 - the same failure mode documented for 0x18. The + * value is stored exactly as pushed; the GR launch builder can fall back to + * sema_mme_state_d19 when this never fires. + */ +static u32 svc_scratch19_val; +static bool svc_scratch19_seen; +static u32 svc_scratch19_log; + +bool gsp_sema_mme_scratch19_get(u32 *val) +{ + if (svc_scratch19_seen && val) + *val = READ_ONCE(svc_scratch19_val); + return svc_scratch19_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) + if (svc_scratch18_seen && svc_scratch18_log >= 24u && + svc_scratch19_seen && svc_scratch19_log >= 24u) return; while (off + 4u <= len) { u32 hdr, op, cnt, addr; @@ -14801,6 +14824,23 @@ static void svc_scratch18_watch(const u8 *buf, u32 len, u64 push_va, off += 4u + cnt * 4u; continue; } + if (addr == 0x3464u) { + u32 val; + + memcpy(&val, buf + off + 4, 4); + if (!svc_scratch19_seen) { + svc_scratch19_seen = true; + WRITE_ONCE(svc_scratch19_val, val); + } + if (svc_scratch19_log < 24u) { + svc_scratch19_log++; + pr_info("sema-scratch19: h=0x%x va=0x%llx off=0x%x op=%u cnt=%u val=0x%08x (SET_MME_SHADOW_SCRATCH(0x19); CB selector B/C address>>8)\n", + h_object, push_va, off, op, cnt, + val); + } + off += 4u + cnt * 4u; + continue; + } off += 4u + cnt * 4u; continue; } @@ -14817,6 +14857,19 @@ static void svc_scratch18_watch(const u8 *buf, u32 len, u64 push_va, h_object, push_va, off, val); } } + if (op == 4u && addr == 0x3464u) { + u32 val = (hdr >> 16) & 0x1fffu; + + if (!svc_scratch19_seen) { + svc_scratch19_seen = true; + WRITE_ONCE(svc_scratch19_val, val); + } + if (svc_scratch19_log < 24u) { + svc_scratch19_log++; + pr_info("sema-scratch19: h=0x%x va=0x%llx off=0x%x op=4 immd val=0x%08x (SET_MME_SHADOW_SCRATCH(0x19); CB selector B/C address>>8)\n", + h_object, push_va, off, val); + } + } off += 4u; } } -- cgit v1.2.3