From c7f5f7116a2a7e38506cf3c9ea2d5346cc3d681a Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Mon, 5 Oct 2026 19:34:47 -0400 Subject: vgsp: golden9e - all ctx buffers FBMEM and every promoted VA PDB-mapped The golden9c cycle reached the server context init and then the GR ctxsw timed out (FECS_A/B TDR) with host-sysmem MAIN/PATCH/FECS/PRIV/UNR and unmapped promoted VAs; the golden9d FBMEM test ran on a boot left dirty by golden9c and its 0x1f is not attributable. The real golden wire carried FBMEM (physAttr=4) for every ctx buffer, so: - allocate PATCH/FECS/PRIV/UNR as server FBMEM (PATCH sized by the engine geometry query) in gr_ctx_prepare before the PDB build (mode 25 only); - map PATCH/FECS/PRIV/UNR at their promoted VAs with VIDMEM PTEs in the same 2 MB window as MAIN; - move the FECS/PRIV/UNR and VA-only 3D global VAs into that window and give the PA-backed entries PHYS_ATTR_FB. golden9d's FBMEM channel memdescs are kept. --- kernel/gsp_phys_booter.c | 195 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 183 insertions(+), 12 deletions(-) diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 36a71d0..daf0714 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -390,6 +390,29 @@ bool gsp_phys_boot_requested(void) * 32 MB but the live server MAIN is 0x133000; PATCH lives at +0x140000 to * stay clear of MAIN's tail). */ #define GSP_PHYS_RMCALL_VA_GR_PATCH (GSP_PHYS_RMCALL_VA_GR_CTX + 0x140000ULL) +/* + * Golden9e (mode 25): the promoted FECS/PRIV/UNR buffers and the VA-only + * 3D globals are placed inside the same 2 MB window as MAIN/PATCH so every + * promoted VA is backed by the ctx PDB page tables (the real golden client + * mapped all of them in its VAS; the earlier mode-25 replay wrote unmapped + * VAs, which can fault the engine context load). + */ +#define GSP_PHYS_RMCALL_VA_GOLDEN9_FECS (GSP_PHYS_RMCALL_VA_GR_CTX + 0x150000ULL) +#define GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV (GSP_PHYS_RMCALL_VA_GR_CTX + 0x151000ULL) +#define GSP_PHYS_RMCALL_VA_GOLDEN9_UNR (GSP_PHYS_RMCALL_VA_GR_CTX + 0x152000ULL) +#define GSP_PHYS_RMCALL_VA_GOLDEN9_BUNDLE_CB (GSP_PHYS_RMCALL_VA_GR_CTX + 0x153000ULL) +#define GSP_PHYS_RMCALL_VA_GOLDEN9_PAGEPOOL (GSP_PHYS_RMCALL_VA_GR_CTX + 0x154000ULL) +#define GSP_PHYS_RMCALL_VA_GOLDEN9_ATTRIBUTE_CB (GSP_PHYS_RMCALL_VA_GR_CTX + 0x155000ULL) +#define GSP_PHYS_RMCALL_VA_GOLDEN9_RTV_CB_GLOBAL (GSP_PHYS_RMCALL_VA_GR_CTX + 0x156000ULL) +/* + * Golden9e server FBMEM allocations for the small promoted buffers (PATCH is + * sized by the PATCH engine geometry query; FECS/PRIV/UNR are one 4 KB page + * each). The real golden wire carried all of them in FBMEM. + */ +#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PATCH 0xcaf00064u +#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_FECS 0xcaf00068u +#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PRIV 0xcaf0006cu +#define GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_UNR 0xcaf00070u /* GR context-promote bisection modes (gsp_phys_rmcall_gr_promote). */ #define GSP_PHYS_RMCALL_GR_PROMOTE_OFF 0u @@ -1483,6 +1506,8 @@ static struct gsp_phys_boot_stage { bool rmcall_ctx_valid; /* mode 11: the context buffer is a server-owned FBMEM allocation */ bool rmcall_ctx_fbmem; + /* mode 25 golden9e: PATCH/FECS/PRIV/UNR are server-owned FBMEM too */ + bool rmcall_golden_fb_aux; u64 rmcall_ctx_pa; /* context buffer DMA base */ u64 rmcall_ctx_va; /* promoted GPU VA window base */ u32 rmcall_ctx_size; /* promoted total size */ @@ -2175,6 +2200,7 @@ static void gsp_phys_rmcall_reset(void) boot_stage.rmcall_ctx_prepared = false; boot_stage.rmcall_ctx_valid = false; boot_stage.rmcall_ctx_fbmem = false; + boot_stage.rmcall_golden_fb_aux = false; boot_stage.rmcall_ctx_pa = 0; boot_stage.rmcall_ctx_va = 0; boot_stage.rmcall_ctx_size = 0; @@ -8280,6 +8306,55 @@ static void gsp_phys_rmcall_pdb_build(void) &boot_stage.rmcall_ctx_pt[pt_page], 0) + (size_t)pt_slot * 8); } + /* + * Golden9e: map the FBMEM PATCH/FECS/PRIV/UNR buffers at their + * promoted VAs in the same 2 MB window as MAIN (window 17) with + * VIDMEM PTEs. Every slot used here is above MAIN's tail + * (0x2200000 + 0x133000 = slot 0x133) and distinct. + */ + if (boot_stage.rmcall_golden_fb_aux) { + u8 *ptv = gsp_phys_chunk_page_va( + &boot_stage.rmcall_ctx_pt[0], 0); + u32 slot, npages; + + npages = DIV_ROUND_UP(boot_stage.rmcall_patch_size, + GSP_PHYS_PAGE_SIZE); + slot = (u32)((GSP_PHYS_RMCALL_VA_GR_PATCH >> 12) & + 0x1ffu); + for (i = 0; i < npages; i++) + put_unaligned_le64( + gsp_phys_rmcall_pte_vid( + boot_stage.rmcall_patch_pa + + (u64)i * GSP_PHYS_PAGE_SIZE), + ptv + (size_t)(slot + i) * 8); + slot = (u32)((GSP_PHYS_RMCALL_VA_GOLDEN9_FECS >> 12) & + 0x1ffu); + put_unaligned_le64( + gsp_phys_rmcall_pte_vid( + boot_stage.rmcall_fecs_pa), + ptv + (size_t)slot * 8); + slot = (u32)((GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV >> 12) & + 0x1ffu); + put_unaligned_le64( + gsp_phys_rmcall_pte_vid( + boot_stage.rmcall_priv_pa), + ptv + (size_t)slot * 8); + slot = (u32)((GSP_PHYS_RMCALL_VA_GOLDEN9_UNR >> 12) & + 0x1ffu); + put_unaligned_le64( + gsp_phys_rmcall_pte_vid( + boot_stage.rmcall_unrestricted_pa), + ptv + (size_t)slot * 8); + pr_info("vgsp-boot: rm-call: GOLDEN9E PDB aux mapped: patch va=0x%llx pages=%u (pa=0x%llx) fecs va=0x%llx (pa=0x%llx) priv va=0x%llx (pa=0x%llx) unr va=0x%llx (pa=0x%llx) (VIDMEM PTEs)\n", + GSP_PHYS_RMCALL_VA_GR_PATCH, npages, + boot_stage.rmcall_patch_pa, + GSP_PHYS_RMCALL_VA_GOLDEN9_FECS, + boot_stage.rmcall_fecs_pa, + GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV, + boot_stage.rmcall_priv_pa, + GSP_PHYS_RMCALL_VA_GOLDEN9_UNR, + boot_stage.rmcall_unrestricted_pa); + } pr_info("vgsp-boot: rm-call: GR ctx PDB mapped: va=0x%llx size=0x%x pages=%u ptPages=%u pd0Entries=%u..%u (%s; fresh slots above the scratch pool; no fetched line rewritten)\n", GSP_PHYS_RMCALL_VA_GR_CTX, boot_stage.rmcall_ctx_size, boot_stage.rmcall_ctx_pages, @@ -8337,6 +8412,82 @@ static void gsp_phys_rmcall_pdb_build(void) GSP_PHYS_RMCALL_GUEST_PT_LINES_PER_PAGE); } +/* + * Mode-25 golden9e: allocate the promoted PATCH/FECS/PRIV/UNR context + * buffers in server FBMEM (the real golden wire carried FBMEM for every + * context buffer; the earlier host-sysmem substitution is a documented + * deviation that leaves the engine's context load reading host memory). + * PATCH is sized by the PATCH engine geometry query (engineId 0x10); the + * three global buffers are one 4 KB page each. Runs before + * gsp_phys_rmcall_pdb_build() so the PDB can map every promoted VA in the + * same 2 MB window as MAIN. Idempotent; a failure aborts the ladder. + */ +static int gsp_phys_rmcall_golden9_fb_aux_prepare(void __iomem *bar0) +{ + struct gsp_phys_rmcall_engine_ctx_props props; + u32 raw, rpc_result = 0, status = 0; + u64 fb = 0; + int ret; + + if (boot_stage.rmcall_golden_fb_aux) + return 0; + + memset(&props, 0, sizeof(props)); + props.engine_id = cpu_to_le32(GSP_PHYS_RMCALL_GR_PATCH_ENGINE_ID); + ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_device, + GSP_PHYS_RMCALL_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES, + &props, sizeof(props), 24 + sizeof(props), + &props, sizeof(props), &rpc_result, &status, + "GR_GET_ENGINE_CONTEXT_PROPERTIES (golden9e PATCH)"); + raw = le32_to_cpu(props.size); + pr_info("vgsp-boot: rm-call: GOLDEN9E PATCH geometry: engineId=0x%x rawSize=0x%x alignment=0x%x status=0x%x rpc_result=0x%x\n", + GSP_PHYS_RMCALL_GR_PATCH_ENGINE_ID, raw, + le32_to_cpu(props.alignment), status, rpc_result); + if (ret) + return ret; + if (!raw || raw > GSP_PHYS_RMCALL_GR_CTX_MAX_SIZE) { + pr_err("vgsp-boot: rm-call: GOLDEN9E PATCH size 0x%x is outside the sanity bound; aborting the ladder with no retry\n", + raw); + return -E2BIG; + } + ret = gsp_phys_rmcall_alloc_fb_mem(bar0, + GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PATCH, raw, &fb, + "GOLDEN9E PATCH"); + if (ret) + return ret; + boot_stage.rmcall_patch_pa = fb; + boot_stage.rmcall_patch_size = raw; + boot_stage.rmcall_patch_prepared = true; + + ret = gsp_phys_rmcall_alloc_fb_mem(bar0, + GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_FECS, 0x1000, &fb, + "GOLDEN9E FECS_EVENT"); + if (ret) + return ret; + boot_stage.rmcall_fecs_pa = fb; + + ret = gsp_phys_rmcall_alloc_fb_mem(bar0, + GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_PRIV, 0x1000, &fb, + "GOLDEN9E PRIV_ACCESS_MAP"); + if (ret) + return ret; + boot_stage.rmcall_priv_pa = fb; + + ret = gsp_phys_rmcall_alloc_fb_mem(bar0, + GSP_PHYS_RMCALL_HANDLE_GOLDEN_FB_UNR, 0x1000, &fb, + "GOLDEN9E UNR_PRIV_ACCESS_MAP"); + if (ret) + return ret; + boot_stage.rmcall_unrestricted_pa = fb; + + boot_stage.rmcall_golden_fb_aux = true; + pr_info("vgsp-boot: rm-call: GOLDEN9E FBMEM aux buffers ready: patch pa=0x%llx size=0x%x fecs=0x%llx priv=0x%llx unr=0x%llx (server FBMEM, all mapped in the ctx PDB window)\n", + boot_stage.rmcall_patch_pa, boot_stage.rmcall_patch_size, + boot_stage.rmcall_fecs_pa, boot_stage.rmcall_priv_pa, + boot_stage.rmcall_unrestricted_pa); + return 0; +} + /* * H1 GR context bind, step 1-2: query the engine-context geometry, then * allocate the zeroed, physically contiguous sysmem context buffer the @@ -8522,6 +8673,19 @@ static int gsp_phys_rmcall_gr_ctx_prepare(void __iomem *bar0) boot_stage.rmcall_ctx_fbmem ? "server FBMEM, VIDMEM aperture PTEs" : "host sysmem, contiguous, zeroed"); + /* + * Mode-25 golden9e: prepare the FBMEM PATCH/FECS/PRIV/UNR buffers now, + * before the PDB build maps their promoted VAs. + */ + if (boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9) { + ret = gsp_phys_rmcall_golden9_fb_aux_prepare(bar0); + if (ret) { + pr_err("vgsp-boot: rm-call: GOLDEN9E FBMEM aux prepare failed (%d); aborting the ladder with no retry\n", + ret); + return ret; + } + } return 0; err_free: @@ -8787,8 +8951,8 @@ static void gsp_phys_rmcall_gr_fwclient_small_prepare(void) static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0) { struct gsp_phys_rmcall_promote_params *p; - u64 bk = GSP_PHYS_RMCALL_VA_GR_CTX + 0x400000ULL; u32 attr = GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR; + u32 fattr; u32 rpc_result = 0, status = 0; unsigned int i; int ret; @@ -8800,10 +8964,13 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0) boot_stage.rmcall_ctx_pa, boot_stage.rmcall_ctx_size); return -EINVAL; } - ret = gsp_phys_rmcall_gr_patch_prepare(bar0); + /* + * Golden9e: PATCH/FECS/PRIV/UNR are server FBMEM allocations prepared + * with the MAIN (gr_ctx_prepare, before the PDB build). Idempotent. + */ + ret = gsp_phys_rmcall_golden9_fb_aux_prepare(bar0); if (ret) return ret; - gsp_phys_rmcall_gr_fwclient_small_prepare(); if (!boot_stage.rmcall_patch_pa || !boot_stage.rmcall_fecs_pa || !boot_stage.rmcall_priv_pa || !boot_stage.rmcall_unrestricted_pa) { @@ -8813,6 +8980,8 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0) boot_stage.rmcall_unrestricted_pa); return -ENOMEM; } + fattr = boot_stage.rmcall_golden_fb_aux ? + GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR_FB : attr; p = kvzalloc(sizeof(*p), GFP_KERNEL); if (!p) @@ -8834,29 +9003,31 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0) gsp_phys_rmcall_promote_entry_fill(p, 1, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PATCH, boot_stage.rmcall_patch_pa, GSP_PHYS_RMCALL_VA_GR_PATCH, - boot_stage.rmcall_patch_size, attr, 1, 0); + boot_stage.rmcall_patch_size, fattr, 1, 0); gsp_phys_rmcall_promote_entry_fill(p, 2, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_BUNDLE_CB, - 0, bk + 0x2000ULL, 0, 0, 0, 0); + 0, GSP_PHYS_RMCALL_VA_GOLDEN9_BUNDLE_CB, 0, 0, 0, 0); gsp_phys_rmcall_promote_entry_fill(p, 3, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PAGEPOOL, - 0, bk + 0x3000ULL, 0, 0, 0, 0); + 0, GSP_PHYS_RMCALL_VA_GOLDEN9_PAGEPOOL, 0, 0, 0, 0); gsp_phys_rmcall_promote_entry_fill(p, 4, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_ATTRIBUTE_CB, - 0, bk + 0x4000ULL, 0, 0, 0, 0); + 0, GSP_PHYS_RMCALL_VA_GOLDEN9_ATTRIBUTE_CB, 0, 0, 0, 0); gsp_phys_rmcall_promote_entry_fill(p, 5, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_RTV_CB_GLOBAL, - 0, bk + 0x5000ULL, 0, 0, 0, 0); + 0, GSP_PHYS_RMCALL_VA_GOLDEN9_RTV_CB_GLOBAL, 0, 0, 0, 0); gsp_phys_rmcall_promote_entry_fill(p, 6, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_FECS_EVENT, - boot_stage.rmcall_fecs_pa, bk + 0x6000ULL, 0x1000u, attr, 1, 0); + boot_stage.rmcall_fecs_pa, GSP_PHYS_RMCALL_VA_GOLDEN9_FECS, + 0x1000u, fattr, 1, 0); gsp_phys_rmcall_promote_entry_fill(p, 7, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_PRIV_MAP, - boot_stage.rmcall_priv_pa, bk + 0x7000ULL, 0x1000u, attr, 1, 0); + boot_stage.rmcall_priv_pa, GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV, + 0x1000u, fattr, 1, 0); gsp_phys_rmcall_promote_entry_fill(p, 8, GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_UNR_PRIV_MAP, - boot_stage.rmcall_unrestricted_pa, bk + 0x8000ULL, - 0x1000u, attr, 1, 0); + boot_stage.rmcall_unrestricted_pa, GSP_PHYS_RMCALL_VA_GOLDEN9_UNR, + 0x1000u, fattr, 1, 0); for (i = 0; i < 9; i++) pr_info("vgsp-boot: rm-call: PROMOTE_CTX golden9 entry[%u]: bufferId=%u pa=0x%llx va=0x%llx size=0x%llx physAttr=0x%x bInitialize=%u bNonmapped=%u%s\n", -- cgit v1.2.3