summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_phys_booter.c99
-rw-r--r--kernel/gsp_phys_gpu.c20
-rw-r--r--kernel/gsp_phys_gpu.h3
-rw-r--r--kernel/gsp_sema_service.c2
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
@@ -1030,6 +1030,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
* GPC-side walker refuses the SM I-fetch with MMU_NACK while hub-side reads
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 */