summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/gsp_phys_booter.c142
1 files changed, 110 insertions, 32 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index b985541..0c2e75a 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -9430,7 +9430,7 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
u32 mask = gsp_phys_rmcall_fwclient_mask_value();
u32 n = 0;
- pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient: entry mask=0x%x (bit0 MAIN, bit1 PM, bit2 PATCH, bit3 FECS_EVENT, bit4 PRIV_ACCESS_MAP, bit5 UNRESTRICTED_PRIV_ACCESS_MAP)\n",
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient: entry mask=0x%x (bit0 MAIN, bit1 PM, bit2 PATCH, bit3 FECS_EVENT, bit4 PRIV_ACCESS_MAP, bit5 UNRESTRICTED_PRIV_ACCESS_MAP, bit6 MAIN VA-only UVM shape, bit7 INITIALIZE_CTX first)\n",
mask);
/*
@@ -9451,32 +9451,103 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: PM prepare failed; omitting the PM entry and continuing (mode 24 treats PM as best-effort; the reference set pre-allocates it for an externally-owned VAS)\n");
gsp_phys_rmcall_gr_fwclient_small_prepare();
- /* Entry 0: MAIN - combined PA+VA, PDB-mapped ctx VA. */
+ /*
+ * Mask bit7 (bisection): send the old-interface
+ * GPU_INITIALIZE_CTX with the client MAIN PA/size before the
+ * MAIN promote, installing the engine-context memdesc the MAIN
+ * commit requires on the V6 client-buffer channel.
+ */
+ if (mask & BIT(7)) {
+ struct gsp_phys_rmcall_init_ctx_params *ic;
+ u32 ic_rpc = 0, ic_status = 0;
+
+ ic = kvzalloc(sizeof(*ic), GFP_KERNEL);
+ if (!ic) {
+ kvfree(p);
+ return -ENOMEM;
+ }
+ ic->engine_type = cpu_to_le32(GSP_PHYS_RMCALL_ENGINE_GR0);
+ ic->h_client = cpu_to_le32(0);
+ ic->ch_id = cpu_to_le32(0);
+ ic->h_chan_client = cpu_to_le32(boot_stage.rmcall_client);
+ ic->h_object = cpu_to_le32(boot_stage.rmcall_channel);
+ ic->h_virt_memory = cpu_to_le32(0);
+ ic->phys_address = cpu_to_le64(boot_stage.rmcall_ctx_pa);
+ ic->phys_attr = cpu_to_le32(attr);
+ ic->h_dma_handle = cpu_to_le32(0);
+ ic->index = cpu_to_le32(0);
+ ic->size = cpu_to_le64(boot_stage.rmcall_ctx_size);
+ ret = gsp_phys_rmcall_control(bar0,
+ boot_stage.rmcall_subdevice,
+ GSP_PHYS_RMCALL_CTRL_GPU_INITIALIZE_CTX,
+ ic, sizeof(*ic), 24, NULL, 0,
+ &ic_rpc, &ic_status,
+ "GPU_INITIALIZE_CTX (fwclient mask bit7, before MAIN)");
+ kvfree(ic);
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient INITIALIZE_CTX (before MAIN): pa=0x%llx size=0x%x physAttr=0x%x status=0x%x rpc_result=0x%x\n",
+ boot_stage.rmcall_ctx_pa,
+ boot_stage.rmcall_ctx_size, attr, ic_status,
+ ic_rpc);
+ if (ret) {
+ kvfree(p);
+ return ret;
+ }
+ }
+
if (mask & BIT(0)) {
if (mask & BIT(6)) {
- gsp_phys_rmcall_promote_entry_fill(p, n,
+ gsp_phys_rmcall_promote_entry_fill(p, 0,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_MAIN,
0, boot_stage.rmcall_ctx_va, 0, 0,
0, 0);
- gsp_phys_rmcall_gr_promote_log_entry(n,
- &p->entry[n],
+ gsp_phys_rmcall_gr_promote_log_entry(0,
+ &p->entry[0],
"VA-only (UVM shape, mask bit6)");
} else {
- gsp_phys_rmcall_promote_entry_fill(p, n,
+ gsp_phys_rmcall_promote_entry_fill(p, 0,
GSP_PHYS_RMCALL_GR_CTX_BUFFER_ID_MAIN,
boot_stage.rmcall_ctx_pa,
boot_stage.rmcall_ctx_va,
boot_stage.rmcall_ctx_size, attr, 1, 0);
- gsp_phys_rmcall_gr_promote_log_entry(n,
- &p->entry[n],
+ gsp_phys_rmcall_gr_promote_log_entry(0,
+ &p->entry[0],
"combined (PDB-mapped ctx VA)");
}
- n++;
- } else {
- pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: MAIN omitted by mask\n");
+ p->entry_count = cpu_to_le32(1);
+ rpc_result = 0;
+ status = 0;
+ ret = gsp_phys_rmcall_control(bar0,
+ boot_stage.rmcall_subdevice,
+ GSP_PHYS_RMCALL_CTRL_GPU_PROMOTE_CTX,
+ p, sizeof(*p), 24, NULL, 0,
+ &rpc_result, &status,
+ "GPU_PROMOTE_CTX (FWCLIENT MAIN)");
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient MAIN: entryCount=1 status=0x%x rpc_result=0x%x (hObject=0x%x hChanClient=0x%x engineType=0x%x gr_promote_param=%u)\n",
+ status, rpc_result,
+ boot_stage.rmcall_channel,
+ boot_stage.rmcall_client,
+ GSP_PHYS_RMCALL_ENGINE_GR0, mode);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: PROMOTE_CTX fwclient MAIN 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",
+ status, rpc_result,
+ gsp_phys_rmcall_status_str(status), ret);
+ kvfree(p);
+ return ret;
+ }
+ boot_stage.rmcall_gr_promote_step = 1;
}
- /* Entry 1: PM - init-only, no PM VA source in the ladder. */
+ /*
+ * Host-safety rule from the 2026-10-05 crash: the non-MAIN
+ * entries are built only after MAIN has consumed entry[0], and
+ * are sent ONLY when MAIN was not selected or MAIN committed.
+ * Sending an accepted non-MAIN control before a failing MAIN
+ * control (the previous order) corrupted host kernel memory and
+ * Oopsed the writing task; that order must not return.
+ */
+ n = 0;
+
+ /* Entry 0: PM - init-only, no PM VA source in the ladder. */
if ((mask & BIT(1)) && boot_stage.rmcall_pm_prepared &&
boot_stage.rmcall_pm_pa && boot_stage.rmcall_pm_size) {
gsp_phys_rmcall_promote_entry_fill(p, n,
@@ -9541,27 +9612,34 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: UNRESTRICTED_PRIV_ACCESS_MAP omitted (allocation unavailable)\n");
}
- p->entry_count = cpu_to_le32(n);
- rpc_result = 0;
- status = 0;
- ret = gsp_phys_rmcall_control(bar0,
- boot_stage.rmcall_subdevice,
- GSP_PHYS_RMCALL_CTRL_GPU_PROMOTE_CTX,
- p, sizeof(*p), 24, NULL, 0,
- &rpc_result, &status,
- "GPU_PROMOTE_CTX (FWCLIENT set)");
- pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient: entryCount=%u status=0x%x rpc_result=0x%x (hObject=0x%x hChanClient=0x%x engineType=0x%x gr_promote_param=%u)\n",
- n, status, rpc_result, boot_stage.rmcall_channel,
- boot_stage.rmcall_client,
- GSP_PHYS_RMCALL_ENGINE_GR0, mode);
- if (ret) {
- pr_err("vgsp-boot: rm-call: PROMOTE_CTX fwclient failed (status=0x%x rpc_result=0x%x, %s, ret=%d); entries emitted=%u; the GR context is not committed and the ladder aborts before BIND with no retry\n",
- status, rpc_result,
- gsp_phys_rmcall_status_str(status), ret, n);
- kvfree(p);
- return ret;
+ if (n > 0) {
+ p->entry_count = cpu_to_le32(n);
+ rpc_result = 0;
+ status = 0;
+ ret = gsp_phys_rmcall_control(bar0,
+ boot_stage.rmcall_subdevice,
+ GSP_PHYS_RMCALL_CTRL_GPU_PROMOTE_CTX,
+ p, sizeof(*p), 24, NULL, 0,
+ &rpc_result, &status,
+ "GPU_PROMOTE_CTX (FWCLIENT non-MAIN, after MAIN)");
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient non-MAIN (after MAIN): entryCount=%u status=0x%x rpc_result=0x%x (hObject=0x%x hChanClient=0x%x engineType=0x%x gr_promote_param=%u)\n",
+ n, status, rpc_result,
+ boot_stage.rmcall_channel,
+ boot_stage.rmcall_client,
+ GSP_PHYS_RMCALL_ENGINE_GR0, mode);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: PROMOTE_CTX fwclient non-MAIN failed (status=0x%x rpc_result=0x%x, %s, ret=%d); entries emitted=%u; the GR context commit is incomplete and the ladder aborts before BIND with no retry\n",
+ status, rpc_result,
+ gsp_phys_rmcall_status_str(status), ret,
+ n);
+ kvfree(p);
+ return ret;
+ }
+ boot_stage.rmcall_gr_promote_step =
+ (mask & BIT(0)) ? 2 : 1;
+ } else if (!(mask & BIT(0))) {
+ pr_warn("vgsp-boot: rm-call: PROMOTE_CTX fwclient: MAIN omitted by mask\n");
}
- boot_stage.rmcall_gr_promote_step = 1;
} else {
pr_err("vgsp-boot: rm-call: unknown gr_promote_param=%u reached the promote step; no PROMOTE_CTX is sent and the ladder aborts with no retry\n",
mode);