From d14b36f8097b2c6b9bc0347b9a658dfdb6477311 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 2 Nov 2026 10:47:41 -0500 Subject: vgsp: CONT-112 - changed-page copy-out witness budget + MME IR-word A/B patch knob (sema_gl_mme_irpatch_off/_val) --- kernel/gsp_phys_booter.c | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index bcb0dd0..6379894 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -130,6 +130,16 @@ MODULE_PARM_DESC(gsp_phys_gr_reloc_resolve, * per-launch RELOC-CENSUS line. */ #define GSP_PHYS_GR_COPYWIT_MAX 12u +/* + * CONT-112: the changed-page witness gets its OWN budget. A store-rich + * launch walks the tracked pages in bi order and the unchanged pages come + * first, so the shared 12-line budget was always consumed by the OUT-UNCH + * flood before the loop reached the handful of engine-changed pages - the + * r1385 evidence has "2/900 pages changed" + OUT-ALIAS-WIT for bi=8960/8965 + * but no OUT-PAGE-WIT va->hpa pair for either. With the split counter both + * classes are witnessed on every launch (<=12 unchanged + <=16 changed). + */ +#define GSP_PHYS_GR_COPYWIT_CHG_MAX 16u static bool gsp_phys_gr_copyout_dump_param = true; module_param_named(gsp_phys_gr_copyout_dump, gsp_phys_gr_copyout_dump_param, bool, 0644); @@ -18399,6 +18409,29 @@ MODULE_PARM_DESC(sema_gl_mme_prelude_pack, /* Packed IR image; indexed by IR word address (<= 0x420 in captures). */ static u32 gsp_phys_gr_mme_ir_pack[4096]; +/* + * CONT-112: A/B IR-word override for the packed MME program. The offline + * replay of the captured SA stream (mmeref/, sim_run.py) shows slot 34 (the + * draw macro) emitting `0x1618<-0x61000008, 0xd74<-0, 0xd78<-count(0x3c), + * 0x1614<-0` from the CLIENT'S OWN call params - i.e. the emitted sequence + * is parameter-correct offline. This knob overrides ONE word of the packed + * image (the exact words the engine loads into its IRAM) so a live A/B can + * mutate the emitted method words one at a time (BEGIN data / SVS / DRAW + * count / END) and observe the engine's writes: the packed image is rebuilt + * per launch, so the value is live-tunable without a reload. Off by + * default (~0u); both params runtime-settable. + */ +static unsigned int gsp_phys_gr_mme_irpatch_off = ~0u; +module_param_named(sema_gl_mme_irpatch_off, gsp_phys_gr_mme_irpatch_off, + uint, 0644); +MODULE_PARM_DESC(sema_gl_mme_irpatch_off, + "IR word index in the packed MME program to override for A/B (default 4294967295 = off)"); +static unsigned int gsp_phys_gr_mme_irpatch_val; +module_param_named(sema_gl_mme_irpatch_val, gsp_phys_gr_mme_irpatch_val, + uint, 0644); +MODULE_PARM_DESC(sema_gl_mme_irpatch_val, + "Value written at sema_gl_mme_irpatch_off in the packed MME program (default 0)"); + /* * SESSION 153-CONTINUED-107: IRAM chronology + load-gate helpers. * @@ -20024,6 +20057,24 @@ static u32 gsp_phys_rmcall_build_gr_launch(u32 *pb, } r += span; } + /* + * CONT-112: single-word A/B override of the + * packed program (see the sema_gl_mme_irpatch + * comment). Applied after the image is built so + * the override is what the macro executes and + * what the IRAM gate compares against. + */ + if (gsp_phys_gr_mme_irpatch_off < maxa) { + pr_info("vgsp-gr: MME-IRPATCH word[%u] = 0x%08x (was 0x%08x, maxa=%u)\n", + gsp_phys_gr_mme_irpatch_off, + gsp_phys_gr_mme_irpatch_val, + gsp_phys_gr_mme_ir_pack[ + gsp_phys_gr_mme_irpatch_off], + maxa); + gsp_phys_gr_mme_ir_pack[ + gsp_phys_gr_mme_irpatch_off] = + gsp_phys_gr_mme_irpatch_val; + } for (kk = 0; kk < 64u; kk++) if ((sa_mask & (1ull << kk)) && sa_ent[kk]) @@ -29392,6 +29443,7 @@ gr_page_unmapped: u32 aliased = 0, unchanged = 0, skipped = 0; u32 chg[8] = { }; u32 outwit = 0; /* COPYWIT: bounded per-launch witness lines */ + u32 outwit_chg = 0; /* CONT-112: own budget, changed pages */ for (wbi = 0; wbi < req->n_data; wbi++) { u32 bi = gsp_phys_gr_data_bi(req->data[wbi].reloc_va); @@ -29492,7 +29544,7 @@ gr_page_unmapped: * sema-bigcopy resolution lines. */ if (gsp_phys_gr_copywit_enabled() && - outwit < GSP_PHYS_GR_COPYWIT_MAX) { + outwit_chg < GSP_PHYS_GR_COPYWIT_CHG_MAX) { /* * r391 diagnostic (sum=0 class): the * landing-table resolution of this VA @@ -29507,7 +29559,7 @@ gr_page_unmapped: req->data[wbi].va, &rpa, &rap, &rval); - outwit++; + outwit_chg++; pr_info("vgsp-gr: OUT-PAGE-WIT va=0x%llx hpa=0x%llx bi=%u first8=%016llx last8=%016llx pre=%016llx post=%016llx res=%s pa=0x%llx ap=%u val8=%016llx vbase=%px\n", req->data[wbi].va, req->data[wbi].hpa, bi, f8, @@ -29597,13 +29649,13 @@ gr_page_unmapped: * write target and the reader's page are different * (aperture/staleness disagreement), not a lost write. */ - if (outwit < GSP_PHYS_GR_COPYWIT_MAX) { + if (outwit_chg < GSP_PHYS_GR_COPYWIT_CHG_MAX) { u64 rpa2 = 0, rval2 = 0; u32 rap2 = 0; if (gsp_sema_gr_va_snap(req->data[wbi].va, &rpa2, &rap2, &rval2)) { - outwit++; + outwit_chg++; pr_info("vgsp-gr: OUT-PAGE-POST va=0x%llx hpa=0x%llx res_pa=0x%llx ap=%u val8=%016llx vbase=%px\n", req->data[wbi].va, req->data[wbi].hpa, rpa2, -- cgit v1.2.3