summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 14:31:55 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 14:31:55 -0400
commit6fa955affe6ebca807737fcf1e51673e3859aa47 (patch)
tree0f985554ca4a1f863d3fef60c4da78e8a6a76a71 /kernel/gsp_phys_booter.c
parent0d8f7427b0e21c87e3a5d2b20fbd27c403ea5954 (diff)
downloadopen-iov-6fa955affe6ebca807737fcf1e51673e3859aa47.tar.gz
open-iov-6fa955affe6ebca807737fcf1e51673e3859aa47.zip
vgsp: m101 - route guest data pages through the server walker (Tier-1 map_va_locked)
The scratch-window comment is decisive: on the shared-management VAS the client PD0 entries built by pdb_build are NOT preserved by the server's root migration, so every engine-visible mapping must be installed through DMA_UPDATE_PDE_2 - the m99/m100 direct plants were invisible (same NACK with 16381 pages 'mapped'). Route each data page through gsp_phys_rmcall_gr_map_va_locked (same call the request pages use) and log the per-window acceptance/refusal (server 0x1f) so the high-VA install behavior is measured. The window pool is currently 8 windows x 32 PTEs.
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c141
1 files changed, 22 insertions, 119 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 880299c..04788d2 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -16150,125 +16150,26 @@ static void gsp_phys_rmcall_gr_gpc_mmu_init(void __iomem *bar0)
* carries GENERIC_MEMORY (0x06) in KIND[63:56] like the Turing UVM/RM
* mappings (PITCH does not exist on Turing).
*/
-static struct gsp_phys_boot_chunk *gsp_phys_rmcall_gr_data_pd1_get(u32 i2)
-{
- struct gsp_phys_boot_chunk *pd2 =
- &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_PD2];
- u32 k;
-
- for (k = 0; k < boot_stage.rmcall_gr_data_pd1_n; k++)
- if (boot_stage.rmcall_gr_data_pd1_idx[k] == i2)
- return &boot_stage.rmcall_gr_data_pd1[k];
- if (boot_stage.rmcall_gr_data_pd1_n >= GSP_PHYS_RMCALL_GR_DATA_PD1_MAX)
- return NULL;
- k = boot_stage.rmcall_gr_data_pd1_n;
- if (gsp_phys_chunk_alloc(boot_stage.pdev,
- &boot_stage.rmcall_gr_data_pd1[k], 1))
- return NULL;
- gsp_phys_chunk_zero(&boot_stage.rmcall_gr_data_pd1[k]);
- boot_stage.rmcall_gr_data_pd1_idx[k] = i2;
- boot_stage.rmcall_gr_data_pd1_n++;
- put_unaligned_le64(gsp_phys_rmcall_pde((u64)gsp_phys_chunk_page_dma(
- &boot_stage.rmcall_gr_data_pd1[k], 0)),
- (u8 *)gsp_phys_chunk_page_va(pd2, 0) +
- (size_t)i2 * 8);
- dma_wmb();
- pr_info("vgsp-gr: data-map PD2[%u] -> pd1 dma=0x%llx\n", i2,
- (u64)gsp_phys_chunk_page_dma(&boot_stage.rmcall_gr_data_pd1[k], 0));
- return &boot_stage.rmcall_gr_data_pd1[k];
-}
-
-static struct gsp_phys_boot_chunk *gsp_phys_rmcall_gr_data_pd0_get(u32 i2,
- u32 i1)
-{
- struct gsp_phys_boot_chunk *pd1 = gsp_phys_rmcall_gr_data_pd1_get(i2);
- u32 key = (i2 << 9) | i1;
- u32 k;
-
- if (!pd1)
- return NULL;
- for (k = 0; k < boot_stage.rmcall_gr_data_pd0_n; k++)
- if (boot_stage.rmcall_gr_data_pd0_idx[k] == key)
- return &boot_stage.rmcall_gr_data_pd0[k];
- if (boot_stage.rmcall_gr_data_pd0_n >= GSP_PHYS_RMCALL_GR_DATA_PD0_MAX)
- return NULL;
- k = boot_stage.rmcall_gr_data_pd0_n;
- if (gsp_phys_chunk_alloc(boot_stage.pdev,
- &boot_stage.rmcall_gr_data_pd0[k], 1))
- return NULL;
- gsp_phys_chunk_zero(&boot_stage.rmcall_gr_data_pd0[k]);
- boot_stage.rmcall_gr_data_pd0_idx[k] = key;
- boot_stage.rmcall_gr_data_pd0_n++;
- put_unaligned_le64(gsp_phys_rmcall_pde((u64)gsp_phys_chunk_page_dma(
- &boot_stage.rmcall_gr_data_pd0[k], 0)),
- (u8 *)gsp_phys_chunk_page_va(pd1, 0) +
- (size_t)i1 * 8);
- dma_wmb();
- pr_info("vgsp-gr: data-map PD1[%u] -> pd0 dma=0x%llx (i2=%u)\n", i1,
- (u64)gsp_phys_chunk_page_dma(&boot_stage.rmcall_gr_data_pd0[k], 0),
- i2);
- return &boot_stage.rmcall_gr_data_pd0[k];
-}
-
-static struct gsp_phys_boot_chunk *gsp_phys_rmcall_gr_data_pt_get(u32 i2,
- u32 i1,
- u32 i0)
+/*
+ * 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
+ * server's root migration (see gsp_phys_rmcall_gr_scratch_win_install_locked),
+ * so the m99/m100 direct plants were invisible to the engine; every
+ * engine-visible mapping must be installed through DMA_UPDATE_PDE_2. The
+ * window pool is small (GSP_PHYS_RMCALL_GR_PT_PAGES x GR_PT_ENTRIES), so the
+ * high-VA acceptance/refusal pattern (server 0x1f) is logged per window.
+ */
+static int gsp_phys_rmcall_gr_data_map(void __iomem *bar0, u64 va, u64 hpa,
+ u32 epoch)
{
- struct gsp_phys_boot_chunk *pd0 =
- gsp_phys_rmcall_gr_data_pd0_get(i2, i1);
- u32 key = (i2 << 18) | (i1 << 9) | i0;
- u32 k;
-
- if (!pd0)
- return NULL;
- for (k = 0; k < boot_stage.rmcall_gr_data_pt_n; k++)
- if (boot_stage.rmcall_gr_data_pt_idx[k] == key)
- return &boot_stage.rmcall_gr_data_pt[k];
- if (boot_stage.rmcall_gr_data_pt_n >= GSP_PHYS_RMCALL_GR_DATA_PT_MAX)
- return NULL;
- k = boot_stage.rmcall_gr_data_pt_n;
- if (gsp_phys_chunk_alloc(boot_stage.pdev,
- &boot_stage.rmcall_gr_data_pt[k], 1))
- return NULL;
- gsp_phys_chunk_zero(&boot_stage.rmcall_gr_data_pt[k]);
- boot_stage.rmcall_gr_data_pt_idx[k] = key;
- boot_stage.rmcall_gr_data_pt_n++;
- /* 16 B dual PDE: big half unused, small half -> 4 KB PT. */
- put_unaligned_le64(0,
- (u8 *)gsp_phys_chunk_page_va(pd0, 0) +
- (size_t)i0 * 16);
- put_unaligned_le64(gsp_phys_rmcall_pde((u64)gsp_phys_chunk_page_dma(
- &boot_stage.rmcall_gr_data_pt[k], 0)),
- (u8 *)gsp_phys_chunk_page_va(pd0, 0) +
- (size_t)i0 * 16 + 8);
- dma_wmb();
- pr_info("vgsp-gr: data-map PD0[%u] -> pt dma=0x%llx (i2=%u i1=%u)\n", i0,
- (u64)gsp_phys_chunk_page_dma(&boot_stage.rmcall_gr_data_pt[k], 0),
- i2, i1);
- return &boot_stage.rmcall_gr_data_pt[k];
-}
+ int ret = gsp_phys_rmcall_gr_map_va_locked(bar0, va, hpa, epoch);
-static int gsp_phys_rmcall_gr_data_map(u64 va, u64 hpa)
-{
- struct gsp_phys_boot_chunk *pt;
- u32 r = (u32)((va >> 47) & 0x1u);
- u32 i2 = (u32)((va >> 38) & 0x1ffu);
- u32 i1 = (u32)((va >> 29) & 0x1ffu);
- u32 i0 = (u32)((va >> 21) & 0x1ffu);
- u32 ip = (u32)((va >> 12) & 0x1ffu);
- u64 pte;
-
- if (r != 0)
- return -ERANGE; /* root[0] only; the demo VAs are < 2^47 */
- pt = gsp_phys_rmcall_gr_data_pt_get(i2, i1, i0);
- if (!pt)
- return -ENOSPC;
- 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();
+ 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;
+ }
boot_stage.rmcall_gr_data_pages++;
return 0;
}
@@ -16990,8 +16891,10 @@ gr_page_unmapped:
u32 dmapped = 0, dfailed = 0, di;
for (di = 0; di < req->n_data; di++) {
- if (gsp_phys_rmcall_gr_data_map(req->data[di].va,
- req->data[di].hpa))
+ if (gsp_phys_rmcall_gr_data_map(bar0,
+ req->data[di].va,
+ req->data[di].hpa,
+ boot_stage.rmcall_gr_submit_epoch))
dfailed++;
else
dmapped++;