summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c68
1 files changed, 62 insertions, 6 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 5aeee31..62ab6eb 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -18453,12 +18453,27 @@ module_param_named(sema_gl_pair_chain, gsp_phys_rmcall_gr_pair_chain,
bool, 0644);
MODULE_PARM_DESC(sema_gl_pair_chain,
"One logical BEGIN..END chain per launch: carry the full 32-bit BEGIN data (SPLIT_MODE 30:29), insert WAIT_FOR_IDLE(0x110) drains between back-to-back normal/normal pairs, and extend pair elision to held-call windows (default 1; 0 = legacy bytes)");
+/*
+ * r1465 PAIR-ORPHAN-DROP (sema_gl_pair_orphan_drop): the pair_open/split
+ * tracker is a projection of the FE's pair state, so it must only advance
+ * through windows the FE actually consumed. A dropped/held/LOAD-ONLY
+ * window is a pair-state no-op (restore the launch-entry snapshot), and an
+ * END observed while the model is closed is provably orphaned (its opener
+ * window was dropped) - the FE has no pair to close and faults EC 0x0d, so
+ * the END run is elided. Default 1; 0 = legacy bytes (leak/0x1614).
+ */
+static bool gsp_phys_rmcall_gr_pair_orphan_drop = true;
+module_param_named(sema_gl_pair_orphan_drop,
+ gsp_phys_rmcall_gr_pair_orphan_drop, bool, 0644);
+MODULE_PARM_DESC(sema_gl_pair_orphan_drop,
+ "Pair-state sync: roll pair_open/open_split back on dropped/held/LOAD-ONLY windows and elide orphan END runs when no pair is open (default 1; 0 = legacy bytes)");
static bool gsp_phys_gr_mme_pairs_emitted; /* launch emitted a pair run */
static u32 gsp_phys_gr_mme_pairs_gen; /* gen whose pairs retired OK */
static u32 gsp_phys_gr_mme_launch_gen; /* last built launch's gen */
static bool gsp_phys_gr_mme_pair_open; /* BEGIN..END open across windows */
static u32 gsp_phys_gr_mme_pair_open_split; /* split mode of that BEGIN */
static bool gsp_phys_gr_mme_pair_open_entry; /* open seen when THIS window was fixed */
+static u32 gsp_phys_gr_mme_pair_open_entry_split; /* split of the entry-open BEGIN */
static u32 gsp_phys_gr_mme_pair_entry_elide_n; /* entry-open pair-run elisions */
/*
@@ -18497,12 +18512,13 @@ static bool gsp_phys_gr_pair_present(const u32 *w, u32 n)
static u32 gsp_phys_gr_pair_chain_fix(u32 *w, u32 *np, u32 cap)
{
u32 n = *np, r = 0, begins = 0, ends = 0, drains = 0;
- u32 chains = 0, orphans = 0, nested = 0, badv = 0;
+ u32 chains = 0, orphans = 0, orphan_dropped = 0, nested = 0, badv = 0;
bool open = READ_ONCE(gsp_phys_gr_mme_pair_open);
bool seen = false, begin_logged = false;
u32 open_split = READ_ONCE(gsp_phys_gr_mme_pair_open_split);
WRITE_ONCE(gsp_phys_gr_mme_pair_open_entry, open);
+ WRITE_ONCE(gsp_phys_gr_mme_pair_open_entry_split, open_split);
while (r < n) {
u32 h = w[r];
@@ -18583,6 +18599,25 @@ static u32 gsp_phys_gr_pair_chain_fix(u32 *w, u32 *np, u32 cap)
begins++;
} else if (is_end) {
if (!open) {
+ /*
+ * r1465 PAIR-ORPHAN-DROP: the opener's
+ * window was dropped, so the FE has no
+ * pair to close and would raise EC 0x0d
+ * on this END. Remove the whole END run
+ * (header 0x80000585/0x80000584 immd13
+ * form or a 1+cnt run32) in place; never
+ * rewrite it.
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_pair_orphan_drop) &&
+ span <= n - r) {
+ memmove(&w[r], &w[r + span],
+ (size_t)(n - r - span) * 4u);
+ n -= span;
+ orphan_dropped++;
+ pr_info_ratelimited("vgsp-gr: PAIR-ORPHAN-DROP off=%u span=%u window=%u\n",
+ r, span, n);
+ continue;
+ }
orphans++;
} else {
u32 expect = ((open_split == 1u ||
@@ -18596,11 +18631,11 @@ static u32 gsp_phys_gr_pair_chain_fix(u32 *w, u32 *np, u32 cap)
}
r += span;
}
- if (begins > 1u || drains || chains || orphans || nested || badv ||
- open)
- pr_info_ratelimited("vgsp-gr: PAIR-CHAIN begin=%u end=%u drains=%u chain=%u orphan_end=%u nested=%u endv_mismatch=%u open_at_end=%u entry=%u window=%u\n",
- begins, ends, drains, chains, orphans, nested,
- badv, open ? 1u : 0u,
+ if (begins > 1u || drains || chains || orphans || orphan_dropped ||
+ nested || badv || open)
+ pr_info_ratelimited("vgsp-gr: PAIR-CHAIN begin=%u end=%u drains=%u chain=%u orphan_end=%u orphan_drop=%u nested=%u endv_mismatch=%u open_at_end=%u entry=%u window=%u\n",
+ begins, ends, drains, chains, orphans, orphan_dropped,
+ nested, badv, open ? 1u : 0u,
READ_ONCE(gsp_phys_gr_mme_pair_open_entry) ? 1u : 0u,
n);
*np = n;
@@ -22009,6 +22044,20 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
*/
win_emit_off = (u32)(p - pb);
if (mme_load_only || mme_hold_window) {
+ /*
+ * r1465 PAIR-ORPHAN-DROP: the FE consumed none of
+ * this window, so the pair projection is a no-op:
+ * restore the launch-entry snapshot the fixer took
+ * before the walk (MME-WINDOW-HOLD and MME-LOAD-ONLY
+ * both land here; the held-call branch still emits
+ * the window, so its pairs are FE-visible).
+ */
+ if (READ_ONCE(gsp_phys_rmcall_gr_pair_orphan_drop)) {
+ WRITE_ONCE(gsp_phys_gr_mme_pair_open,
+ READ_ONCE(gsp_phys_gr_mme_pair_open_entry));
+ WRITE_ONCE(gsp_phys_gr_mme_pair_open_split,
+ READ_ONCE(gsp_phys_gr_mme_pair_open_entry_split));
+ }
if (mme_hold_window && !mme_load_only) {
pr_info_ratelimited("vgsp-gr: MME-WINDOW-HOLD gen=%u h=%#x window=%u dropped (r1447 arming hold) push=0x%llx\n",
pl_gen, req->h_object, win3d_n,
@@ -27096,6 +27145,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
* reaches gsp_phys_gr_pair_chain_fix cannot elide.
*/
gsp_phys_gr_mme_pair_open_entry = false;
+ gsp_phys_gr_mme_pair_open_entry_split = 0;
gsp_phys_gr_codehash_done = false; /* CODEHASH: once per launch */
/*
* M91 FAULT-CAP: snapshot the fault epoch per launch, so the capture
@@ -29734,6 +29784,9 @@ gr_page_unmapped:
0);
WRITE_ONCE(gsp_phys_gr_mme_pair_open_entry,
false);
+ WRITE_ONCE(
+ gsp_phys_gr_mme_pair_open_entry_split,
+ 0);
/*
* r1447: the wiped context voids the arming
* window-hold and the strict grace budget too.
@@ -30112,6 +30165,9 @@ gr_page_unmapped:
WRITE_ONCE(
gsp_phys_gr_mme_pair_open_entry,
false);
+ WRITE_ONCE(
+ gsp_phys_gr_mme_pair_open_entry_split,
+ 0);
/*
* r1447: same context wipe -
* void the arming window-hold