diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-15 16:01:03 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-15 16:01:03 -0500 |
| commit | 9a0870638b2bb1d199ee5d09e70893423a6909c7 (patch) | |
| tree | dee25c83ab7f45a2699e5577b095ecbee000da38 /kernel/gsp_phys_booter.c | |
| parent | 43bbf490dca972cb96fcf1d69dd0b6859377e452 (diff) | |
| download | open-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.c | 119 |
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; |
