diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-01 18:42:55 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-01 18:42:55 -0400 |
| commit | 8849b383a6a5c6d24b5d655545eb47d8a23e0324 (patch) | |
| tree | 3bb943c64f935607147d985c05b7c866ed15aa12 | |
| parent | 1d170f781df7ba05c2bbc12e1bd76b1e37091270 (diff) | |
| download | open-iov-8849b383a6a5c6d24b5d655545eb47d8a23e0324.tar.gz open-iov-8849b383a6a5c6d24b5d655545eb47d8a23e0324.zip | |
gsp-phys: remove the GSP-owned channel variant that wedges the RM task
| -rw-r--r-- | kernel/gsp_phys_booter.c | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index fa68945..d20ee7e 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -267,10 +267,17 @@ bool gsp_phys_boot_requested(void) * NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER bit 23 (alloc/alloc_channel.h:223-225); * the RM's own internal CE channel sets it * (mem_mgr/arch/maxwell/mem_utils_gm107.c:1186-1283). Kernel privilege is - * internalFlags 1:0 = 2 and GSP-ownership is internalFlags bit 6 = 0x40 - * (generated/g_kernel_channel_nvoc.h:185-203). + * internalFlags 1:0 = 2 (generated/g_kernel_channel_nvoc.h:185-203). */ #define GSP_PHYS_RMCALL_CHANNEL_FLAG_SKIP_SCRUBBER (1u << 23) + +/* + * BANNED - do not use: internalFlags bit 6 = 0x40 marks the channel as + * GSP-owned. A live run with this bit set wedged the GSP-RM task: the alloc + * RPC never replied, every later RPC timed out, and the fail-safe held the + * device until reboot. No channel variant may set this bit. The define is + * kept only to document the prohibition where the bit was learned. + */ #define GSP_PHYS_RMCALL_CHANNEL_INTERNALFLAGS_GSP_OWNED 0x40u /* Buffers the ladder allocates and registers in stage 2. */ @@ -817,7 +824,8 @@ static struct gsp_phys_boot_stage { u32 rmcall_subdevice; u32 rmcall_tsg; u32 rmcall_channel; - u32 rmcall_channel_variant; /* winning stage-3 variant (1..4, 0=none) */ + u32 rmcall_channel_variant; /* winning stage-3 variant (1..N, 0=none) */ + bool rmcall_channel_server_mem; /* winning variant had server-allocated mem */ u32 rmcall_token; /* GET_WORK_SUBMIT_TOKEN result */ struct pci_dev *pdev; /* borrowed claim pdev (valid while primed) */ struct gsp_phys_boot_chunk rmcall_chunks[GSP_PHYS_RMCALL_BUF_COUNT]; @@ -1328,6 +1336,7 @@ static void gsp_phys_rmcall_reset(void) boot_stage.rmcall_tsg = 0; boot_stage.rmcall_channel = 0; boot_stage.rmcall_channel_variant = 0; + boot_stage.rmcall_channel_server_mem = false; boot_stage.rmcall_token = 0; for (i = 0; i < GSP_PHYS_RMCALL_BUF_COUNT; i++) { boot_stage.rmcall_mem_handles[i] = 0; @@ -4682,13 +4691,14 @@ gsp_phys_rmcall_mem_desc(u32 index) } /* - * Channel-alloc variants tried in order after the TSG exists. V1/V2 mirror the + * Channel-alloc variants tried in order after the TSG exists. V1 mirrors the * RM's internal CE channel template (mem_utils_gm107.c:1186-1283: device - * parent, hDeviceId, SKIP_SCRUBBER flag, PRIVILEGE_KERNEL internalFlags; - * V2 adds GSP_OWNED). V3 keeps the reference shape but zeroes the memdescs and - * GPFIFO so the server allocates channel memory itself (no client ring to - * fill, so stage 4 refuses). V4 is the previously tried control shape - * (TSG parent, flags 0). + * parent, hDeviceId, SKIP_SCRUBBER flag, PRIVILEGE_KERNEL internalFlags). + * V2 keeps the reference shape but zeroes the memdescs and GPFIFO so the + * server allocates channel memory itself (no client ring to fill, so stage 4 + * refuses). V3 is the previously tried control shape (TSG parent, flags 0). + * A GSP-owned internalFlags variant used to sit between V1 and V2; it wedged + * the RM task and is removed so it can never be selected again. */ struct gsp_phys_rmcall_channel_variant { const char *name; @@ -4705,11 +4715,6 @@ gsp_phys_rmcall_channel_variants[] = { GSP_PHYS_RMCALL_CHANNEL_FLAG_SKIP_SCRUBBER, GSP_PHYS_RMCALL_CHANNEL_INTERNALFLAGS_PRIV_KERNEL, false, GSP_PHYS_RMCALL_HANDLE_CHANNEL_V1 }, - { "ref-plus-gsp-owned", false, - GSP_PHYS_RMCALL_CHANNEL_FLAG_SKIP_SCRUBBER, - GSP_PHYS_RMCALL_CHANNEL_INTERNALFLAGS_PRIV_KERNEL | - GSP_PHYS_RMCALL_CHANNEL_INTERNALFLAGS_GSP_OWNED, false, - GSP_PHYS_RMCALL_HANDLE_CHANNEL_V2 }, { "server-allocated-mem", false, GSP_PHYS_RMCALL_CHANNEL_FLAG_SKIP_SCRUBBER, GSP_PHYS_RMCALL_CHANNEL_INTERNALFLAGS_PRIV_KERNEL, true, @@ -4808,6 +4813,7 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0) if (!ret) { boot_stage.rmcall_channel = v->handle; boot_stage.rmcall_channel_variant = i + 1; + boot_stage.rmcall_channel_server_mem = v->server_mem; pr_info("gsp-phys-boot: rm-call: stage 3 channel variant %u (%s) WON: hChannel=0x%x\n", i + 1, v->name, v->handle); break; @@ -4930,12 +4936,13 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0) int ret; /* - * V3 won with server-allocated memdescs: there is no client GPFIFO, - * USERD or pushbuffer to fill, so no work item can be submitted. - * Distinct error, nothing is scheduled or rung. + * The winning variant requested server-allocated memdescs: there is no + * client GPFIFO, USERD or pushbuffer to fill, so no work item can be + * submitted. Distinct error, nothing is scheduled or rung. */ - if (boot_stage.rmcall_channel_variant == 3) { - pr_err("gsp-phys-boot: rm-call: stage 4 unavailable: winning channel variant V3 (server-allocated mem) has no client GPFIFO/USERD; submission requires V1, V2 or V4\n"); + if (boot_stage.rmcall_channel_server_mem) { + pr_err("gsp-phys-boot: rm-call: stage 4 unavailable: winning channel variant V%u (server-allocated mem) has no client GPFIFO/USERD; submission requires a client-memory variant (ref-device-skip-scrubber or current-control)\n", + boot_stage.rmcall_channel_variant); return -EOPNOTSUPP; } |
