diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-14 19:04:22 -0500 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-11-14 19:04:22 -0500 |
| commit | 0b06e5516816b24a617faeddcfe7f3fc3663ff62 (patch) | |
| tree | 5bebfda8032208ff39d7817d8d8700da32635bd1 /kernel | |
| parent | 8524835fe1efe529796fcf48e38b49dc9d556a3c (diff) | |
| download | open-iov-0b06e5516816b24a617faeddcfe7f3fc3663ff62.tar.gz open-iov-0b06e5516816b24a617faeddcfe7f3fc3663ff62.zip | |
vgsp: alias a contiguous 7-page fixed-CB region in the scratch PT pool (sema_gl_mme_cb_alias, default 0) (eng45)
Macro 57 (LOAD_CONSTANT_BUFFER) reads the 0x7000-byte fixed CB at
seed-shadow +0x5000, but only the single seed page was mapped (the
pre-existing fixed-CB+0x4000 class), producing FAULT_PTE VIRT_READ at
0x0_015a5000 11 ms after the released calls (post-REARM). The alias maps a
contiguous 7-page region in the scratch PT pool (page 0 = CB image/MVP;
unservable tail = dummy zero page), wired into the scratch-0x18 and d19
seed paths, logged MME-CB-ALIAS. Safety-validated c654 (alias exercised,
0 MMU faults, 0 badf1201, 0 poison all boot); the beef macro chain was not
reproduced in-window, so end-to-end validation is pending.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 159 |
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 |
