diff options
| -rw-r--r-- | kernel/gsp_phys_booter.c | 117 | ||||
| -rw-r--r-- | kernel/gsp_phys_gpu.c | 19 | ||||
| -rw-r--r-- | kernel/gsp_phys_gpu.h | 4 |
3 files changed, 140 insertions, 0 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c index 8bf94d8..de546d4 100644 --- a/kernel/gsp_phys_booter.c +++ b/kernel/gsp_phys_booter.c @@ -14412,6 +14412,121 @@ static int gsp_phys_rmcall_gr_sem_push_locked(void __iomem *bar0) } /* + * m84 diagnostic (gsp_phys_rmcall_gr_img_probe; default 0). Reads the first + * 4 KB of the GR MAIN context image (promoted at VA_GR_CTX, FBMEM) and of the + * per-VEID subcontext header (image + 0xf3000) through the real COPY engine. + * The rmcall channel is GR-bound in this mode, so the probe re-binds it to + * COPY0, submits one CE copy block per region into the DST sysmem chunk, + * polls the module semaphore, re-binds GR0 and dumps the image header + * pointers. Any rejection or timeout is logged and changes nothing else; + * the forwarded launch path then runs as usual. Must be called from stage 4 + * (gsp_phys_rm_lock held). + */ +static void gsp_phys_rmcall_ctx_image_probe(void __iomem *bar0) +{ + struct gsp_phys_boot_chunk *sem = + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_SEM]; + struct gsp_phys_boot_chunk *dst = + &boot_stage.rmcall_chunks[GSP_PHYS_RMCALL_BUF_DST]; + struct gsp_phys_rmcall_ce_submit sub; + u64 regions[2]; + u32 bind_params; + int r; + + if (!boot_stage.rmcall_ctx_pa || boot_stage.rmcall_stage < 3) + return; + + bind_params = GSP_PHYS_RMCALL_ENGINE_COPY0; + { + u32 rpc_result = 0, status = 0; + + r = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_channel, + GSP_PHYS_RMCALL_CTRL_BIND_CHANNEL, + &bind_params, sizeof(bind_params), 16, NULL, 0, + &rpc_result, &status, + "BIND_CHANNEL COPY0 (m84 image probe)"); + pr_info("vgsp-boot: rm-call: m84 image probe: BIND COPY0 status=0x%x rpc_result=0x%x ret=%d\n", + status, rpc_result, r); + } + + regions[0] = GSP_PHYS_RMCALL_VA_GR_CTX; /* image header */ + regions[1] = GSP_PHYS_RMCALL_VA_GR_CTX + 0xf3000ULL; /* subctx hdr VEID0 */ + if (!r) { + u32 k; + + for (k = 0; k < 2; k++) { + u32 rpc_result = 0, status = 0, poll = 0; + unsigned long deadline; + u8 *d; + + WRITE_ONCE(*(u32 *)gsp_phys_chunk_page_va(sem, 0), 0); + wmb(); + r = gsp_phys_rmcall_ce_submit_locked(bar0, + regions[k], GSP_PHYS_RMCALL_VA_DST, + GSP_PHYS_RMCALL_VA_SEM, + GSP_PHYS_PAGE_SIZE, + GSP_PHYS_RMCALL_SEM_PAYLOAD, false, + &sub); + (void)rpc_result; + (void)status; + if (r) { + pr_err("vgsp-boot: rm-call: m84 image probe: CE submit for region %u refused (%d)\n", + k, r); + break; + } + deadline = jiffies + + msecs_to_jiffies(GSP_PHYS_RMCALL_TIMEOUT_MS); + for (;;) { + poll = READ_ONCE(*(u32 *)gsp_phys_chunk_page_va(sem, 0)); + if (poll == GSP_PHYS_RMCALL_SEM_PAYLOAD) + break; + if (time_after_eq(jiffies, deadline)) { + pr_err("vgsp-boot: rm-call: m84 image probe: region %u CE copy TIMEOUT (sem=0x%08x) - an engine-side walk of VA 0x%llx failed or the CE did not run\n", + k, poll, regions[k]); + break; + } + msleep(GSP_PHYS_RMCALL_POLL_MS); + } + if (poll != GSP_PHYS_RMCALL_SEM_PAYLOAD) + break; + d = gsp_phys_chunk_page_va(dst, 0); + if (!d) + break; + pr_info("vgsp-boot: rm-call: m84 image probe: region %u VA=0x%llx copied OK\n", + k, regions[k]); + { + u32 i; + + for (i = 0; i < 0x80; i += 8) + pr_info("vgsp-ctximg[%u] [%03x] = %08x %08x %08x %08x %08x %08x %08x %08x\n", + k, i * 4, + get_unaligned_le32(d + i * 4), + get_unaligned_le32(d + (i + 1) * 4), + get_unaligned_le32(d + (i + 2) * 4), + get_unaligned_le32(d + (i + 3) * 4), + get_unaligned_le32(d + (i + 4) * 4), + get_unaligned_le32(d + (i + 5) * 4), + get_unaligned_le32(d + (i + 6) * 4), + get_unaligned_le32(d + (i + 7) * 4)); + } + } + } + + bind_params = GSP_PHYS_RMCALL_ENGINE_GR0; + { + u32 rpc_result = 0, status = 0; + + r = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_channel, + GSP_PHYS_RMCALL_CTRL_BIND_CHANNEL, + &bind_params, sizeof(bind_params), 16, NULL, 0, + &rpc_result, &status, + "BIND_CHANNEL GR0 (m84 image probe)"); + pr_info("vgsp-boot: rm-call: m84 image probe: rebind GR0 status=0x%x rpc_result=0x%x ret=%d\n", + status, rpc_result, r); + } +} + +/* * P6a guest-memory CE helper: run one CE copy with explicit operand VAs on * the ladder channel and poll the module semaphore outside gsp_phys_rm_lock * (the same lock discipline as the P5 shadow API, so a guest copy can never @@ -17182,6 +17297,8 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0) if (ret) pr_err("vgsp-boot: rm-call: stage 4 GR path failed (%d); no retry\n", ret); + else if (gsp_phys_rmcall_gr_img_probe_value()) + gsp_phys_rmcall_ctx_image_probe(bar0); return ret; } diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c index f094d36..e3ca2e8 100644 --- a/kernel/gsp_phys_gpu.c +++ b/kernel/gsp_phys_gpu.c @@ -796,6 +796,25 @@ unsigned int gsp_phys_rmcall_gr_lmem_tpc_size_value(void) EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_lmem_tpc_size_value); /* + * m84 ctx-image probe (gsp_phys_rmcall_gr_img_probe; default 0). After the + * stage-4 GR sem proof the ladder re-binds the rmcall channel to COPY0, + * copies the first 4 KB of the MAIN context image and of the VEID0 subctx + * header into the DST sysmem chunk through the real CE, dumps them, and + * re-binds GR0. Diagnostic only; each failure is logged and ignored. + */ +static int gsp_phys_rmcall_gr_img_probe_param; +module_param_named(gsp_phys_rmcall_gr_img_probe, + gsp_phys_rmcall_gr_img_probe_param, int, 0644); +MODULE_PARM_DESC(gsp_phys_rmcall_gr_img_probe, + "Stage-4 CE read-back of the GR context image header + VEID0 subctx header (default 0)"); + +int gsp_phys_rmcall_gr_img_probe_value(void) +{ + return gsp_phys_rmcall_gr_img_probe_param; +} +EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_img_probe_value); + +/* * m83 sysmem error notifier (gsp_phys_rmcall_gr_notifier_sys; default 0). * The mode-35 V7 error notifier is normally a server FBMEM class-0x40 memory * object (unreadable). With 1 it is a host sysmem chunk registered as the diff --git a/kernel/gsp_phys_gpu.h b/kernel/gsp_phys_gpu.h index 9bd5624..1b0bac3 100644 --- a/kernel/gsp_phys_gpu.h +++ b/kernel/gsp_phys_gpu.h @@ -366,6 +366,10 @@ int gsp_phys_rmcall_gr_lane_skip_value(void); * records are readable (default 0 = server FBMEM). */ int gsp_phys_rmcall_gr_notifier_sys_value(void); +/* m84: stage-4 CE read-back of the GR context image header + subctx header + * (default 0). */ +int gsp_phys_rmcall_gr_img_probe_value(void); + /* * Ladder VAS ownership selector (gsp_phys_rmcall_vas_shared; default 0). * 0 = FERMI_VASPACE_A is allocated IS_EXTERNALLY_OWNED (historical ladder |
