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.c159
1 files changed, 157 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 7a7af61..bdcf25e 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -19794,6 +19794,22 @@ MODULE_PARM_DESC(sema_gl_mme_seed_xlat,
"Translate the seed value's page to the engine-side shadow/identity VA before emitting (default 1; 0 = raw)");
/*
+ * eng45: fixed-constant-buffer region alias. The single-page seed reloc
+ * maps the CB base page only; the released macro 57 then reads
+ * base+0x5000 (the CB is 0x7000 bytes) and the GR MMU faults with
+ * FAULT_PTE on the unmapped tail (c653 HUBCLIENT_SCC @ 0x15a5000). With
+ * this on, the seed path aliases the whole 7-page region contiguously
+ * (page 0 = the copied client CB image with the MVP; unresolved tail
+ * pages read the dummy zero page) and points scratch 0x18 / d19 at the
+ * alias base, so the fetch never faults. Default 0 = legacy single page.
+ */
+static bool gsp_phys_rmcall_gr_mme_cb_alias;
+module_param_named(sema_gl_mme_cb_alias, gsp_phys_rmcall_gr_mme_cb_alias,
+ bool, 0644);
+MODULE_PARM_DESC(sema_gl_mme_cb_alias,
+ "Alias the full 7-page fixed-CB region for the seed so macro57's base+0x5000 read cannot FAULT_PTE (default 0 = single seed page)");
+
+/*
* SESSION 153-CONTINUED-105: golden MME runtime state seed, STATE
* 0xD26..0xD2A (SET_MME_SHADOW_SCRATCH 0x26..0x2a, methods 0x3498/0x349c/
* 0x34a0/0x34a4/0x34a8). The bug2548370 loadConstantBuffer macro (slot 57 /
@@ -20815,6 +20831,20 @@ static bool gsp_phys_gr_window_has_surface(const u32 *win, u32 n){
static bool gsp_phys_rmcall_gr_3d_reloc(u32 *up_w, u32 *lo_w,
const struct gsp_phys_gr_submit *req,
u32 *n_shadow);
+/*
+ * eng45: map the fixed-constant-buffer region contiguously. The single
+ * seed-page reloc below maps only the CB base page; the bug2548370
+ * loadConstantBuffer macro (slot 57) then reads base+0x5000 and the GR
+ * MMU raises FAULT_PTE on the unmapped tail page (c653: HUBCLIENT_SCC @
+ * 0x15a5000, 11 ms after the released calls ran macro 0x39). This aliases
+ * the whole CB region (7 pages) into one contiguous scratch-PT line,
+ * resolving each page and falling back to the dummy zero page for a page
+ * the guest VAS cannot serve, so the fetch never faults. The MVP at 0x80
+ * lives in page 0 (the seed page the client CB image is copied into), so
+ * the draw's transform constants survive. Called with the GR lock held.
+ */
+static bool gsp_phys_gr_cb_alias_locked(const struct gsp_phys_gr_submit *req,
+ u64 va, u32 npages, u64 *alias_out);
/*
* SESSION 153-CONTINUED-104: FE idle witness for the calls-kept gate.
@@ -21949,7 +21979,19 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
u64 va = (u64)sv << 8;
bool xl = false;
- if (READ_ONCE(gsp_phys_rmcall_gr_mme_seed_xlat)
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_cb_alias) && va) {
+ u64 abase = 0;
+
+ if (gsp_phys_gr_cb_alias_locked(req, va,
+ 7u,
+ &abase)) {
+ va = abase;
+ sv = (u32)(va >> 8);
+ xl = true;
+ }
+ }
+ if (!xl &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_seed_xlat)
&& va) {
u32 up_w = (u32)((va >> 32) & 0xffu);
u32 lo_w = (u32)va & 0xfffffffcu;
@@ -22006,7 +22048,19 @@ if (gsp_phys_gr_slot_kept(j, sa_mask,
bool xl = false;
bool ok = true;
- if (READ_ONCE(gsp_phys_rmcall_gr_mme_seed_xlat)
+ if (READ_ONCE(gsp_phys_rmcall_gr_mme_cb_alias) && va) {
+ u64 abase = 0;
+
+ if (gsp_phys_gr_cb_alias_locked(req, va,
+ 7u,
+ &abase)) {
+ va = abase;
+ sv = (u32)(va >> 8);
+ xl = true;
+ }
+ }
+ if (!xl &&
+ READ_ONCE(gsp_phys_rmcall_gr_mme_seed_xlat)
&& va) {
u32 up_w = (u32)((va >> 32) & 0xffu);
u32 lo_w = (u32)va & 0xfffffffcu;
@@ -28454,6 +28508,107 @@ static bool gsp_phys_gr_surface_alias_locked(const struct gsp_phys_gr_submit *re
}
/*
+ * eng45: contiguous fixed-CB region alias (see the forward declaration).
+ * Same scratch-PT line mechanics as gsp_phys_gr_surface_alias_locked, but
+ * an unresolved page falls back to the dummy zero page instead of failing
+ * the whole run: the CB tail is not needed for the draw's MVP (which is
+ * in page 0), only its FETCH must not fault. The alias is cached per
+ * seed VA for the boot so each window does not consume a fresh line.
+ */
+static u64 gsp_phys_gr_cb_alias_va;
+static u64 gsp_phys_gr_cb_alias_base;
+static bool gsp_phys_gr_cb_alias_valid;
+static u32 gsp_phys_gr_cb_alias_log;
+
+static bool gsp_phys_gr_cb_alias_locked(const struct gsp_phys_gr_submit *req,
+ u64 va, u32 npages, u64 *alias_out)
+{
+ u64 map_pages = npages;
+ u32 nlines, base_line, i, j;
+ u64 first_va, last_va, page_va = va & ~(u64)(GSP_PHYS_PAGE_SIZE - 1);
+
+ if (!page_va || !map_pages || map_pages > 64u)
+ return false;
+ if (gsp_phys_gr_cb_alias_valid && gsp_phys_gr_cb_alias_va == page_va) {
+ *alias_out = gsp_phys_gr_cb_alias_base + (va - page_va);
+ return true;
+ }
+ nlines = (u32)((map_pages +
+ GSP_PHYS_RMCALL_GUEST_PT_CACHE_PTES - 1) /
+ GSP_PHYS_RMCALL_GUEST_PT_CACHE_PTES);
+ base_line = boot_stage.rmcall_guest_pt_next_line;
+ if (!nlines || base_line + nlines > GSP_PHYS_RMCALL_GUEST_PT_TOTAL_LINES)
+ return false;
+ first_va = gsp_phys_rmcall_guest_pt_win_va(
+ base_line / GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE) +
+ ((u64)(base_line %
+ GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE) << 16);
+ last_va = gsp_phys_rmcall_guest_pt_win_va(
+ (base_line + nlines - 1u) /
+ GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE) +
+ ((u64)((base_line + nlines - 1u) %
+ GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE) << 16);
+ if (last_va != first_va + ((u64)(nlines - 1u) << 16))
+ return false;
+ boot_stage.rmcall_guest_pt_next_line = base_line + nlines;
+ for (i = 0; i < nlines; i++) {
+ u32 line = base_line + i;
+ u32 page = line / GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE;
+ u32 lip = line % GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE;
+ u8 *pt;
+
+ if (gsp_phys_rmcall_gr_scratch_win_install_locked(page))
+ return false;
+ pt = gsp_phys_rmcall_guest_pt_page_va(page);
+ if (!pt)
+ return false;
+ for (j = 0; j < GSP_PHYS_RMCALL_GUEST_PT_CACHE_PTES; j++) {
+ u64 k = (u64)i * GSP_PHYS_RMCALL_GUEST_PT_CACHE_PTES +
+ j;
+ u64 pv, hpa = 0;
+ u32 pi;
+
+ if (k >= map_pages)
+ break;
+ pv = page_va + (k << 12);
+ for (pi = 0; pi < req->n_pages; pi++) {
+ if ((req->pages[pi].guest_va &
+ ~(u64)(GSP_PHYS_PAGE_SIZE - 1)) == pv &&
+ req->pages[pi].hpa) {
+ hpa = req->pages[pi].hpa;
+ break;
+ }
+ }
+ if (!hpa) {
+ struct gsp_sema_gr_reloc r;
+
+ if (!gsp_sema_gr_reloc_resolve(pv, &r) && r.hpa)
+ hpa = r.hpa;
+ }
+ if (!hpa)
+ hpa = gsp_phys_gr_surf_dummy_dma_locked();
+ if (!hpa)
+ return false;
+ put_unaligned_le64(gsp_phys_rmcall_pte(hpa),
+ pt + (size_t)(GSP_PHYS_RMCALL_GUEST_PT_CACHE_PTES *
+ lip + j) * 8);
+ }
+ dma_wmb();
+ }
+ gsp_phys_gr_cb_alias_va = page_va;
+ gsp_phys_gr_cb_alias_base = first_va;
+ gsp_phys_gr_cb_alias_valid = true;
+ if (gsp_phys_gr_cb_alias_log < 8u) {
+ gsp_phys_gr_cb_alias_log++;
+ pr_info("vgsp-gr: MME-CB-ALIAS va=0x%llx pages=%u -> alias=0x%llx h=0x%x push=0x%llx\n",
+ page_va, map_pages, first_va, req->h_object,
+ req->push_va);
+ }
+ *alias_out = first_va + (va - page_va);
+ return true;
+}
+
+/*
* SESSION 153-CONTINUED-27: pre-pass over a raw 3D window. Scans the
* colour-target runs (C597 INC 0x800+j*0x40 [upper, lower, w, h, fmt,
* blksz] and - same surface, shape seen on the TWOD subchannel - INC