summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c55
1 files changed, 54 insertions, 1 deletions
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;
}
}