diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index daf0714..f7cb150 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -7854,6 +7854,45 @@ static int gsp_phys_rmcall_golden_mem(void __iomem *bar0, return ret; } +/* + * Golden9f: install the client PDB hierarchy on the golden VAS. The golden + * VAS is PTETABLE_HEAP_MANAGED (client-owned page tables on this config, no + * split range), so the supported client mechanism is + * DMA_SET_PAGE_DIRECTORY with the ladder's root PDB (the same tree the + * ladder VAS uses; its window maps the promoted ctx VAs). Without this the + * channel alloc's pVAS validation rejects the empty golden VAS (the + * golden9a/b NOCAT chain 0x51a8f10/0x52008f4/0x51a89a4). + */ +static int gsp_phys_rmcall_golden9_vas_pdb(void __iomem *bar0) +{ + struct gsp_phys_rmcall_pdb_params pdb; + u32 pdb_rpc = 0; + int ret; + + memset(&pdb, 0, sizeof(pdb)); + pdb.phys_address = cpu_to_le64((u64)gsp_phys_chunk_page_dma( + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_VASPDB], 0)); + pdb.num_entries = cpu_to_le32(GSP_PHYS_RMCALL_PDB_NUM_ENTRIES); + pdb.flags = cpu_to_le32(GSP_PHYS_RMCALL_PDB_FLAG_APERTURE_SYSMEM_NONCOH | + GSP_PHYS_RMCALL_PDB_FLAG_ALL_CHANNELS); + pdb.h_va_space = cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_GOLDEN_VAS); + pdb.ch_id = 0; + pdb.sub_device_id = cpu_to_le32(GSP_PHYS_RMCALL_PDB_SUBDEVICE_ID); + pdb.pasid = 0; + ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_device, + GSP_PHYS_RMCALL_CTRL_DMA_SET_PAGE_DIRECTORY, + &pdb, sizeof(pdb), 16, NULL, 0, + &pdb_rpc, NULL, + "DMA_SET_PAGE_DIRECTORY (golden9f golden VAS)"); + pr_info("vgsp-boot: rm-call: GOLDEN9F golden VAS PDB install: hVas=0x%x root=0x%llx numEntries=%u ret=%d rpc_result=0x%x\n", + GSP_PHYS_RMCALL_HANDLE_GOLDEN_VAS, + (u64)gsp_phys_chunk_page_dma( + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_VASPDB], + 0), + le32_to_cpu(pdb.num_entries), ret, pdb_rpc); + return ret; +} + static int gsp_phys_rmcall_golden_replay(void __iomem *bar0) { struct gsp_phys_rmcall_vas_params va; @@ -7900,6 +7939,16 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0) ret); return ret; } + /* + * Golden9f: give the golden VAS real page tables (the ladder's + * root PDB) before the channel alloc validates its pVAS. + */ + ret = gsp_phys_rmcall_golden9_vas_pdb(bar0); + if (ret) { + pr_err("vgsp-boot: rm-call: GOLDEN9F golden VAS PDB install failed (%d); the golden replay aborts with no retry\n", + ret); + return ret; + } } /* 2. GPFIFO pushbuffer, physical (kernel_graphics.c:2202-2222). */ @@ -7971,14 +8020,16 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0) ch.internal_flags = cpu_to_le32( GSP_PHYS_RMCALL_CHANNEL_INTERNALFLAGS_PRIV_KERNEL); /* - * The captured golden VAS has no server page tables until the - * 0x90f10106 COPY_SERVER_RESERVED_PDES control runs, and the - * channel alloc's pVAS validation rejects an empty VAS (NOCAT - * 0x51a8f10/0x52008f4/0x51a89a4). Bind the golden channel to - * the ladder's own VAS (the one the working V5 channel/TSG - * already uses, with its page tables installed). + * Golden9f: bind the golden channel to the golden VAS (the + * captured shape), now that its page directory is installed + * above. The earlier golden9c workaround used the ladder VAS; + * that VAS is IS_EXTERNALLY_OWNED, so the server's promote + * defers channel-context binding to UVM and the engine ctxsw + * never becomes usable. The golden VAS is PTETABLE_HEAP_MANAGED + * (client page tables, not externally owned) and takes the full + * client-managed commit path. */ - ch.h_va_space = cpu_to_le32(boot_stage.rmcall_vas); + ch.h_va_space = cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_GOLDEN_VAS); ch.h_object_buffer = cpu_to_le32(0); /* * The captured golden wire carried client-local FBMEM |
