summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c118
-rw-r--r--kernel/gsp_sema_service.c101
-rw-r--r--kernel/gsp_sema_service.h17
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