From 77243ee5273ea0d5c4285b3f8fdb2b01687ac480 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 1 Oct 2026 20:32:10 -0400 Subject: gsp-phys: keep the channel USERD in host-writable sysmem for the ladder Revert the USERD selection to the client sysmem chunk unconditionally: the ladder advances GP_PUT by writing that chunk directly, and there is no BAR1/PRAMIN aperture here to reach an FBMEM page, so an FBMEM USERD would leave the host write invisible to the hardware USERD the engine polls. Remove the now-dead FBMEM USERD allocator, handle and state; the FBMEM error-notifier allocation path is unchanged. The PDB hierarchy, VA-based gpFifoOffset and ring-entry GET, TSG schedule insurance, logs and asserts from the PDB change are kept. Logs now say userd=sysmem (host-writable) so the path in use is unambiguous. --- kernel/gsp_phys_booter.c | 139 ++++++----------------------------------------- 1 file changed, 16 insertions(+), 123 deletions(-) diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 5565159..4e7fd6f 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -344,7 +344,6 @@ bool gsp_phys_boot_requested(void) #define GSP_PHYS_RMCALL_HANDLE_CHANNEL_V3 0xcaf00018u #define GSP_PHYS_RMCALL_HANDLE_CHANNEL_V5 0xcaf00024u #define GSP_PHYS_RMCALL_HANDLE_NOTIFIER_MEM 0xcaf00028u -#define GSP_PHYS_RMCALL_HANDLE_USERD_MEM 0xcaf0002cu #define GSP_PHYS_RMCALL_HANDLE_MEM_BASE 0xcaf01000u #define GSP_PHYS_RMCALL_HANDLE_MEM_STRIDE 4u @@ -928,9 +927,6 @@ static struct gsp_phys_boot_stage { u32 rmcall_notifier_mem; /* FBMEM error-notifier object handle */ u64 rmcall_notifier_base; /* its returned frame-buffer address */ bool rmcall_notifier_valid; /* the FBMEM notifier alloc succeeded */ - u32 rmcall_userd_mem; /* FBMEM USERD object handle */ - u64 rmcall_userd_base; /* its returned frame-buffer address */ - bool rmcall_userd_valid; /* the FBMEM USERD alloc succeeded */ u64 rmcall_va_base; /* channel PDB VA window base */ u64 rmcall_va_gpfifo; /* GPFIFO GPU VA in that window */ u64 rmcall_va_pb; /* pushbuffer GPU VA in that window */ @@ -1455,9 +1451,6 @@ static void gsp_phys_rmcall_reset(void) boot_stage.rmcall_notifier_mem = 0; boot_stage.rmcall_notifier_base = 0; boot_stage.rmcall_notifier_valid = false; - boot_stage.rmcall_userd_mem = 0; - boot_stage.rmcall_userd_base = 0; - boot_stage.rmcall_userd_valid = false; boot_stage.rmcall_va_base = 0; boot_stage.rmcall_va_gpfifo = 0; boot_stage.rmcall_va_pb = 0; @@ -4784,83 +4777,6 @@ static int gsp_phys_rmcall_alloc_notifier_mem(void __iomem *bar0) return 0; } -/* - * Allocate the channel's USERD page in FBMEM. Same class-0x40 shape as the - * error-notifier allocation above (owner HEAP_OWNER_RM_CLIENT_GENERIC, type - * IMAGE, VIDMEM|UNCACHED, SKIP_SCRUB); the reference defaults USERD to - * VIDMEM (mem_utils_gm107.c:792-804,1132-1161) and the client push path - * allocates NV01_MEMORY_LOCAL_USER with these flags (nvidia-push-init.c: - * 515-554). The server returns the allocated FB offset in - * NV_MEMORY_ALLOCATION_PARAMS.offset, which userdMem.base carries with - * addressSpace FBMEM. - * - * Failure is non-fatal: the channel params then fall back to the sysmem - * USERD chunk and log the fallback. - */ -static int gsp_phys_rmcall_alloc_userd_mem(void __iomem *bar0) -{ - struct gsp_phys_rmcall_memory_alloc_params mem; - struct gsp_phys_rmcall_rm_alloc_req *req; - struct gsp_phys_rx_record rec; - u32 req_len = sizeof(*req) + sizeof(mem); - u32 status; - u64 base; - int ret; - - memset(&mem, 0, sizeof(mem)); - mem.owner = cpu_to_le32(GSP_PHYS_RMCALL_HEAP_OWNER_RM_CLIENT_GENERIC); - mem.type = cpu_to_le32(GSP_PHYS_RMCALL_OS32_TYPE_IMAGE); - mem.size = cpu_to_le64(GSP_PHYS_RMCALL_COPY_SIZE); - mem.attr = cpu_to_le32(GSP_PHYS_RMCALL_OS32_ATTR_VIDMEM_UNCACHED); - mem.internalflags = - cpu_to_le32(GSP_PHYS_RMCALL_OS32_INTERNAL_FLAG_SKIP_SCRUB); - - req = kvzalloc(req_len, GFP_KERNEL); - if (!req) - return -ENOMEM; - req->h_client = cpu_to_le32(boot_stage.rmcall_client); - req->h_parent = cpu_to_le32(boot_stage.rmcall_device); - req->h_object = cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_USERD_MEM); - req->h_class = cpu_to_le32(GSP_PHYS_RMCALL_CLASS_MEMORY_LOCAL_USER); - req->params_size = cpu_to_le32(sizeof(mem)); - memcpy(req->params, &mem, sizeof(mem)); - - ret = gsp_phys_rmcall_rpc(bar0, GSP_PHYS_RMCALL_FUNC_GSP_RM_ALLOC, - req, req_len, 20, &rec, true, NULL); - kvfree(req); - if (ret) { - pr_err("gsp-phys-boot: rm-call: FBMEM USERD alloc (hMemory=0x%x class=0x40 size=0x%x) RPC failed: %d\n", - GSP_PHYS_RMCALL_HANDLE_USERD_MEM, - GSP_PHYS_RMCALL_COPY_SIZE, ret); - gsp_phys_rx_record_free(&rec); - return ret; - } - - status = gsp_phys_rmcall_reply_u32(&rec, 16); - if (status != 0 || - rec.payload_len < 32 + offsetof(struct gsp_phys_rmcall_memory_alloc_params, - offset) + 8) { - pr_err("gsp-phys-boot: rm-call: FBMEM USERD alloc rejected: status=0x%x payload=%u B (need the echoed params through offset at +%zu)\n", - status, rec.payload_len, - offsetof(struct gsp_phys_rmcall_memory_alloc_params, - offset) + 8); - gsp_phys_rx_record_free(&rec); - return -EIO; - } - base = get_unaligned_le64(rec.buf + GSP_PHYS_MSG_ELEMENT_PAYLOAD_OFF + 32 + - offsetof(struct gsp_phys_rmcall_memory_alloc_params, - offset)); - gsp_phys_rx_record_free(&rec); - - boot_stage.rmcall_userd_mem = GSP_PHYS_RMCALL_HANDLE_USERD_MEM; - boot_stage.rmcall_userd_base = base; - boot_stage.rmcall_userd_valid = true; - pr_info("gsp-phys-boot: rm-call: FBMEM USERD allocated: hMemory=0x%x class=0x40 size=0x%x FB base=0x%llx\n", - boot_stage.rmcall_userd_mem, GSP_PHYS_RMCALL_COPY_SIZE, - boot_stage.rmcall_userd_base); - return 0; -} - /* * One GSP_RM_CONTROL (76). Reply status at payload+12, echoed params at * payload+24 (rpcRmApiControl_GSP, rpc.c:9797-10031). out_status (optional) @@ -5139,22 +5055,13 @@ gsp_phys_rmcall_channel_params_init(struct gsp_phys_rmcall_channel_params *ch, ch->gp_fifo_entries = cpu_to_le32(GSP_PHYS_RMCALL_GPFIFO_ENTRIES); ch->instance_mem = gsp_phys_rmcall_mem_desc(GSP_PHYS_RMCALL_BUF_INSTANCE); /* - * USERD is the reference default FBMEM page (mem_utils_gm107.c: - * 792-804,1132-1161; nvidia-push-init.c:515-554) when stage 3's - * class-0x40 allocation succeeded; the sysmem chunk remains the - * fallback when it did not. + * USERD stays the client sysmem chunk (as before the PDB change). The + * host ladder advances GP_PUT by writing the chunk directly, and there + * is no BAR1/PRAMIN aperture here to reach an FBMEM page, so an FBMEM + * USERD would leave the host write invisible to the hardware USERD the + * engine polls. The server accepts the sysmem descriptor (cycle 21). */ - if (boot_stage.rmcall_userd_valid) { - ch->userd_mem.base = cpu_to_le64(boot_stage.rmcall_userd_base); - ch->userd_mem.size = cpu_to_le64(GSP_PHYS_RMCALL_COPY_SIZE); - ch->userd_mem.address_space = - cpu_to_le32(GSP_PHYS_RMCALL_ADDR_FBMEM); - ch->userd_mem.cache_attrib = - cpu_to_le32(GSP_PHYS_RMCALL_CACHE_UNCACHED); - } else { - ch->userd_mem = - gsp_phys_rmcall_mem_desc(GSP_PHYS_RMCALL_BUF_USERD); - } + ch->userd_mem = gsp_phys_rmcall_mem_desc(GSP_PHYS_RMCALL_BUF_USERD); ch->ramfc_mem = gsp_phys_rmcall_mem_desc(GSP_PHYS_RMCALL_BUF_RAMFC); ch->mthdbuf_mem = gsp_phys_rmcall_mem_desc(GSP_PHYS_RMCALL_BUF_MTHDBUF); } @@ -5354,8 +5261,9 @@ static void gsp_phys_rmcall_pdb_build(void) * SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX -> GET_WORK_SUBMIT_TOKEN order lives in * stage 4. After SET_PAGE_DIRECTORY the root's lower levels are built * (gsp_phys_rmcall_pdb_build), because the engine fetches the GPFIFO and the - * pushbuffer by GPU VA through that hierarchy; the USERD page is allocated in - * FBMEM alongside the notifier. + * pushbuffer by GPU VA through that hierarchy; the USERD stays in host-writable + * sysmem so the ladder's GP_PUT write reaches the hardware USERD (no BAR1 + * aperture exists here for an FBMEM page). */ static int gsp_phys_rmcall_stage3(void __iomem *bar0) { @@ -5451,26 +5359,15 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0) pr_warn("gsp-phys-boot: rm-call: FBMEM error-notifier allocation failed (%d); channel allocs carry a zeroed notifier memdesc and only the stage-4 token recovery can save the token\n", ret); - /* - * Allocate the USERD page in FBMEM as well (reference default); on - * failure the channel variants fall back to the sysmem USERD chunk. - */ - ret = gsp_phys_rmcall_alloc_userd_mem(bar0); - if (ret) - pr_warn("gsp-phys-boot: rm-call: FBMEM USERD allocation failed (%d); channel allocs fall back to the sysmem USERD chunk\n", - ret); - ret = gsp_phys_rmcall_alloc_channel(bar0); if (ret) return ret; - pr_info("gsp-phys-boot: rm-call: stage 3 complete: hVas=0x%x hTsg=0x%x hChannel=0x%x variant=V%u notifier=%s base=0x%llx userd=%s base=0x%llx engine=COPY0 (cid is server-assigned, request value ignored; token is requested in stage 4)\n", + pr_info("gsp-phys-boot: rm-call: stage 3 complete: hVas=0x%x hTsg=0x%x hChannel=0x%x variant=V%u notifier=%s base=0x%llx userd=sysmem (host-writable) engine=COPY0 (cid is server-assigned, request value ignored; token is requested in stage 4)\n", boot_stage.rmcall_vas, boot_stage.rmcall_tsg, boot_stage.rmcall_channel, boot_stage.rmcall_channel_variant, boot_stage.rmcall_notifier_valid ? "FBMEM" : "none", - boot_stage.rmcall_notifier_base, - boot_stage.rmcall_userd_valid ? "FBMEM" : "sysmem", - boot_stage.rmcall_userd_base); + boot_stage.rmcall_notifier_base); return 0; } @@ -5732,10 +5629,9 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0) put_unaligned_le32(e1, (u8 *)ring_va + slot * 8 + 4); dma_wmb(); /* - * GP_PUT stays on the client sysmem USERD chunk, which is the hardware - * USERD only on the FBMEM-alloc fallback path; when the server used the - * FBMEM USERD page this host write cannot reach it (no BAR1/PRAMIN - * aperture here), kept as-is for the fallback. + * GP_PUT advances on the client sysmem USERD chunk, which is the + * channel's hardware USERD because the params carry that same chunk; + * the host write is therefore what the engine polls (cycle 21). */ put_unaligned_le32((gpput + 1) % GSP_PHYS_RMCALL_GPFIFO_ENTRIES, (u8 *)userd + GSP_PHYS_RMCALL_USERD_GPPUT_OFF); @@ -5755,9 +5651,8 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0) wmb(); writel(doorbell, bar0 + GSP_PHYS_RMCALL_DOORBELL_OFF); - pr_info("gsp-phys-boot: rm-call: submitted: pb=0x%llx pbVa=0x%llx gpFifoVa=0x%llx userd=%s words=%u slot=%u (was GPGet=%u GPPut=%u) e0=0x%08x e1=0x%08x token=0x%08x (runlistId=%u chId=0x%x) doorbell=0x%08x @0x%x; polling sem=0x%llx for 0x%08x (<=%u ms)\n", + pr_info("gsp-phys-boot: rm-call: submitted: pb=0x%llx pbVa=0x%llx gpFifoVa=0x%llx userd=sysmem (host-writable) words=%u slot=%u (was GPGet=%u GPPut=%u) e0=0x%08x e1=0x%08x token=0x%08x (runlistId=%u chId=0x%x) doorbell=0x%08x @0x%x; polling sem=0x%llx for 0x%08x (<=%u ms)\n", pb_dma, GSP_PHYS_RMCALL_VA_PB, GSP_PHYS_RMCALL_VA_GPFIFO, - boot_stage.rmcall_userd_valid ? "FBMEM" : "sysmem", words, slot, gpget, gpput, e0, e1, boot_stage.rmcall_token, runlist_id, ch_id, doorbell, GSP_PHYS_RMCALL_DOORBELL_OFF, sem_dma, @@ -6046,9 +5941,7 @@ static int gsp_phys_state_show(struct seq_file *m, void *v) boot_stage.rmcall_notifier_valid ? "FBMEM" : "none", boot_stage.rmcall_notifier_base); seq_printf(m, - "rm_call_userd: userd=%s hMemory=0x%x base=0x%llx | rm_call_pdb: vaBase=0x%llx vaGpfifo=0x%llx vaPb=0x%llx\n", - boot_stage.rmcall_userd_valid ? "FBMEM" : "sysmem", - boot_stage.rmcall_userd_mem, boot_stage.rmcall_userd_base, + "rm_call_userd: userd=sysmem (host-writable) | rm_call_pdb: vaBase=0x%llx vaGpfifo=0x%llx vaPb=0x%llx\n", boot_stage.rmcall_va_base, boot_stage.rmcall_va_gpfifo, boot_stage.rmcall_va_pb); seq_printf(m, -- cgit v1.2.3