summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 11:16:02 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-07 11:16:02 -0400
commit4541bae601a330d2a22a21d9e24d0fe879ebf618 (patch)
tree8665b8abb113776a727758653d8207db754505e2 /kernel
parent26f0006adcb9dc83d41a3bf84f386892f33bde83 (diff)
downloadopen-iov-4541bae601a330d2a22a21d9e24d0fe879ebf618.tar.gz
open-iov-4541bae601a330d2a22a21d9e24d0fe879ebf618.zip
vgsp: m83 - host-readable sysmem error notifier for the RM's channel-error records
NV_PGRAPH_EXCEPTION reads 0x01000000 (GPC) with EXCEPTION1 GPC1:0=0b11 at the QMD activation; the fault record the engine writes goes to the channel's error notifier, which is server FBMEM today and unreadable. gsp_phys_rmcall_gr_notifier_sys=1 registers a host sysmem chunk as the hObjectError memory object and carries it in the channel's errorNotifierMem with the SYS aperture, so the RM's asynchronous channel-error report is dumped in the launch post-mortem (the m35 lane still uses the captured substitute object shape).
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c69
-rw-r--r--kernel/gsp_phys_gpu.c20
-rw-r--r--kernel/gsp_phys_gpu.h4
3 files changed, 92 insertions, 1 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 5a5287f..8bf94d8 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -12707,6 +12707,46 @@ static int gsp_phys_rmcall_user_lane_notifier(void __iomem *bar0)
u64 base = 0;
int ret;
+ /*
+ * m83: host-visible sysmem error notifier (gsp_phys_rmcall_gr_notifier_sys;
+ * default 0). The RM writes asynchronous channel error records into the
+ * context's error notifier; with the FBMEM aperture nothing can read them
+ * (the m66..m82 GPC exception has never been decodable). A sysmem chunk
+ * registered as the hObjectError memory object makes the RM's own fault
+ * record readable from the host.
+ */
+ if (gsp_phys_rmcall_gr_notifier_sys_value()) {
+ struct gsp_phys_boot_chunk *n =
+ &boot_stage.rmcall_user_lane_notifier;
+
+ if (!boot_stage.pdev) {
+ pr_err("vgsp-boot: rm-call: mode 35 sysmem error-notifier: no claimed pci_dev\n");
+ return -EINVAL;
+ }
+ if (!n->pages) {
+ ret = gsp_phys_chunk_alloc(boot_stage.pdev, n,
+ GSP_PHYS_RMCALL_NOTIFIER_SIZE /
+ GSP_PHYS_PAGE_SIZE);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: mode 35 sysmem error-notifier chunk allocation failed (%d)\n",
+ ret);
+ return ret;
+ }
+ gsp_phys_chunk_zero(n);
+ }
+ ret = gsp_phys_rmcall_register_chunk(bar0, n,
+ GSP_PHYS_RMCALL_HANDLE_USER_LANE_NOTIFIER,
+ "mode 35 user-lane error notifier (sysmem m83)");
+ if (ret)
+ return ret;
+ base = (u64)gsp_phys_chunk_page_dma(n, 0);
+ boot_stage.rmcall_user_lane_notifier_pa = base;
+ pr_info("vgsp-boot: rm-call: mode 35 user-lane error notifier: hObject=0x%x SYSMEM pa=0x%llx size=0x%x (host-readable RM fault records; m83)\n",
+ GSP_PHYS_RMCALL_HANDLE_USER_LANE_NOTIFIER, base,
+ GSP_PHYS_RMCALL_NOTIFIER_SIZE);
+ return 0;
+ }
+
ret = gsp_phys_rmcall_alloc_fb_mem(bar0,
GSP_PHYS_RMCALL_HANDLE_USER_LANE_NOTIFIER,
GSP_PHYS_RMCALL_NOTIFIER_SIZE, &base,
@@ -12869,7 +12909,9 @@ static int gsp_phys_rmcall_alloc_user_lane_channel(void __iomem *bar0)
ch.error_notifier_mem.size =
cpu_to_le64(GSP_PHYS_RMCALL_NOTIFIER_SIZE);
ch.error_notifier_mem.address_space =
- cpu_to_le32(GSP_PHYS_RMCALL_ADDR_FBMEM);
+ cpu_to_le32(gsp_phys_rmcall_gr_notifier_sys_value() ?
+ GSP_PHYS_RMCALL_ADDR_SYSMEM :
+ GSP_PHYS_RMCALL_ADDR_FBMEM);
ch.error_notifier_mem.cache_attrib =
cpu_to_le32(GSP_PHYS_RMCALL_CACHE_UNCACHED);
@@ -16660,6 +16702,31 @@ gr_page_unmapped:
p1[0], p1[1], p1[2], p1[3],
p1[4], p1[5], p1[6], p1[7]);
}
+ /*
+ * m83: the RM's asynchronous channel-error reports
+ * land in the error notifier; with the sysmem
+ * aperture they are host-readable after a failure.
+ */
+ if (gsp_phys_rmcall_gr_notifier_sys_value()) {
+ struct gsp_phys_boot_chunk *nt =
+ &boot_stage.rmcall_user_lane_notifier;
+ const u32 *np = nt->pages ?
+ gsp_phys_chunk_page_va(nt, 0) : NULL;
+ u32 i;
+
+ if (np) {
+ for (i = 0; i < 32; i += 8)
+ pr_info("vgsp-gr: post-mortem notifier w%u..%u = %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ i, i + 7,
+ np[i], np[i + 1],
+ np[i + 2],
+ np[i + 3],
+ np[i + 4],
+ np[i + 5],
+ np[i + 6],
+ np[i + 7]);
+ }
+ }
{
u8 *qp2 = qmd_dst_mem ? qmd_dst_mem :
(req->qmd_hpa ?
diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c
index a71ab97..f094d36 100644
--- a/kernel/gsp_phys_gpu.c
+++ b/kernel/gsp_phys_gpu.c
@@ -796,6 +796,26 @@ unsigned int gsp_phys_rmcall_gr_lmem_tpc_size_value(void)
EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_lmem_tpc_size_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
+ * hObjectError memory object and carried in the channel's errorNotifierMem
+ * with the SYS aperture, so the RM's asynchronous channel-error records for
+ * the GPC exception are readable (dumped in the launch post-mortem).
+ */
+static int gsp_phys_rmcall_gr_notifier_sys_param;
+module_param_named(gsp_phys_rmcall_gr_notifier_sys,
+ gsp_phys_rmcall_gr_notifier_sys_param, int, 0644);
+MODULE_PARM_DESC(gsp_phys_rmcall_gr_notifier_sys,
+ "Mode-35 error notifier as host sysmem (RM fault records readable; default 0)");
+
+int gsp_phys_rmcall_gr_notifier_sys_value(void)
+{
+ return gsp_phys_rmcall_gr_notifier_sys_param;
+}
+EXPORT_SYMBOL_GPL(gsp_phys_rmcall_gr_notifier_sys_value);
+
+/*
* m78 lane-enable skip mask (gsp_phys_rmcall_gr_lane_skip; default 0). Bit 0
* skips R2 #1059 GR_SET_CTXSW_PREEMPTION_MODE (CILP), bit 1 skips #1061
* SET_TIMESLICE, bit 2 skips #1063 device-sched. Used to bisect which
diff --git a/kernel/gsp_phys_gpu.h b/kernel/gsp_phys_gpu.h
index 216c96e..9bd5624 100644
--- a/kernel/gsp_phys_gpu.h
+++ b/kernel/gsp_phys_gpu.h
@@ -362,6 +362,10 @@ int gsp_phys_rmcall_gr_lane_tail_value(void);
* 4=#1063 device-sched); default 0 = send all. */
int gsp_phys_rmcall_gr_lane_skip_value(void);
+/* m83: mode-35 error notifier as host sysmem so the RM's channel-error
+ * records are readable (default 0 = server FBMEM). */
+int gsp_phys_rmcall_gr_notifier_sys_value(void);
+
/*
* Ladder VAS ownership selector (gsp_phys_rmcall_vas_shared; default 0).
* 0 = FERMI_VASPACE_A is allocated IS_EXTERNALLY_OWNED (historical ladder