summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-05 14:31:10 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-05 14:31:10 -0500
commitc126441814ded6498b2e06ebb2a33ee05faac994 (patch)
tree878fde7d5a0951ae07dbc4b27707a03df0a90c3a /kernel/gsp_sema_service.c
parent22f77ffbf5ea2a3f6f678b825c7d296c16471175 (diff)
downloadopen-iov-c126441814ded6498b2e06ebb2a33ee05faac994.tar.gz
open-iov-c126441814ded6498b2e06ebb2a33ee05faac994.zip
vgsp-gr: keep the validated fixed CB across launches and map each VTG stream contiguously
- Remember the last fixed-CB page that resolved through a SYS source and passed the matrix gate; a later resolution miss (or a method-page answer) reuses it instead of zeroing the seed page with the synthetic identity. Only a boot with no validated read ever uses the identity fallback. Do not skip the write on an unchanged hash: the seed page lives in the client's screen allocation and the guest can rewrite it between launches. - Treat the CALL_MME_MACRO(2) vertex stream as one range: map [base,end) into a fresh contiguous fetch line and rewrite both ends from it, preserving the client's stream length across 4 KB boundaries. Unresolvable pages map the module zero page (a zero vertex, never a fault). The generic per-word pass remains the fallback. - Diagnostics: cb-copy logs the first 8 seed-page words and the cached flag; MME-VSTREAM-LINE dumps the resolved base page (client VA, HPA, page count, first 8 words). - Evidence: r1494 (poison 11/17 -> 1/16, real vertex floats at the stream bases, CB cache verified live with src=vaswalk -> src=cached-real) and r1495/r1496 (the active draw's vertex/index page is an all-zero vidmem shadow page while the data exists in guest sysmem - the new wall).
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 5bc387e..dd02aa0 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -15344,6 +15344,16 @@ static u32 svc_gl_cb_copy_h;
static u32 svc_gl_cb_copy_val;
static u32 svc_gl_cb_copy_hash;
static u32 svc_gl_cb_copy_log;
+/*
+ * r1494: the last fixed-CB page that resolved through a SYS (engine-page)
+ * source and passed the matrix gate. The client VA can move/reuse after
+ * the first frame (r1492 read back a method page with the same VA and
+ * r1493 fell back to identity), so a later resolution miss must not zero
+ * the seed page: reuse this page for the rest of the boot. Only a page
+ * that was never credibly resolved falls back to the synthetic identity.
+ */
+static u8 svc_gl_cb_good[SEMA_PAGE_SIZE];
+static bool svc_gl_cb_good_valid;
static u32 svc_gl_cb_hash(const u8 *p, u32 n)
{
@@ -15558,33 +15568,49 @@ have:
* r1491: a source whose 0x80 block is not a credible matrix would
* still collapse every vertex. Only a SYS (engine-page) read is
* trusted; an FB-shadow read is by construction not the engine's
- * page, so author the identity positive control there too.
- */
- if ((ssrc == 4 || ssrc == 5 || ssrc == 6 || ssrc == 7) ||
- !svc_gl_cb_matrix_ok(buf)) {
+ * page, so it must not become the seed either.
+ *
+ * r1494: split "is this the real CB?" from "what do we write?".
+ * A validated SYS page becomes the boot's remembered real CB. When
+ * a later resolution misses (or answers with a method page), write
+ * that remembered page again instead of the identity fallback -
+ * the fallback may only run when no real CB was ever resolved this
+ * boot. Do not skip the write on an unchanged hash: the seed page
+ * lives in the client's screen allocation and the guest can have
+ * rewritten it between launches, so "same content as last time" is
+ * not the same as "page still holds it".
+ */
+ if (ssrc != 4 && ssrc != 5 && ssrc != 6 && ssrc != 7 &&
+ svc_gl_cb_matrix_ok(buf)) {
+ memcpy(svc_gl_cb_good, buf, sizeof(svc_gl_cb_good));
+ svc_gl_cb_good_valid = true;
+ } else if (svc_gl_cb_good_valid) {
+ memcpy(buf, svc_gl_cb_good, sizeof(svc_gl_cb_good));
+ src = "cached-real";
+ ssrc = 9;
+ } else {
memset(buf, 0, sizeof(buf));
put_unaligned_le32(0x3f800000u, buf + 0x80); /* m00 */
put_unaligned_le32(0x3f800000u, buf + 0x94); /* m11 */
put_unaligned_le32(0x3f800000u, buf + 0xa8); /* m22 */
put_unaligned_le32(0x3f800000u, buf + 0xbc); /* m33 */
src = "synthetic-id";
+ ssrc = 7;
}
hash = svc_gl_cb_hash(buf, sizeof(buf));
- if (svc_gl_cb_copy_h == h_object && svc_gl_cb_copy_val == val &&
- svc_gl_cb_copy_hash == hash)
- return;
+ (void)hash;
rc = svc_grce_inline_write(vgpu, sema_gl_cb_copy_to, buf, sizeof(buf),
h_object);
- if (svc_gl_cb_copy_log < 24u) {
- u32 w0, w1;
+ if (svc_gl_cb_copy_log < 96u) {
+ u32 w[8];
- memcpy(&w0, buf, 4);
- memcpy(&w1, buf + 4, 4);
+ memcpy(w, buf, sizeof(w));
svc_gl_cb_copy_log++;
- pr_info("vgsp-sema: sema-gl: cb-copy src=0x%llx dst=0x%llx pa=0x%llx ap=%u hpa=0x%llx ssrc=%d first=%08x %08x src=%s write=%d (fixed-CB page -> forced seed page)\n",
- src_va, sema_gl_cb_copy_to, pa, ap, hpa, ssrc, w0, w1,
- src, rc);
- if (svc_gl_cb_copy_log <= 4u)
+ pr_info("vgsp-sema: sema-gl: cb-copy src=0x%llx dst=0x%llx pa=0x%llx ap=%u hpa=0x%llx ssrc=%d first8=%08x %08x %08x %08x %08x %08x %08x %08x src=%s write=%d cached=%d (fixed-CB page -> forced seed page)\n",
+ src_va, sema_gl_cb_copy_to, pa, ap, hpa, ssrc,
+ w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7],
+ src, rc, svc_gl_cb_good_valid ? 1 : 0);
+ if (svc_gl_cb_copy_log <= 12u)
svc_gl_cb_dump_matrix(buf, src, pa, ap, ssrc);
}
if (!rc) {