From f90b1a123a60dea44ac98f05529ec2fd545c26eb Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 5 Oct 2026 12:15:30 -0400 Subject: vgsp: GR shared path ctx-window PDE install and PATCH+MAIN PA-only promote fallback - UPDATE_PDE_2 now also installs the GR context window PT pages (PDE 17+). - The shared-path fallback promotes PATCH then MAIN PA-only (mode-13 order, the real client's set); the mapped (bNonmapped=0) entry still hits the known 0x40 structural gate and is not sent. - Shared+srvctx: channel/BIND/schedule/token/GPFIFO fetch all green; the remaining failure is ROBUST_CHANNEL_GR_FAULT_DURING_CTXSW (0x2c). --- kernel/gsp_phys_booter.c | 67 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 7 deletions(-) diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index aed4c67..223420f 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -6356,6 +6356,7 @@ static int gsp_phys_rmcall_map_pt_window(void __iomem *bar0) struct gsp_phys_rmcall_update_pde2_params p; u32 rpc_result = 0, status = 0; u64 pt_pa = (u64)gsp_phys_chunk_page_dma(pt, 0); + u32 i; int ret; if (!boot_stage.rmcall_vas) { @@ -6404,6 +6405,41 @@ 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)); + /* + * Install the GR context window PT pages too (VA 0x2200000 window + * number 17 + i), so the engine can load/restore the context through + * the mapped VA the promote installs. + */ + for (i = 0; i < boot_stage.rmcall_ctx_pt_pages; i++) { + u32 ctx_index = (u32)((GSP_PHYS_RMCALL_VA_GR_CTX >> 21) + i); + u64 ctx_pt_pa = (u64)gsp_phys_chunk_page_dma( + &boot_stage.rmcall_ctx_pt[i], 0); + + memset(&p, 0, sizeof(p)); + p.pde_index = cpu_to_le32(ctx_index); + p.flags = cpu_to_le32(GSP_PHYS_RMCALL_PDE2_FLAG_FLUSH); + p.pt[0].phys_addr = cpu_to_le64(ctx_pt_pa); + p.pt[0].aperture = + cpu_to_le32(GSP_PHYS_RMCALL_PDE2_APERTURE_SYS_COH); + p.pt[1].aperture = + cpu_to_le32(GSP_PHYS_RMCALL_PDE2_APERTURE_INVALID); + p.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, + &p, sizeof(p), sizeof(p), &p, sizeof(p), + &rpc_result, &status, + "DMA_UPDATE_PDE_2 (ctx window)"); + if (ret) { + pr_err("vgsp-boot: rm-call: DMA_UPDATE_PDE_2 ctx window %u rejected: status=0x%x rpc_result=0x%x ret=%d; aborting with no retry\n", + ctx_index, status, rpc_result, ret); + return ret; + } + pr_info("vgsp-boot: rm-call: DMA_UPDATE_PDE_2 ctx window accepted: pdeIndex=%u ptPa=0x%llx status=0x%x\n", + ctx_index, ctx_pt_pa, status); + } /* * Belt-and-braces: rewrite the PT contents after the walker install * (the install must not be allowed to leave the externally supplied PT @@ -8859,8 +8895,8 @@ static int gsp_phys_rmcall_srv_ctx_commit(void __iomem *bar0) main_pa = boot_stage.rmcall_ctx_pa; main_size = boot_stage.rmcall_ctx_size; pa_attr = GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR; - pr_warn("vgsp-boot: rm-call: server MAIN ctx buffer was not reported; committing the CLIENT MAIN buffer pa=0x%llx size=0x%llx PA-only instead\n", - main_pa, main_size); + pr_warn("vgsp-boot: rm-call: server MAIN ctx buffer was not reported; committing the CLIENT MAIN buffer pa=0x%llx size=0x%llx mapped (VA 0x%llx, PDE installed) instead\n", + main_pa, main_size, GSP_PHYS_RMCALL_VA_GR_CTX); } ic = kvzalloc(sizeof(*ic), GFP_KERNEL); @@ -8899,9 +8935,25 @@ static int gsp_phys_rmcall_srv_ctx_commit(void __iomem *bar0) p->h_virt_memory = cpu_to_le32(0); p->virt_address = cpu_to_le64(0); p->size = cpu_to_le64(0); - p->entry_count = cpu_to_le32(1); - gsp_phys_rmcall_promote_entry_fill(p, 0, 0, - main_pa, 0, main_size, pa_attr, 1, 1); + /* + * The real client's promote set always contains PATCH; promote it + * PA-only before MAIN (mode 13 order). Preparation is lazy and + * bounded; a failure just drops the PATCH entry. + */ + if (gsp_phys_rmcall_gr_patch_prepare(bar0) == 0 && + boot_stage.rmcall_patch_size != 0) { + gsp_phys_rmcall_promote_entry_fill(p, 0, 2, + boot_stage.rmcall_patch_pa, 0, + boot_stage.rmcall_patch_size, + GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR, 1, 1); + gsp_phys_rmcall_promote_entry_fill(p, 1, 0, + main_pa, 0, main_size, pa_attr, 1, 1); + p->entry_count = cpu_to_le32(2); + } else { + gsp_phys_rmcall_promote_entry_fill(p, 0, 0, + main_pa, 0, main_size, pa_attr, 1, 1); + p->entry_count = cpu_to_le32(1); + } rpc_result = 0; status = 0; ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_subdevice, @@ -8909,8 +8961,9 @@ static int gsp_phys_rmcall_srv_ctx_commit(void __iomem *bar0) p, sizeof(*p), 24, NULL, 0, &rpc_result, &status, "GPU_PROMOTE_CTX (server MAIN PA-only)"); - pr_info("vgsp-boot: rm-call: MAIN PROMOTE_CTX: entry{bufferId=MAIN pa=0x%llx size=0x%llx physAttr=0x%x bInitialize=1 bNonmapped=1} status=0x%x rpc_result=0x%x ret=%d\n", - main_pa, main_size, pa_attr, status, rpc_result, ret); + pr_info("vgsp-boot: rm-call: MAIN PROMOTE_CTX: entries=%u entry{MAIN pa=0x%llx size=0x%llx physAttr=0x%x bInitialize=1 bNonmapped=1} status=0x%x rpc_result=0x%x ret=%d\n", + le32_to_cpu(p->entry_count), main_pa, main_size, pa_attr, + status, rpc_result, ret); kvfree(p); return ret; } -- cgit v1.2.3