From 21f09152465337155758f1c4def7770f066e482e Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 6 Oct 2026 16:00:41 -0400 Subject: vgsp: mode 32 - sibling A promote before V6 constructs (compile-verified, untested) --- kernel/gsp_phys_booter.c | 186 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 137 insertions(+), 49 deletions(-) (limited to 'kernel/gsp_phys_booter.c') diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 98b85e8..c5de21e 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -665,6 +665,15 @@ bool gsp_phys_boot_requested(void) * commits V6's instance pointer + RAMFC while V6's own promote is suppressed. */ #define GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT 31u +/* + * Mode 32 (2026-10-06): mode 31 with one ordering change. The TSG-parented + * sibling A's alloc + 9-entry promote run immediately after V6's channel alloc + * and BEFORE V6's GR object constructs (0xc597 on the ladder channel and the + * 0xc5c0 compute object), inverting the mode-31 order whose A commit asserted + * GSP-RM (NOCAT 0x595f724/0x5162778). V6's own promote stays suppressed and + * V6 remains the execution channel. + */ +#define GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY 32u /* * Mode-28 golden execution channel shape bits (gsp_phys_rmcall_golden_exec_shape, * default 7). Every combination keeps the captured flags 0x00200320 and the @@ -779,7 +788,7 @@ bool gsp_phys_boot_requested(void) */ #define GSP_PHYS_RMCALL_FWCLIENT_MASK_FECS_SYSMEM (1u << 16) #define GSP_PHYS_RMCALL_GR_PROMOTE_MAX \ - (GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) + (GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) /* * Work-submit token notifier slot. The default index is @@ -7643,6 +7652,8 @@ static const char *gsp_phys_rmcall_gr_promote_name(void) return "mode 30: clean unwired TSG sibling A (promote + TURING_A first-init) + V6 execution"; case GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT: return "mode 31: mode-25 D first-init + TSG sibling A 9-entry promote after V6 (explicit TSG commit) + V6 execution"; + case GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY: + return "mode 32: mode 31 with the TSG sibling A alloc+promote immediately after V6's alloc and before V6's GR constructs + V6 execution"; default: return "off (PROMOTE_CTX never sent)"; } @@ -7833,7 +7844,9 @@ static int gsp_phys_rmcall_alloc_channel(void __iomem *bar0) boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT)) { + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY)) { vars = &gsp_phys_rmcall_channel_variant_skipctx; attempts = 1; } @@ -8296,7 +8309,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0) boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) && + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) && gsp_phys_rmcall_engine_is_gr()) { if (gsp_phys_rmcall_fwclient_mask_value() & GSP_PHYS_RMCALL_GOLDEN9_MASK_LADDER_VAS) { @@ -8408,7 +8423,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0) boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) && + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) && gsp_phys_rmcall_engine_is_gr()) { ch.flags = cpu_to_le32(GSP_PHYS_RMCALL_CHANNEL_FLAG_GOLDEN9); ch.internal_flags = cpu_to_le32( @@ -8614,7 +8631,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0) boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) && + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) && gsp_phys_rmcall_engine_is_gr()) { ret = gsp_phys_rmcall_golden9_promote(bar0); if (ret) @@ -9477,10 +9496,10 @@ static int gsp_phys_rmcall_gr_ctx_prepare(void __iomem *bar0) * Modes 11/15 back the context buffer with a server-owned FBMEM * allocation (VIDMEM aperture, the shape the KMD promote path * expects); mode 23 uses the same FBMEM object as the hVirtMemory - * promote target; mode 25 and mode 31 use the FBMEM MAIN that made - * the golden first-init construct succeed (m25c); every other mode - * keeps the host sysmem chunk. The PT pages are always host sysmem - * pages behind the sysmem-aperture PD0. + * promote target; mode 25 and modes 31/32 use the FBMEM MAIN that + * made the golden first-init construct succeed (m25c); every other + * mode keeps the host sysmem chunk. The PT pages are always host + * sysmem pages behind the sysmem-aperture PD0. */ if (boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_OLDIFACE_FB || @@ -9491,7 +9510,9 @@ static int gsp_phys_rmcall_gr_ctx_prepare(void __iomem *bar0) boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9 || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) { + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) { u64 fb_base = 0; ret = gsp_phys_rmcall_alloc_fb_mem(bar0, @@ -9544,14 +9565,16 @@ static int gsp_phys_rmcall_gr_ctx_prepare(void __iomem *bar0) "server FBMEM, VIDMEM aperture PTEs" : "host sysmem, contiguous, zeroed"); /* - * Mode-25 golden9e and mode-31 (whose D first-init replay uses the - * same golden9 promote): prepare the FBMEM PATCH/FECS/PRIV/UNR + * Mode-25 golden9e and modes 31/32 (whose D first-init replay uses + * the same golden9 promote): 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 || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) { + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) { 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", @@ -9943,12 +9966,13 @@ static int gsp_phys_rmcall_golden9_promote(void __iomem *bar0) } /* - * Mode 31: allocate the clean TSG-parented sibling A (captured shape, no - * ring/USERD/HOBJ wiring) and run its 9-entry golden9 promote after V6's own - * constructs, so the server's TSG-wide engine-context commit walk - * (fifo_gv100.c:1480-1494) commits V6's instance pointer + RAMFC while V6's - * own promote is suppressed. Two 9-entry promotes total (D and A); V6 gets - * none. + * Modes 31/32: allocate the clean TSG-parented sibling A (captured shape, no + * ring/USERD/HOBJ wiring) and run its 9-entry golden9 promote, so the + * server's TSG-wide engine-context commit walk (fifo_gv100.c:1480-1494) + * commits V6's instance pointer + RAMFC while V6's own promote is suppressed. + * Two 9-entry promotes total (D and A); V6 gets none. Mode 31 runs this after + * V6's own constructs; mode 32 runs it immediately after V6's channel alloc + * and before V6's constructs. */ static int gsp_phys_rmcall_golden_sibling_alloc(void __iomem *bar0) { @@ -9979,11 +10003,17 @@ static int gsp_phys_rmcall_golden_sibling_alloc(void __iomem *bar0) GSP_PHYS_RMCALL_HANDLE_GOLDEN_SIBLING, GSP_PHYS_RMCALL_CLASS_CHANNEL, &ch, sizeof(ch), false, NULL, - "mode 31 GOLDEN SIBLING A (TSG commit carrier)", + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY ? + "mode 32 GOLDEN SIBLING A (pre-construct commit carrier)" : + "mode 31 GOLDEN SIBLING A (TSG commit carrier)", true, &rpc, &status); if (ret) return ret; - gsp_phys_rmcall_ctx_diag_decode("post-V6-constructs pre-A-commit"); + gsp_phys_rmcall_ctx_diag_decode(boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY ? + "post-V6-alloc pre-A-commit" : + "post-V6-constructs pre-A-commit"); ret = gsp_phys_rmcall_golden9_promote_on(bar0, GSP_PHYS_RMCALL_HANDLE_GOLDEN_SIBLING); if (ret) @@ -9996,6 +10026,32 @@ static int gsp_phys_rmcall_golden_sibling_alloc(void __iomem *bar0) return 0; } +/* + * Modes 31/32 gating: sibling A consumes D's golden-replay first-init state + * and is only meaningful on the physical GR backend, so the golden and gpu + * gates are mandatory before the helper sends anything; abort with no retry + * otherwise (SA-CHK F1). The call sites stay mode-specific: mode 31 after + * V6's GR constructs, mode 32 immediately after V6's channel alloc. + */ +static int gsp_phys_rmcall_golden_sibling_commit(void __iomem *bar0) +{ + u32 mode = boot_stage.rmcall_gr_promote; + int ret; + + if (!gsp_phys_rmcall_golden_enabled() || !gsp_phys_gpu_enabled()) { + pr_err("vgsp-boot: rm-call: mode %u requires gsp_phys_rmcall_golden=1 and gsp_phys_gpu=1 (the golden replay did not run); sibling A is not allocated and no promote is sent; the ladder aborts with no retry\n", + mode); + return -EINVAL; + } + ret = gsp_phys_rmcall_golden_sibling_alloc(bar0); + if (ret) { + pr_err("vgsp-boot: rm-call: mode %u sibling A commit failed (%d); no V6 promote follows; the ladder aborts with no retry\n", + mode, ret); + return ret; + } + return 0; +} + /* * Fill one MAIN promote entry with the prepared PA/VA and the snapshot's * entry size. initialize/nonmapped carry the bisection shape: modes 1/3/5 @@ -10182,14 +10238,15 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0) mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC || mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST || mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || - mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) && + mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) && (!gsp_phys_rmcall_golden_enabled() || !gsp_phys_gpu_enabled())) { pr_err("vgsp-boot: rm-call: mode %u requires gsp_phys_rmcall_golden=1 and gsp_phys_gpu=1 (the golden replay did not run); no PROMOTE_CTX is sent and the ladder aborts with no retry\n", mode); return -EINVAL; } /* - * Mode 30/31: the sibling A's 9-entry promote carries the group + * Mode 30/31/32: the sibling A's 9-entry promote carries the group * context commit; nothing is sent on the V6 channel. A multi-entry * promote containing MAIN is refused for a SKIP-ctx channel * (graphics_context.c: bKMDVirtualContext -> NV_ERR_INVALID_ARGUMENT) @@ -10197,11 +10254,14 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0) * shapes never establish, so a V6 promote would abort stage 3 on 0x1f. */ if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || - mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) { + mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) { if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING) pr_info("vgsp-boot: rm-call: mode 30: no PROMOTE_CTX on V6; the sibling A carries the group context commit (config_group ppEngCtxDesc), V6 inherits via the TSG commit/channel setup\n"); - else + else if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) pr_info("vgsp-boot: rm-call: mode 31: no PROMOTE_CTX on V6; sibling A's 9-entry promote ran after V6's alloc and the TSG loop (fifo_gv100.c:1480-1494) already committed V6\n"); + else + pr_info("vgsp-boot: rm-call: mode 32: no PROMOTE_CTX on V6; sibling A's 9-entry promote ran before V6's GR constructs and the TSG loop (fifo_gv100.c:1480-1494) may have committed V6\n"); boot_stage.rmcall_gr_promote_step = 1; return 0; } @@ -12039,7 +12099,9 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0) boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) && + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) && gsp_phys_rmcall_engine_is_gr()) { pr_err("vgsp-boot: rm-call: stage 3 aborted: mode-%u golden replay failed (%d); the golden construct is atomic and is not retried\n", boot_stage.rmcall_gr_promote, ret); @@ -12084,26 +12146,57 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0) return ret; /* - * Mode 30/31 readback point 1: V6's instance/RAMFC right after the + * Mode 32: allocate the TSG-parented sibling A and run its 9-entry + * promote immediately after V6's channel alloc and BEFORE V6's GR + * object constructs (the 0xc597 ladder construct and the 0xc5c0 + * compute object below), inverting the mode-31 order whose A commit + * asserted GSP-RM (NOCAT 0x595f724/0x5162778). V6's own promote is + * suppressed in gsp_phys_rmcall_gr_ctx_promote and V6 stays the + * execution channel. + */ + if (gsp_phys_rmcall_engine_is_gr() && + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) { + ret = gsp_phys_rmcall_golden_sibling_commit(bar0); + if (ret) + return ret; + } + + /* + * Mode 30/31/32 readback point 1: V6's instance/RAMFC right after the * channel alloc (mode 30: A's replay contains the 9-entry promote and * A's TURING_A first-init by now; mode 31: D's replay ran and the - * sibling A commit plus V6's constructs are still ahead), so the - * commit effect can be separated from the later BIND/GPFIFO_SCHEDULE. - * The decode line prints the decisive fields (instance WFI pointer - * pair + both ENG_CTX_VALID target words). + * sibling A commit plus V6's constructs are still ahead; mode 32: the + * sibling A commit already ran and V6's constructs are still ahead), + * so the commit effect can be separated from the later + * BIND/GPFIFO_SCHEDULE. The decode line prints the decisive fields + * (instance WFI pointer pair + both ENG_CTX_VALID target words). */ if (gsp_phys_rmcall_engine_is_gr() && (boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING || boot_stage.rmcall_gr_promote == - GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT)) { - gsp_phys_rmcall_ctx_diag_dump( - "INSTANCE (post-V6-alloc pre-A-commit)", - &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_INSTANCE]); - gsp_phys_rmcall_ctx_diag_dump( - "RAMFC (post-V6-alloc pre-A-commit)", - &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_RAMFC]); - gsp_phys_rmcall_ctx_diag_decode("post-V6-alloc pre-A-commit"); + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT || + boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY)) { + if (boot_stage.rmcall_gr_promote == + GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT_EARLY) { + gsp_phys_rmcall_ctx_diag_dump( + "INSTANCE (post-A-commit pre-V6-constructs)", + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_INSTANCE]); + gsp_phys_rmcall_ctx_diag_dump( + "RAMFC (post-A-commit pre-V6-constructs)", + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_RAMFC]); + gsp_phys_rmcall_ctx_diag_decode("post-A-commit pre-V6-constructs"); + } else { + gsp_phys_rmcall_ctx_diag_dump( + "INSTANCE (post-V6-alloc pre-A-commit)", + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_INSTANCE]); + gsp_phys_rmcall_ctx_diag_dump( + "RAMFC (post-V6-alloc pre-A-commit)", + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_RAMFC]); + gsp_phys_rmcall_ctx_diag_decode("post-V6-alloc pre-A-commit"); + } } /* @@ -12178,20 +12271,15 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0) * 9-entry promote here, after V6's own constructs, so the * server's TSG-wide commit walk sees V6 in its group; V6's * own promote is suppressed in gsp_phys_rmcall_gr_ctx_promote. + * Mode 32 runs the same commit right after V6's channel alloc + * instead (before the constructs); the shared wrapper carries + * the golden/gpu gate and the abort policy. */ if (boot_stage.rmcall_gr_promote == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_SIBLING_COMMIT) { - if (!gsp_phys_rmcall_golden_enabled() || - !gsp_phys_gpu_enabled()) { - pr_err("vgsp-boot: rm-call: mode 31 requires gsp_phys_rmcall_golden=1 and gsp_phys_gpu=1 (the golden replay did not run); sibling A is not allocated and no promote is sent; the ladder aborts with no retry\n"); - return -EINVAL; - } - ret = gsp_phys_rmcall_golden_sibling_alloc(bar0); - if (ret) { - pr_err("vgsp-boot: rm-call: mode 31 sibling A commit failed (%d); no V6 promote follows; the ladder aborts with no retry\n", - ret); + ret = gsp_phys_rmcall_golden_sibling_commit(bar0); + if (ret) return ret; - } } ret = gsp_phys_rmcall_gr_ctx_promote(bar0); if (ret) { -- cgit v1.2.3