summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-03 17:43:19 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-03 17:43:19 -0500
commitc332445746b8a8ef46869c3b47e165c375bb1f8d (patch)
treed4c5092b331ef530123880ae327e08e48a7f3cfa /kernel
parent9b801327ffd9e3f2e1f031f9f3752f3ffe3240fd (diff)
downloadopen-iov-c332445746b8a8ef46869c3b47e165c375bb1f8d.tar.gz
open-iov-c332445746b8a8ef46869c3b47e165c375bb1f8d.zip
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
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c64
-rw-r--r--kernel/gsp_sema_service.c55
-rw-r--r--kernel/gsp_sema_service.h11
3 files changed, 129 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 9774869..ab52e06 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18908,6 +18908,10 @@ static u32 gsp_phys_rmcall_gr_mme_state_d2a;
module_param_named(sema_mme_state_d2a, gsp_phys_rmcall_gr_mme_state_d2a,
uint, 0644);
MODULE_PARM_DESC(sema_mme_state_d2a, "Seed value for STATE 0xD2A LAST_UPDATED_LOAD_CONSTANT_BUFFER_OFFSET (method 0x34a8)");
+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");
/*
* SESSION 153-CONTINUED-105: split the packed MME prelude emission across
@@ -20033,6 +20037,66 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
}
}
/*
+ * SESSION 153-CONTINUED-115: STATE 0xD19 seed (shadow scratch
+ * 0x19, method 0x3464 = SET_MME_SHADOW_SCRATCH(0x19): the
+ * constant-buffer selector B/C address>>8). The bug2548370
+ * loadConstantBuffer macro's in-band update emits the selector
+ * from d19 once the fast path is refused (see the state seed
+ * below); the replay context never received the client's
+ * once-per-channel 0x3464 write, so d19 read 0 and the
+ * consumer fetched constants from address 0. Value:
+ * sema_mme_state_d19 when nonzero, else the captured write
+ * (0x3464); fail-closed - a missed shadow translation skips
+ * the emission instead of writing an untranslated selector.
+ * Gated by sema_gl_mme_state_seed (STATE class).
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_state_seed)) {
+ static u32 mme_state_d19_log;
+ u32 sv = READ_ONCE(gsp_phys_rmcall_gr_mme_state_d19);
+ bool have = sv != 0u;
+
+ if (!have)
+ have = gsp_sema_mme_scratch19_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) | (0x3464u >> 2);
+ *p++ = sv;
+ if (mme_state_d19_log < 16u) {
+ mme_state_d19_log++;
+ pr_info("vgsp-gr: MME-STATE-SEED d19=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 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;
}
}
diff --git a/kernel/gsp_sema_service.h b/kernel/gsp_sema_service.h
index 7efc2f3..5b993a8 100644
--- a/kernel/gsp_sema_service.h
+++ b/kernel/gsp_sema_service.h
@@ -568,6 +568,17 @@ u64 gsp_sema_mme_sa_get(u32 *entries, u32 n);
bool gsp_sema_mme_scratch18_get(u32 *val);
/*
+ * SESSION 153-CONTINUED-115: the client's own SET_MME_SHADOW_SCRATCH(0x19)
+ * write (method 0x3464) - STATE 0xD19, the constant-buffer selector B/C
+ * (address>>8) the bug2548370 loadConstantBuffer macro's in-band update
+ * emits from once the fast path is refused. Companion of scratch 0x18
+ * above; returns true (and stores the value exactly as pushed) once any
+ * decoded client push carried the write. false until then (never observed
+ * live so far; sema_mme_state_d19 can supply the seed value instead).
+ */
+bool gsp_sema_mme_scratch19_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