diff options
Diffstat (limited to 'kernel/gsp_phys_booter.c')
| -rw-r--r-- | kernel/gsp_phys_booter.c | 51 |
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++; |
