summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-14 15:42:56 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-14 15:42:56 -0500
commitdfc76004dcc680941c8634fce0d7d56d7ae3ad2b (patch)
treed8874050722f0a4b0f67f4c166591b94f4aae74b /kernel/gsp_phys_booter.c
parent1f0df0c62cc6786de9c230f6c4196e14653a30e2 (diff)
downloadopen-iov-dfc76004dcc680941c8634fce0d7d56d7ae3ad2b.tar.gz
open-iov-dfc76004dcc680941c8634fce0d7d56d7ae3ad2b.zip
vgsp: eng42 - engine-global MME pack completion: record the pack completion globally (pack_done_gen/ch) so the post-completion call release fires for cross-lane completions (c552: part 1 on X, completion on beef -> pack_done_h withheld, REARM unreachable); restart the owner-less wedged cursor (poff==maxa && done_h==0) so a later window can re-emit the deterministic golden image (validation pending)
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c111
1 files changed, 99 insertions, 12 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 35cfc79..9f1efdd 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18520,6 +18520,26 @@ static bool gsp_phys_gr_mme_pack_sa;
static u32 gsp_phys_gr_mme_pack_load_h;
static u32 gsp_phys_gr_mme_pack_load_words;
static u32 gsp_phys_gr_mme_pack_done_h;
+/*
+ * eng42: the packed program's residency is an ENGINE property, not a
+ * channel property. The 0x114/0x11c IRAM writes load the engine context
+ * that every window's calls execute against - a completion on ANY lane
+ * means the (deterministic golden) image is resident. c552 proved the
+ * per-channel proof above can never fire for a cross-lane completion:
+ * part 1 on h=0x1000013, final part on h=0xbeef0100 -> the contiguous
+ * check zeroed load_h -> pack_done_h=0 -> the eng40 release
+ * (done_h == req->h_object) was unreachable although the engine held the
+ * whole program, and the cursor wedged at maxa for the rest of the boot
+ * (no gen rewind under keep_gen=1; chan_ctx_reset no-ops without an
+ * owner). pack_done_gen/ch record the completion GLOBALLY (generation
+ * and completing channel, forensics only); every genuine engine-context
+ * wipe clears them beside pack_done_h, and a re-register of a channel
+ * that owns the load invalidates them via chan_ctx_reset. The post-
+ * completion call release then fires for a draw on ANY channel whose
+ * window will execute against the resident engine program.
+ */
+static u32 gsp_phys_gr_mme_pack_done_gen;
+static u32 gsp_phys_gr_mme_pack_done_ch;
/*
* CONT-103: prelude residency witness + calls-kept block shrink.
@@ -20608,6 +20628,8 @@ static void gsp_phys_gr_mme_iram_gate_fail(void)
WRITE_ONCE(gsp_phys_gr_mme_pack_load_h, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_load_words, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_done_h, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_ch, 0);
/*
* CONT-118: residency is unproven again, so a settled release armed
* for this generation is void; the re-emission re-earns it.
@@ -20828,6 +20850,8 @@ static void gsp_phys_gr_ctx_wipe_latches(void)
WRITE_ONCE(gsp_phys_gr_mme_pack_load_h, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_load_words, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_done_h, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_ch, 0);
WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
WRITE_ONCE(gsp_phys_gr_mme_release_gen, 0);
WRITE_ONCE(gsp_phys_gr_mme_release_h, 0);
@@ -20870,6 +20894,8 @@ void gsp_phys_gr_mme_chan_ctx_reset(u32 h)
WRITE_ONCE(gsp_phys_gr_mme_pack_load_h, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_load_words, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_done_h, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_ch, 0);
WRITE_ONCE(gsp_phys_gr_mme_prelude_gen, 0);
WRITE_ONCE(gsp_phys_gr_mme_pre_emit_off, 0);
WRITE_ONCE(gsp_phys_gr_mme_pending_gen, 0);
@@ -21589,6 +21615,10 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
0);
WRITE_ONCE(gsp_phys_gr_mme_pack_done_h,
0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_gen,
+ 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_ch,
+ 0);
}
}
/*
@@ -22501,6 +22531,37 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
if (can && split && !sa_done &&
3u * npair > left)
can = false;
+ /*
+ * eng42 (b): an owner-less completion
+ * (c552 cross-lane: done_h==0) wedges
+ * the cursor at maxa for the rest of
+ * the boot - the generation edge does
+ * not rewind it (keep_gen=1) and
+ * chan_ctx_reset no-ops without an
+ * owner, so no later window could
+ * re-emit the deterministic golden
+ * image. Restart the drain here (this
+ * launch stays non-emitting; the REARM
+ * clause below still releases its held
+ * calls against the global completion
+ * record above).
+ */
+ if (!can && poff >= maxa && maxa >= 3u &&
+ READ_ONCE(gsp_phys_gr_mme_pack_done_h) == 0u &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_pack_keep_gen) &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_golden_force)) {
+ WRITE_ONCE(gsp_phys_gr_mme_pack_off,
+ 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_sa,
+ false);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_load_h,
+ 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_load_words,
+ 0);
+ pr_info("vgsp-gr: MME-PACK-WEDGE-RESET h=0x%x maxa=%u (owner-less completion; cursor restarted, calls released below if held) push=0x%llx\n",
+ req->h_object, maxa,
+ req->push_va);
+ }
if (can) {
pp = p;
if (!sa_done) {
@@ -22574,7 +22635,7 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
gsp_phys_gr_mme_pack_load_words,
0);
}
- if (poff >= maxa)
+ if (poff >= maxa) {
WRITE_ONCE(
gsp_phys_gr_mme_pack_done_h,
(READ_ONCE(
@@ -22584,6 +22645,20 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
gsp_phys_gr_mme_pack_load_words) >=
maxa) ?
req->h_object : 0);
+ /*
+ * eng42: completion is
+ * engine-global - record it
+ * whatever lane carried the
+ * final part (see the
+ * pack_done_gen comment).
+ */
+ WRITE_ONCE(
+ gsp_phys_gr_mme_pack_done_gen,
+ pl_gen);
+ WRITE_ONCE(
+ gsp_phys_gr_mme_pack_done_ch,
+ req->h_object);
+ }
}
pwords = (u32)(pp - p);
p = pp;
@@ -22944,29 +23019,39 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
}
}
/*
- * eng40: post-completion per-channel re-arm. Once the packed
- * program has completed ON THIS CHANNEL - contiguous load,
- * deterministic golden image - the channel context keeps it
- * until a wipe or re-register. Every later frame bumps the
+ * eng40/eng42: post-completion re-arm. Once the packed
+ * program completed (deterministic golden image), the engine
+ * context keeps it until a wipe. Every later frame bumps the
* capture generation, the pack branch cannot re-emit (poff ==
* maxa), and the completion carrier dropped its own window, so
* without this release the real calls stay held forever (c489:
- * pcv=0 on every post-completion draw). Only non-emitting
- * launches release (pre_words_out == 0 - the r1222 same-launch
- * clause stays intact), and the per-channel flag is invalidated
- * by any context wipe or channel registration, so a fresh context
- * can never run calls against a non-resident program.
+ * pcv=0 on every post-completion draw). eng42: the completion
+ * is engine-global - the release also fires when the
+ * contiguous per-channel proof is absent but the global
+ * record stands (c552: part 1 on X, completion on beef ->
+ * pack_done_h withheld, engine still holds the image; the
+ * completing beeves had no draw while the X lane kept
+ * drawing). Only non-emitting launches release (pre_words_out
+ * == 0 - the r1222 same-launch clause stays intact), and the
+ * records are invalidated by every context wipe / owning-
+ * channel re-register, so a fresh context can never run calls
+ * against a non-resident program.
*/
if (mme_hold_calls && pre_words_out == 0 &&
READ_ONCE(gsp_phys_rmcall_gr_mme_pack_keep_gen) &&
READ_ONCE(gsp_phys_rmcall_gr_mme_golden_force) &&
- READ_ONCE(gsp_phys_gr_mme_pack_done_h) == req->h_object) {
+ (READ_ONCE(gsp_phys_gr_mme_pack_done_h) == req->h_object ||
+ READ_ONCE(gsp_phys_gr_mme_pack_done_gen) != 0u)) {
static u32 pack_rearm_log;
if (pack_rearm_log < 8u) {
pack_rearm_log++;
- pr_info("vgsp-gr: MME-PACK-REARM h=0x%x gen=%u (pack complete + contiguous load; calls released) push=0x%llx\n",
+ pr_info("vgsp-gr: MME-PACK-REARM h=0x%x gen=%u (pack complete%s; calls released) push=0x%llx\n",
req->h_object, pl_gen,
+ READ_ONCE(gsp_phys_gr_mme_pack_done_h) ==
+ req->h_object ?
+ " + contiguous load" :
+ " (engine-resident, cross-lane completion)",
(unsigned long long)req->push_va);
}
mme_hold_calls = false;
@@ -32484,6 +32569,8 @@ gr_page_unmapped:
WRITE_ONCE(gsp_phys_gr_mme_pack_load_h, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_load_words, 0);
WRITE_ONCE(gsp_phys_gr_mme_pack_done_h, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_gen, 0);
+ WRITE_ONCE(gsp_phys_gr_mme_pack_done_ch, 0);
WRITE_ONCE(gsp_phys_gr_mme_live_gen, 0);
WRITE_ONCE(
gsp_phys_gr_mme_release_gen,