summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 20:32:10 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 20:32:10 -0400
commit3537f3ebafca87705d962ebe4c05a4ba61644da7 (patch)
tree1624726a3a1f5f9d99dd71675e2b28f666a50af6
parentd8abca80d93bc944cb53b4e797b7440e12e71f69 (diff)
downloadopen-iov-3537f3ebafca87705d962ebe4c05a4ba61644da7.tar.gz
open-iov-3537f3ebafca87705d962ebe4c05a4ba61644da7.zip
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.
-rw-r--r--kernel/gsp_phys_booter.c139
1 files 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;
@@ -4785,83 +4778,6 @@ static int gsp_phys_rmcall_alloc_notifier_mem(void __iomem *bar0)
}
/*
- * 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)
* receives the server control status even when it is nonzero; the echoed
@@ -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,