From 6aeb72dd60aec44325d293963156f6c90f7de9f0 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 7 Oct 2026 15:05:08 -0400 Subject: vgsp: m106 - pre-install the data PT window pool in stage 3 (pre-commit) Post-commit UPDATE_PDE_2 installs are accepted (status 0x0) but ineffective (m94's scratch windows, m101-m105's reloc windows: the SM never resolves them), while the stage-3 ctx-window installs are honoured. Add a fixed 32-window pool at GSP_PHYS_RMCALL_VA_GR_DATA_BASE (0x100000000 + k<<21, inside the server-managed region), each backed by a module PT page installed through UPDATE_PDE_2 during stage 3; the engine data map then only writes leaf PTEs into those fresh PT pages at launch (the P6b-proven 'direct leaf write into a walker-installed fresh table' pattern). The mail injection uses the reserved last window (k=31); service data windows cap at 31 and use the same fixed layout. --- kernel/gsp_phys_booter.c | 99 +++++++++++++++++++++++++++++++++++++++++++---- kernel/gsp_phys_gpu.c | 20 ++++++++++ kernel/gsp_phys_gpu.h | 3 ++ kernel/gsp_sema_service.c | 2 +- 4 files changed, 115 insertions(+), 9 deletions(-) diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 5639030..ef192be 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -1021,6 +1021,14 @@ bool gsp_phys_boot_requested(void) #define GSP_PHYS_RMCALL_GR_DATA_PD1_MAX 4u #define GSP_PHYS_RMCALL_GR_DATA_PD0_MAX 8u #define GSP_PHYS_RMCALL_GR_DATA_PT_MAX 64u +/* + * m106: fixed pre-installed data window pool: GSP_PHYS_RMCALL_GR_DATA_WINS + * windows starting at GSP_PHYS_RMCALL_VA_GR_DATA_BASE, inside the + * server-managed region [0x100000000, 0x11fffffff). Window k maps at + * BASE + k<<21; the last window is reserved for the mail injection. + */ +#define GSP_PHYS_RMCALL_VA_GR_DATA_BASE 0x100000000ULL +#define GSP_PHYS_RMCALL_GR_DATA_WINS 32u /* * Rank-2 qmdwin diagnostic (gsp_phys_rmcall_gr_qmdwin=1): dedicated module @@ -7314,6 +7322,65 @@ static int gsp_phys_rmcall_map_pt_window(void __iomem *bar0) 0x100u * 8), get_unaligned_le64((u8 *)gsp_phys_chunk_page_va(pt, 0) + 0x101u * 8)); + /* + * m106: pre-install the fixed data PT pool before the channel commit + * (see gsp_phys_rmcall_gr_data_prewin). Each pool window's PT page is + * installed through the server walker here; the leaf PTEs are written + * at launch, so the first kernel-time walk sees freshly installed + * tables. This mirrors the ctx-window installs above, which the + * engine honours (post-commit installs are accepted but ineffective). + */ + if (gsp_phys_rmcall_gr_data_prewin_value()) { + struct gsp_phys_rmcall_update_pde2_params dp; + unsigned int k; + + for (k = 0; k < GSP_PHYS_RMCALL_GR_DATA_WINS; k++) { + struct gsp_phys_boot_chunk *dpt = + &boot_stage.rmcall_gr_data_pt[k]; + u32 didx = (u32)((GSP_PHYS_RMCALL_VA_GR_DATA_BASE >> + 21) + k); + + if (!dpt->pages) { + if (gsp_phys_chunk_alloc(boot_stage.pdev, dpt, + 1u)) + return -ENOMEM; + gsp_phys_chunk_zero(dpt); + } + memset(&dp, 0, sizeof(dp)); + dp.pde_index = cpu_to_le32(didx); + dp.flags = cpu_to_le32(GSP_PHYS_RMCALL_PDE2_FLAG_FLUSH); + dp.pt[0].phys_addr = cpu_to_le64((u64) + gsp_phys_chunk_page_dma(dpt, 0)); + dp.pt[0].aperture = + cpu_to_le32(GSP_PHYS_RMCALL_PDE2_APERTURE_SYS_COH); + dp.pt[1].aperture = + cpu_to_le32(GSP_PHYS_RMCALL_PDE2_APERTURE_INVALID); + dp.h_va_space = cpu_to_le32(boot_stage.rmcall_vas); + rpc_result = 0; + status = 0; + ret = gsp_phys_rmcall_control(bar0, + boot_stage.rmcall_device, + GSP_PHYS_RMCALL_CTRL_DMA_UPDATE_PDE_2, + &dp, sizeof(dp), sizeof(dp), &dp, + sizeof(dp), &rpc_result, &status, + "DMA_UPDATE_PDE_2 (data pool)"); + if (ret) { + pr_err("vgsp-boot: rm-call: data pool window %u rejected: status=0x%x rpc_result=0x%x ret=%d; aborting with no retry\n", + didx, status, rpc_result, ret); + return ret; + } + /* the install may zero the PT page; leaves come later */ + gsp_phys_chunk_zero(dpt); + } + pr_info("vgsp-boot: rm-call: data PT pool installed: %u windows at pdeIndex %u..%u (VA 0x%llx..0x%llx)\n", + GSP_PHYS_RMCALL_GR_DATA_WINS, + (u32)(GSP_PHYS_RMCALL_VA_GR_DATA_BASE >> 21), + (u32)((GSP_PHYS_RMCALL_VA_GR_DATA_BASE >> 21) + + GSP_PHYS_RMCALL_GR_DATA_WINS - 1), + GSP_PHYS_RMCALL_VA_GR_DATA_BASE, + GSP_PHYS_RMCALL_VA_GR_DATA_BASE + + ((u64)GSP_PHYS_RMCALL_GR_DATA_WINS - 1) * 0x200000ULL); + } return 0; } @@ -16205,13 +16272,27 @@ static void gsp_phys_gr_rewrite_data_vars(u32 *w, u32 n_words, static int gsp_phys_rmcall_gr_data_map(void __iomem *bar0, u64 va, u64 hpa, u32 epoch) { - int ret = gsp_phys_rmcall_gr_map_va_locked(bar0, va, hpa, epoch); + struct gsp_phys_boot_chunk *pt; + u32 k, ip; + u64 pte; - if (ret) { - pr_err_ratelimited("vgsp-gr: data Tier-1 map refused va=0x%llx hpa=0x%llx ret=%d\n", - va, hpa, ret); - return ret; - } + (void)bar0; + (void)epoch; + if (va < GSP_PHYS_RMCALL_VA_GR_DATA_BASE) + return -ERANGE; + k = (u32)((va - GSP_PHYS_RMCALL_VA_GR_DATA_BASE) >> 21); + if (k >= GSP_PHYS_RMCALL_GR_DATA_WINS) + return -ERANGE; + pt = &boot_stage.rmcall_gr_data_pt[k]; + if (!pt->pages) + return -EIO; + ip = (u32)((va >> 12) & 0x1ffu); + pte = gsp_phys_rmcall_pte(hpa); + if (gsp_phys_rmcall_gr_pte_kind_value()) + pte |= (u64)gsp_phys_rmcall_gr_pte_kind_value() << 56; + put_unaligned_le64(pte, (u8 *)gsp_phys_chunk_page_va(pt, 0) + + (size_t)ip * 8); + dma_wmb(); boot_stage.rmcall_gr_data_pages++; return 0; } @@ -16554,7 +16635,9 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req, if (!w[0] && !w[1]) { static const char mail[] = "the little gpu man says you've got mail"; - u64 mva = 0x11ff00000ULL; + u64 mva = GSP_PHYS_RMCALL_VA_GR_DATA_BASE + + ((u64)GSP_PHYS_RMCALL_GR_DATA_WINS - 1) + << 21; if (!boot_stage.rmcall_gr_mail.pages && !gsp_phys_chunk_alloc(boot_stage.pdev, @@ -16568,7 +16651,7 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req, dma_wmb(); } if (boot_stage.rmcall_gr_mail.pages && - !gsp_phys_rmcall_gr_map_va_locked( + !gsp_phys_rmcall_gr_data_map( bar0, mva, (u64)gsp_phys_chunk_page_dma( &boot_stage.rmcall_gr_mail, 0), diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c index a350ed9..e92e5f1 100644 --- a/kernel/gsp_phys_gpu.c +++ b/kernel/gsp_phys_gpu.c @@ -1029,6 +1029,26 @@ int gsp_phys_rmcall_gr_mail_patch_value(void) } EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_mail_patch_value); +/* + * m106: pre-install the fixed data PT pool (32 windows at + * GSP_PHYS_RMCALL_VA_GR_DATA_BASE) during stage 3, before the channel + * commit. Post-commit UPDATE_PDE_2 installs are accepted but ineffective + * (m101-m105); the ctx-window installs show the pre-commit path is the + * one the engine honours. Launch-time work is then only leaf PTE writes + * into these freshly installed PT pages. Default 0. + */ +static int gsp_phys_rmcall_gr_data_prewin_param; +module_param_named(gsp_phys_rmcall_gr_data_prewin, + gsp_phys_rmcall_gr_data_prewin_param, int, 0644); +MODULE_PARM_DESC(gsp_phys_rmcall_gr_data_prewin, + "Pre-install the data PT window pool in stage 3 (default 0)"); + +int gsp_phys_rmcall_gr_data_prewin_value(void) +{ + return gsp_phys_rmcall_gr_data_prewin_param; +} +EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_data_prewin_value); + /* * m95: program each GPC's MMU_CTRL from the hub's PFB MMU_CTRL (the real RM's * grInitGPCMmuPRIRegs matching-fields copy) before a forwarded launch. The diff --git a/kernel/gsp_phys_gpu.h b/kernel/gsp_phys_gpu.h index e83220a..b7c8cd4 100644 --- a/kernel/gsp_phys_gpu.h +++ b/kernel/gsp_phys_gpu.h @@ -349,6 +349,9 @@ int gsp_phys_rmcall_gr_pte_kind_value(void); /* m104: inject the mail_kernel message page when bank-4 is empty. */ int gsp_phys_rmcall_gr_mail_patch_value(void); +/* m106: pre-install the data PT window pool in stage 3. */ +int gsp_phys_rmcall_gr_data_prewin_value(void); + /* m72: append the vendor local-memory context block to the GR prelude so * SKEDCHECK05 LOCAL_MEMORY_TOTAL_SIZE passes (default 0); base VA and * per-TPC size are overridable for A/B runs. */ diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index dfc9922..844d2c9 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3263,7 +3263,7 @@ struct svc_gr_data { * managed region at an affine-relocated VA and the pointers in the bank * pages are rewritten to match. */ -#define SVC_GR_DATA_WINS_MAX 64 +#define SVC_GR_DATA_WINS_MAX 31 struct svc_gr_data_win { u64 va_base; /* guest window base (2 MB aligned) */ u64 reloc_base; /* relocated window base */ -- cgit v1.2.3