summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-15 16:01:03 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-15 16:01:03 -0500
commit9a0870638b2bb1d199ee5d09e70893423a6909c7 (patch)
treedee25c83ab7f45a2699e5577b095ecbee000da38 /kernel/gsp_phys_booter.c
parent43bbf490dca972cb96fcf1d69dd0b6859377e452 (diff)
downloadopen-iov-9a0870638b2bb1d199ee5d09e70893423a6909c7.tar.gz
open-iov-9a0870638b2bb1d199ee5d09e70893423a6909c7.zip
vgsp: eng63 - held-CALL target census, DRAW-window preference, and release-launch SA re-arm
c776 proved the saved-window release replay carries the slot-34 CALL_MME_MACRO run (MME-WINRUN off=340 op=5 cnt=10 mthd=3910) but the macros ran 0x33/0x0/0x39: the release launch sets emit_prelude=0, and the client capture had no slot 34 (c774 fill published golden entry 0x265 host-side only), so the stale engine SA[34] resolved the call to IR 0 (mac=0x0). - MME-CALL-CENSUS/MME-CALL-TARGET: decode the held window's CALL runs with the hold/drop run grammar (op 1/3 walk method+4k, op 5 only the header method, op 4 one method) and print targets + slot34 with the client/golden/used entry. - release_save: among DRAW_IAB-bearing windows prefer the smaller raw DRAW stream (324 B/81 words, the c716 mac=0x22 shape) over the 728 B state window; keep=draw-win receipt. - sema_gl_mme_release_sa_arm (default 0; params-r1624 enables it): run the SA re-arm + golden fill on the release launch so CALL_MME_MACRO(34) points at the golden DRAW_IAB body (IR 0x265). Pack-carry/release receipts unchanged; release carrier still default 0.
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c119
1 files changed, 116 insertions, 3 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 65ab874..24b2b7f 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18993,6 +18993,24 @@ MODULE_PARM_DESC(sema_gl_mme_pack_release_ms,
"Settle delay before the saved-window release carrier fires (clamped 20..5000 ms; default 100)");
/*
+ * Release-launch SA re-arm. The saved-window release launch replays the
+ * held window with emit_prelude=false (the pack is already resident), so
+ * the per-launch SA re-arm block is the only writer of the START-ADDRESS
+ * RAM pairs on that launch. The client capture may leave slot 34 missing
+ * or zero (r1231: "SA[34]=0 lands last") and the golden fill then
+ * publishes slot 34's body (IR 0x265) into the host table only; without a
+ * re-arm the release's CALL_MME_MACRO(34) keeps the engine's stale entry
+ * (c776 replay ran mac=0x33/0x0/0x39, never 0x22). Arm the called slots
+ * (including the golden-filled slot 34) on release launches only. Default
+ * 0 = A/B; the release carrier itself is default off.
+ */
+static bool gsp_phys_rmcall_gr_mme_release_sa_arm;
+module_param_named(sema_gl_mme_release_sa_arm,
+ gsp_phys_rmcall_gr_mme_release_sa_arm, bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_release_sa_arm,
+ "Re-emit the START-ADDRESS RAM pairs (incl. golden slot 34 -> IR 0x265) before a saved-window release launch so CALL_MME_MACRO(34) resolves to DRAW_IAB (default 0; needs sema_gl_mme_pack_release=1)");
+
+/*
* DRAW_IAB preference (release carrier follow-up): the held-call window that
* matters is the DRAW window, whose method stream carries the
* CALL_MME_MACRO(34) run that expands to DRAW_IAB (mac=0x22).
@@ -19044,6 +19062,75 @@ static u32 gsp_phys_gr_mme_release_due_ms(void)
}
/*
+ * Held-CALL target census (release-carrier diagnostic): decode every
+ * CALL_MME_MACRO(j) run of the held window with the same run grammar the
+ * hold/drop walk uses (op 1/3 carry 1+cnt words and walk method+4k, op 5
+ * writes only data[0] to the header method, op 4 is a single method; only
+ * methods 0x3800+j*8 are the .Macro half) and resolve each target slot
+ * against the host START-ADDRESS RAM table. The c756/c776 dumps show the
+ * slot-34 run (`a00a0e44`, ONE_INCR 0x3910) in BOTH the 324 B DRAW window
+ * and the 728 B state window, so the byte scan cannot discriminate them -
+ * the census names the actual call targets and the SA entry each resolves
+ * to, which is what the release replay executes.
+ */
+static void gsp_phys_gr_mme_call_census(const struct gsp_phys_gr_submit *req,
+ u32 held, u32 win_n)
+{
+ static u32 census_log;
+ u32 sa_ent[64], r = 0, calls = 0, slot34 = 0;
+ u64 sa_mask, targets = 0;
+
+ if (!req || !req->stream || !req->stream_n || census_log >= 16u)
+ return;
+ sa_mask = gsp_sema_mme_sa_get(sa_ent, 64);
+ while (r < req->stream_n) {
+ u32 h = req->stream[r];
+ u32 op = (h >> 29) & 7u;
+ u32 cnt = (h >> 16) & 0x1fffu;
+ u32 span = 1u, k, nk = 0;
+
+ if ((op == 1u || op == 3u || op == 5u) && cnt &&
+ r + 1u + cnt <= req->stream_n)
+ span = 1u + cnt;
+ if (op == 1u || op == 3u)
+ nk = span - 1u;
+ else if (op == 4u || op == 5u)
+ nk = 1u;
+ for (k = 0; k < nk; k++) {
+ u32 m = ((h & 0xfffu) << 2) + 4u * k;
+ u32 j, gent = 0, gn;
+ const u32 *gw;
+ bool have_cli, have_gold;
+
+ if (m < 0x3800u || m >= 0x3a00u || (m & 7u))
+ continue;
+ j = (m - 0x3800u) / 8u;
+ if (j >= 64u)
+ continue;
+ have_cli = (sa_mask & (1ull << j)) && sa_ent[j];
+ have_gold = gsp_phys_gr_golden_slot(j, &gent, &gw,
+ &gn);
+ calls++;
+ targets |= 1ull << j;
+ if (j == 34u) {
+ slot34 = 1;
+ pr_info("vgsp-gr: MME-CALL-TARGET slot=34 method=0x%x client=0x%x golden=0x%x used=0x%x win=%u held=%u\n",
+ m, have_cli ? sa_ent[j] : 0u,
+ have_gold ? gent : 0u,
+ have_cli ? sa_ent[j] :
+ (have_gold ? gent : 0u),
+ win_n, held);
+ }
+ }
+ r += span;
+ }
+ census_log++;
+ pr_info("vgsp-gr: MME-CALL-CENSUS h=0x%x win=%u held=%u calls=%u targets=0x%llx slot34=%u\n",
+ req->h_object, win_n, held, calls,
+ (unsigned long long)targets, slot34);
+}
+
+/*
* Snapshot at the held-call window (the caller logs `MME-CALL-HOLD` first).
* Only the raw window and the capture fields are copied; guest pages are
* referenced by HPA (the boot's pages remain valid), and the saved stream
@@ -19057,6 +19144,7 @@ static void gsp_phys_gr_mme_release_save(const struct gsp_phys_gr_submit *req,
struct gsp_phys_gr_mme_release_state *s = &gsp_phys_gr_mme_release;
unsigned long flags;
bool draw_ia, keep = false;
+ const char *prefer = NULL;
u32 old_h = 0, old_win = 0;
static u32 prefer_log;
@@ -19079,6 +19167,7 @@ static void gsp_phys_gr_mme_release_save(const struct gsp_phys_gr_submit *req,
}
draw_ia = gsp_phys_gr_mme_window_has_draw_ia(req->stream,
req->stream_n);
+ gsp_phys_gr_mme_call_census(req, held, win_n);
spin_lock_irqsave(&gsp_phys_gr_mme_release_lock, flags);
/*
* The DRAW window's raw stream is the release payload that can run the
@@ -19091,6 +19180,22 @@ static void gsp_phys_gr_mme_release_save(const struct gsp_phys_gr_submit *req,
old_h = s->h_object;
old_win = s->win_n;
keep = true;
+ prefer = "draw-ia";
+ } else if (s->valid && !s->consumed && s->draw_ia && draw_ia &&
+ s->stream_n <= req->stream_n) {
+ /*
+ * Among DRAW_IAB-bearing windows prefer the DRAW window's raw
+ * stream: the 324 B window (81 raw words, c756 push
+ * 0x4011978) is the c716 mac=0x22 shape, while the 728 B
+ * state window (182 raw words, c772/c776 push 0x42192a0)
+ * only also carries the slot-34 run. Both scan as draw_ia,
+ * so the smaller raw stream is the structural discriminator;
+ * a later state window must not supersede the draw.
+ */
+ old_h = s->h_object;
+ old_win = s->win_n;
+ keep = true;
+ prefer = "draw-win";
}
if (!keep) {
s->valid = false;
@@ -19141,9 +19246,10 @@ static void gsp_phys_gr_mme_release_save(const struct gsp_phys_gr_submit *req,
if (keep) {
if (prefer_log < 16u) {
prefer_log++;
- pr_info("vgsp-gr: MME-CARRY-SAVE-PREFER keep=draw-ia "
+ pr_info("vgsp-gr: MME-CARRY-SAVE-PREFER keep=%s "
"h=0x%x old_win=%u new_win=%u\n",
- old_h, old_win, win_n);
+ prefer ? prefer : "keep", old_h, old_win,
+ win_n);
}
return;
}
@@ -24546,8 +24652,15 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
* and the next prelude re-emission. Emitting the re-arm
* ahead of the window makes every launch's calls resolve
* to the captured SA entry.
+ *
+ * sema_gl_mme_release_sa_arm extends the same re-arm to the
+ * saved-window release launch (which never emits the prelude
+ * and would otherwise execute CALL_MME_MACRO(34) against the
+ * engine's stale SA[34]: c776 ran mac=0x33/0x0/0x39).
*/
- if (READ_ONCE(gsp_phys_rmcall_gr_mme_sa_rearm)) {
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_sa_rearm) ||
+ (release &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_release_sa_arm))) {
u32 sa_ent[64];
u64 sa_mask = gsp_sema_mme_sa_get(sa_ent, 64);
u32 r = 0, rearm = 0;