summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/gsp_phys_booter.c')
-rw-r--r--kernel/gsp_phys_booter.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index af91968..c2d4b95 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -472,8 +472,21 @@ bool gsp_phys_boot_requested(void)
* virtual-memdesc promote.
*/
#define GSP_PHYS_RMCALL_GR_PROMOTE_KMD_INIT_HVIRT 22u
+/*
+ * Mode 23 (2026-10-05, untested): the hVirtMemory no-entry promote backed by
+ * a server-owned FBMEM context object (GSP_RM_ALLOC class 0x40), on the
+ * server-managed shared V5 channel (gsp_phys_srv_ctxbuf=1). The mode-6 hVirt
+ * branch requires the server-manages byte (set by srvctx=1) and resolves the
+ * hVirtMemory object's memdesc; 0x5b00d2c then commits that memdesc. A
+ * PHYSICAL (FBMEM) memdesc does not enter the ADDR_VIRTUAL vaList gate that
+ * blocks every client VA promote on the server-booked list, so this is the one
+ * promote shape that can reach the per-buffer commit on the stable
+ * shared+srvctx channel. The FBMEM object handle is
+ * GSP_PHYS_RMCALL_HANDLE_CTX_FB (allocated by the ctx-buffer prep step).
+ */
+#define GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB 23u
#define GSP_PHYS_RMCALL_GR_PROMOTE_MAX \
- (GSP_PHYS_RMCALL_GR_PROMOTE_KMD_INIT_HVIRT)
+ (GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB)
/*
* Work-submit token notifier slot. The default index is
@@ -7840,13 +7853,16 @@ 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); every other mode keeps the host sysmem chunk. The PT
+ * expects); mode 23 uses the same FBMEM object as the hVirtMemory
+ * promote target; 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 ||
boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_KMD_FB) {
+ GSP_PHYS_RMCALL_GR_PROMOTE_KMD_FB ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB) {
u64 fb_base = 0;
ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
@@ -8397,16 +8413,20 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
} else if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_BARE_VA ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_BARE_VA) {
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_BARE_VA ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB) {
/*
- * Modes 6/7/20: the documented no-entry branches. Modes 6/20
+ * Modes 6/7/20/23: the documented no-entry branches. Modes 6/20
* first reserve the context window with an NV01_MEMORY_VIRTUAL
* object on the ladder VAS and pass it as hVirtMemory
* (hClient is its owner); mode 7 sends the bare
- * (virtAddress, size) pair with no hVirtMemory. entryCount=0
- * in all, so the server creates the memdesc/vaList entry
- * instead of resolving one of our raw-PTE entries. Mode 20 is
- * the same shape as mode 6 but on the V6 KMD-managed channel.
+ * (virtAddress, size) pair with no hVirtMemory. Mode 23 passes
+ * the server-owned FBMEM context object (class 0x40) allocated
+ * by the ctx-buffer prep: a physical memdesc reaches 0x5b00d2c
+ * without the ADDR_VIRTUAL vaList gate. entryCount=0 in all, so
+ * the server creates/resolves the memdesc instead of resolving
+ * one of our raw-PTE entries; mode 20 is the same shape as mode
+ * 6 but on the V6 KMD-managed channel.
*/
if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT) {
@@ -8418,6 +8438,10 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
p->h_client = cpu_to_le32(boot_stage.rmcall_client);
p->h_virt_memory =
cpu_to_le32(boot_stage.rmcall_gr_hvirt);
+ } else if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB) {
+ p->h_client = cpu_to_le32(boot_stage.rmcall_client);
+ p->h_virt_memory =
+ cpu_to_le32(GSP_PHYS_RMCALL_HANDLE_CTX_FB);
}
p->virt_address = cpu_to_le64(boot_stage.rmcall_ctx_va);
p->size = cpu_to_le64(boot_stage.rmcall_ctx_size);
@@ -8428,12 +8452,14 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
p, sizeof(*p), 24, NULL, 0,
&rpc_result, &status,
(mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT) ?
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB) ?
"GPU_PROMOTE_CTX (hVirtMemory)" :
"GPU_PROMOTE_CTX (bare VA+size)");
pr_info("vgsp-boot: rm-call: PROMOTE_CTX %s: entryCount=0 hVirtMemory=0x%x virtAddress=0x%llx size=0x%x status=0x%x rpc_result=0x%x (hClient=0x%x hObject=0x%x hChanClient=0x%x engineType=0x%x gr_promote_param=%u)\n",
(mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT) ?
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB) ?
"hVirtMemory" : "bare VA+size",
le32_to_cpu(p->h_virt_memory),
boot_stage.rmcall_ctx_va, boot_stage.rmcall_ctx_size,
@@ -8443,7 +8469,8 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
if (ret) {
pr_err("vgsp-boot: rm-call: PROMOTE_CTX %s failed (status=0x%x rpc_result=0x%x, %s, ret=%d); the GR context is not committed and the ladder aborts before BIND with no retry\n",
(mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT) ?
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_HVIRT ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_HVIRT_FB) ?
"hVirtMemory" : "bare VA+size",
status, rpc_result,
gsp_phys_rmcall_status_str(status), ret);