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.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 04788d2..53932d4 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -1104,8 +1104,8 @@ bool gsp_phys_boot_requested(void)
* inline writes. Both are deliberately outside rmcall_chunks so the COPY0
* stage-2 registration walk stays byte-identical.
*/
-#define GSP_PHYS_RMCALL_GR_PT_PAGES 8u
-#define GSP_PHYS_RMCALL_GR_PT_ENTRIES 32u
+#define GSP_PHYS_RMCALL_GR_PT_PAGES 32u
+#define GSP_PHYS_RMCALL_GR_PT_ENTRIES 512u
#define GSP_PHYS_RMCALL_GR_SHADOW_PAGES 24u
/*
@@ -16151,6 +16151,44 @@ static void gsp_phys_rmcall_gr_gpc_mmu_init(void __iomem *bar0)
* mappings (PITCH does not exist on Turing).
*/
/*
+ * m102: rewrite the data pointers inside a shadowed const-bank page: any
+ * 8-byte value that falls inside a mapped guest data window is replaced by
+ * the affine-relocated server-managed VA (the engine cannot walk the
+ * client-managed guest VAs: UPDATE_PDE_2 refuses them with 0x1f).
+ */
+static void gsp_phys_gr_rewrite_data_vars(u32 *w, u32 n_words,
+ const struct gsp_phys_gr_submit *req,
+ u32 bank)
+{
+ u32 rew = 0, k;
+
+ if (!req->n_data_wins)
+ return;
+ for (k = 0; k + 1 < n_words; k += 2) {
+ u64 v = (u64)w[k] | ((u64)w[k + 1] << 32);
+ u64 wb;
+ u32 x;
+
+ if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 7))
+ continue;
+ wb = v & ~0x1fffffULL;
+ for (x = 0; x < req->n_data_wins; x++) {
+ if (req->data_wins[x].va_base != wb)
+ continue;
+ v = req->data_wins[x].reloc_base |
+ (v & 0x1fffffULL);
+ w[k] = (u32)v;
+ w[k + 1] = (u32)(v >> 32);
+ rew++;
+ break;
+ }
+ }
+ if (rew)
+ pr_info("vgsp-gr: bank %u: %u data pointers relocated\n",
+ bank, rew);
+}
+
+/*
* m101: map one guest data page through the server walker (Tier-1
* DMA_UPDATE_PDE_2), exactly like the launch request pages. On the
* shared-management VAS the client PD0 entries are not preserved by the
@@ -16500,6 +16538,11 @@ int gsp_phys_backend_guest_gr_submit(const struct gsp_phys_gr_submit *req,
GSP_PHYS_PAGE_SIZE);
copied++;
}
+ if (pg->hpa && pg->qmd_word >= 32 && pg->qmd_word <= 47 &&
+ !(pg->qmd_word & 1))
+ gsp_phys_gr_rewrite_data_vars((u32 *)sh_page,
+ GSP_PHYS_PAGE_SIZE / 4, req,
+ (pg->qmd_word - 32) / 2);
/*
* m98: dump the program prologue (qmd_word 48, from
* the QMD's in-page entry offset) and the param/const-0
@@ -16892,7 +16935,9 @@ gr_page_unmapped:
for (di = 0; di < req->n_data; di++) {
if (gsp_phys_rmcall_gr_data_map(bar0,
- req->data[di].va,
+ req->data[di].reloc_va ?
+ req->data[di].reloc_va :
+ req->data[di].va,
req->data[di].hpa,
boot_stage.rmcall_gr_submit_epoch))
dfailed++;