summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
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/gsp_phys_booter.c
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/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c64
1 files changed, 64 insertions, 0 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