summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 13:35:23 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-06 13:35:23 -0400
commit61c2434533045524dfbb70e4d9aa82c08a5272db (patch)
tree4266364c4853c96f90611cc6483ee82e6b8510ea
parenta1f9d3f7b77e954a1a9ee36c7f787fe2083b544a (diff)
downloadopen-iov-61c2434533045524dfbb70e4d9aa82c08a5272db.tar.gz
open-iov-61c2434533045524dfbb70e4d9aa82c08a5272db.zip
vgsp: mode-29 construct-last golden execution lane + fetch-aligned USERD control offset
- New mode 29 (GOLDEN_EXEC_LAST): identical to mode 28 but skips the TURING_COMPUTE_A alloc on the client-wired golden channel (every GR object construct there blocks RM); stage 3 completes with the golden handle swapped and BIND/GPFIFO_SCHEDULE/token are accepted. Param clamp 0..29. - Shape bits: bit6 TSG parent (alloc accepted, same no-fetch), bit7 host USERD control offset 0 (THE FETCH FIX: the server applies the sysmem userd_mem base directly and ignores the captured USERD_INDEX_VALUE=3, so GP_PUT/GP_GET live at +0x8c/+0x88; m14: GP_GET advanced 1), bit8 pre-promote compute object (invalid order: RM blocked -110 + NOCAT 0x52a8b04). - Failure diagnostics: REAL GR SEM FAILED now dumps both candidate USERD control offsets (ctl and alt).
-rw-r--r--kernel/gsp_phys_booter.c257
-rw-r--r--kernel/gsp_phys_gpu.c6
2 files changed, 228 insertions, 35 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index c049c44..989c91f 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -638,6 +638,18 @@ bool gsp_phys_boot_requested(void)
*/
#define GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC 28u
/*
+ * Mode 29: the construct-last golden execution lane. Identical to mode 28
+ * (same wired golden channel + 9-entry promote + execution swap + suppressed
+ * V6 promote) with ONE ordering change: the ladder's TURING_COMPUTE_A (0xc5c0)
+ * object alloc is skipped, because every GR object construct on a
+ * client-wired golden channel deadlocks the server (m3a-m3g: -110, RM task
+ * blocked). The golden replay itself skips its TURING_A via shape bit5, so
+ * after the wired channel alloc + promote no construct touches the golden
+ * channel again; BIND/GPFIFO_SCHEDULE/token and every forwarded publish run
+ * object-less (the SET_OBJECT 0xc5c0 binding is the live experiment).
+ */
+#define GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST 29u
+/*
* Mode-28 golden execution channel shape bits (gsp_phys_rmcall_golden_exec_shape,
* default 7). Every combination keeps the captured flags 0x00200320 and the
* FBMEM instance/RAMFC/mthd slices; the bits only choose the client-visible
@@ -650,6 +662,37 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_HOBJ_VAS BIT(4)
#define GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_SKIP_TURING_A BIT(5)
/*
+ * Shape bit6: parent the golden execution channel to the ladder TSG (with
+ * hVASpace=0 per the TSG rule, kernel_channel.c:429-435) instead of the
+ * captured device parenting. The channel that actually fetches on this board
+ * (V6) is TSG-parented (variant skipctx tsg_parent=true) and is scheduled by
+ * TSG_GPFIFO_SCHEDULE; m11's device-parented golden channel accepted BIND +
+ * channel GPFIFO_SCHEDULE but its PBDMA never fetched (GP_PUT=1, GP_GET=0,
+ * no sem release). This bit tests the runlist-membership hypothesis.
+ */
+#define GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_TSG_PARENT BIT(6)
+/*
+ * Shape bit7: point the HOST USERD control offset at +0x0 (instead of the
+ * captured +0x600) while leaving the channel flags captured. Pure H2 probe:
+ * if the server applies the sysmem userd_mem base directly and ignores the
+ * captured USERD_INDEX_VALUE=3, the hardware control block lives at +0x8c
+ * while m11/m12 wrote +0x68c (GP_PUT invisible to the PBDMA, GP_GET stuck 0).
+ * Clearing the flags index instead was m13: the channel alloc is REJECTED
+ * (rpc_result=0x51), so this bit must not touch the flags. The failure-path
+ * diagnostic dumps both candidate offsets.
+ */
+#define GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_USERD_INDEX0 BIT(7)
+/*
+ * Shape bit8: allocate TURING_COMPUTE_A (0xc5c0) on the wired golden channel
+ * BETWEEN the channel alloc and the 9-entry promote (a construct-before-
+ * promote ordering that the m3 series never tested; every construct after the
+ * promote deadlocked). Needed because m14 proved the PBDMA fetches
+ * (GP_GET advances at host offset 0) but the engine methods need the class
+ * object the object-less mode 29 skipped. The handle is GOLDEN_GR_OBJ
+ * (0xcaf00058, free because shape bit5 skips the replay's TURING_A).
+ */
+#define GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_PRE_PROMOTE_COMPUTE_OBJ BIT(8)
+/*
* Existing fwclient mask bit 8: mode-25 gate for the captured VAS
* COPY_SERVER_RESERVED_PDES control. The captured control copies three
* server-RM-internal page-table levels the ladder cannot source safely, so
@@ -707,8 +750,20 @@ bool gsp_phys_boot_requested(void)
* VA_GOLDEN9_PRIV). One VA-only booking entry, like the accepted globals.
*/
#define GSP_PHYS_RMCALL_FWCLIENT_MASK_PRIV_VA_ONLY (1u << 15)
+/*
+ * Mode-25 bisection bit 16: the FECS_EVENT sysmem variant. The FBMEM FECS
+ * entry is refused 0x1f on V6 in every PA-bearing form (combined and
+ * PA-only) while the golden channel accepts the identical entry. The mode-24
+ * sysmem shape (attr 0x6, 4 KB, trust the PA) was never tested alone. With
+ * this bit the FBMEM FECS PA/size are released before the small-buffer
+ * prepare, so the FWCLIENT FECS entry is built from the sysmem chunk
+ * (bit 3 = combined sysmem form) and an extra init-only sysmem entry
+ * (PA + size + attr 0x6, bInitialize=1, bNonmapped=1, like the accepted PM)
+ * is sent after the FECS VA-only booking.
+ */
+#define GSP_PHYS_RMCALL_FWCLIENT_MASK_FECS_SYSMEM (1u << 16)
#define GSP_PHYS_RMCALL_GR_PROMOTE_MAX \
- (GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC)
+ (GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST)
/*
* Work-submit token notifier slot. The default index is
@@ -7555,6 +7610,8 @@ static const char *gsp_phys_rmcall_gr_promote_name(void)
return "mode 27: golden9 9-entry promote on the V6 execution channel only (no golden-channel promote)";
case GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC:
return "mode 28: golden execution lane (golden channel with client GPFIFO/USERD, 9-entry promote on it, execution switched to it)";
+ case GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST:
+ return "mode 29: construct-last golden execution lane (mode 28 minus the TURING_COMPUTE_A object construct on the wired golden channel)";
default:
return "off (PROMOTE_CTX never sent)";
}
@@ -7935,7 +7992,9 @@ static void gsp_phys_rmcall_golden_3d_on_ladder(void __iomem *bar0)
* GR-instance by-product) must not attach a second one to it.
*/
if (boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC)
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST)
return;
ret = gsp_phys_rmcall_alloc_gr_object_class(bar0,
GSP_PHYS_RMCALL_CLASS_GR_3D,
@@ -8196,7 +8255,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
boot_stage.rmcall_gr_promote ==
GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9_V6_ONLY ||
boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) &&
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
gsp_phys_rmcall_engine_is_gr()) {
if (gsp_phys_rmcall_fwclient_mask_value() &
GSP_PHYS_RMCALL_GOLDEN9_MASK_LADDER_VAS) {
@@ -8302,7 +8363,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
boot_stage.rmcall_gr_promote ==
GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9_V6_ONLY ||
boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) &&
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
gsp_phys_rmcall_engine_is_gr()) {
ch.flags = cpu_to_le32(GSP_PHYS_RMCALL_CHANNEL_FLAG_GOLDEN9);
ch.internal_flags = cpu_to_le32(
@@ -8367,7 +8430,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
* object alloc.
*/
if (boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) {
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) {
u32 exec_shape =
gsp_phys_rmcall_golden_exec_shape_value();
@@ -8394,13 +8459,20 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_HOBJ_VAS)
ch.h_object_buffer =
cpu_to_le32(boot_stage.rmcall_vas);
+ if (exec_shape &
+ GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_TSG_PARENT) {
+ ch_parent = boot_stage.rmcall_tsg;
+ ch.h_va_space = cpu_to_le32(0);
+ }
}
pr_info("vgsp-boot: rm-call: GOLDEN9 channel shape: flags=0x%x (PRIVILEGED|USERD_INDEX_VALUE=3|USERD_INDEX_PAGE_FIXED, no SKIP_SCRUBBER/SKIP_CTXBUFFER_ALLOC) hObjectBuffer=0 gpFifoEntries=0x%x instance/userd/ramfc/mthd=FBMEM memdescs block=0x%llx (capture-matched apertures)\n",
GSP_PHYS_RMCALL_CHANNEL_FLAG_GOLDEN9,
GSP_PHYS_RMCALL_GOLDEN_GPFIFO_ENTRIES, golden_fb);
if (boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC)
- pr_info("vgsp-boot: rm-call: GOLDEN EXEC channel shape (mode 28): flags=0x%x (captured) shape=0x%x gpFifoOffset=0x%llx gpFifoEntries=%u hObjectBuffer=0x%x userd=%s size=0x%llx hParent=device hVASpace=0x%x; instance/ramfc/mthd stay FBMEM\n",
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST)
+ pr_info("vgsp-boot: rm-call: GOLDEN EXEC channel shape (mode 28/29): flags=0x%x (captured) shape=0x%x gpFifoOffset=0x%llx gpFifoEntries=%u hObjectBuffer=0x%x userd=%s size=0x%llx hParent=%s hVASpace=0x%x; instance/ramfc/mthd stay FBMEM\n",
GSP_PHYS_RMCALL_CHANNEL_FLAG_GOLDEN9,
gsp_phys_rmcall_golden_exec_shape_value(),
le64_to_cpu(ch.gp_fifo_offset),
@@ -8410,7 +8482,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
cpu_to_le32(GSP_PHYS_RMCALL_ADDR_SYSMEM)) ?
"sysmem" : "FBMEM",
le64_to_cpu(ch.userd_mem.size),
- boot_stage.rmcall_vas);
+ ch_parent == boot_stage.rmcall_tsg ?
+ "ladder-TSG" : "device",
+ le32_to_cpu(ch.h_va_space));
}
ret = gsp_phys_rmcall_alloc(bar0, boot_stage.rmcall_client,
ch_parent,
@@ -8432,6 +8506,38 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
}
/*
+ * Shape bit8: allocate the TURING_COMPUTE_A (0xc5c0) object on the
+ * wired golden channel BEFORE the 9-entry promote. Every construct
+ * AFTER the promote on a client-wired golden channel deadlocked RM
+ * (m3a-m3g); the before-promote ordering is untested. The m14 result
+ * (GP_GET advances at +0x88 -> the PBDMA fetches) shows the remaining
+ * blocker is engine-method execution, and the engine methods
+ * (SET_OBJECT/SET_REPORT_SEMAPHORE 0xc5c0) need this class object in
+ * the channel's context, which mode 29 skipped.
+ */
+ if ((boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
+ (gsp_phys_rmcall_golden_exec_shape_value() &
+ GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_PRE_PROMOTE_COMPUTE_OBJ)) {
+ ret = gsp_phys_rmcall_alloc_gr_object_class(bar0,
+ GSP_PHYS_RMCALL_CLASS_COMPUTE,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_GR_OBJ,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_CHANNEL,
+ "GOLDEN pre-promote TURING_COMPUTE_A", &rpc,
+ &status);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: GOLDEN pre-promote TURING_COMPUTE_A (0xc5c0) alloc failed (status=0x%x rpc_result=0x%x ret=%d); the golden replay aborts with no retry\n",
+ status, rpc, ret);
+ return ret;
+ }
+ pr_info("vgsp-boot: rm-call: GOLDEN pre-promote TURING_COMPUTE_A (0xc5c0) allocated on the wired golden channel 0x%x (hObj=0x%x) before the promote\n",
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_CHANNEL,
+ GSP_PHYS_RMCALL_HANDLE_GOLDEN_GR_OBJ);
+ }
+
+ /*
* Mode 25: the single atomic 9-entry GPU_PROMOTE_CTX on the golden
* channel, in the captured order/forms. It runs after the channel
* alloc and before the 3D object, matching the wire order of the real
@@ -8445,7 +8551,9 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
boot_stage.rmcall_gr_promote ==
GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9_V6 ||
boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) &&
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
gsp_phys_rmcall_engine_is_gr()) {
ret = gsp_phys_rmcall_golden9_promote(bar0);
if (ret)
@@ -8453,8 +8561,10 @@ static int gsp_phys_rmcall_golden_replay(void __iomem *bar0)
}
/* 6. TURING_A (0xc597) 3D object on the golden channel (kernel_graphics.c:2409-2433). */
- if (boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC &&
+ if ((boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
(gsp_phys_rmcall_golden_exec_shape_value() &
GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_SKIP_TURING_A)) {
pr_info("vgsp-boot: rm-call: mode 28: GOLDEN TURING_A 3D object skipped (shape bit5); the ladder's TURING_COMPUTE_A on the same channel provides the GR instance state\n");
@@ -9915,7 +10025,12 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
int ret;
if (!boot_stage.rmcall_ctx_prepared ||
- !boot_stage.rmcall_channel || !boot_stage.rmcall_gr_object)
+ !boot_stage.rmcall_channel ||
+ (!boot_stage.rmcall_gr_object &&
+ boot_stage.rmcall_gr_promote !=
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC &&
+ boot_stage.rmcall_gr_promote !=
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST))
return -EINVAL;
if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_OFF)
return -EOPNOTSUPP;
@@ -9927,7 +10042,8 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
*/
if ((mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9 ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9_V6_ONLY ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) &&
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
(!gsp_phys_rmcall_golden_enabled() || !gsp_phys_gpu_enabled())) {
pr_err("vgsp-boot: rm-call: mode %u requires gsp_phys_rmcall_golden=1 and gsp_phys_gpu=1 (the golden replay did not run); no PROMOTE_CTX is sent and the ladder aborts with no retry\n",
mode);
@@ -9938,8 +10054,9 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
* channel inside the golden replay (it owns the committed context and
* the forwarded launches); nothing is sent on the V6 channel at all.
*/
- if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) {
- pr_info("vgsp-boot: rm-call: mode-28 golden execution lane: no PROMOTE_CTX on V6 (the golden channel 0x%x carries the committed context); continuing to stage 4 on the golden channel\n",
+ if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) {
+ pr_info("vgsp-boot: rm-call: mode-28/29 golden execution lane: no PROMOTE_CTX on V6 (the golden channel 0x%x carries the committed context); continuing to stage 4 on the golden channel\n",
GSP_PHYS_RMCALL_HANDLE_GOLDEN_CHANNEL);
boot_stage.rmcall_gr_promote_step = 1;
return 0;
@@ -10693,6 +10810,22 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
}
if (gsp_phys_rmcall_gr_pm_prepare(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");
+ /*
+ * Bit 16: release the FBMEM FECS booking so the small-buffer
+ * prepare allocates the sysmem 4 KB chunk and the FECS entries
+ * are built in the mode-24 sysmem shape (attr 0x6). The FBMEM
+ * chunk/PA itself stays allocated server-side and the PDB
+ * FECS VA mapping is untouched; only the promote entry source
+ * changes.
+ */
+ if ((mask & GSP_PHYS_RMCALL_FWCLIENT_MASK_FECS_SYSMEM) &&
+ boot_stage.rmcall_fecs_pa && boot_stage.rmcall_fecs_size) {
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX fwclient FECS sysmem variant: releasing the FBMEM FECS pa=0x%llx size=0x%x to force the sysmem small buffer\n",
+ boot_stage.rmcall_fecs_pa,
+ boot_stage.rmcall_fecs_size);
+ boot_stage.rmcall_fecs_pa = 0;
+ boot_stage.rmcall_fecs_size = 0;
+ }
gsp_phys_rmcall_gr_fwclient_small_prepare();
/*
@@ -11106,6 +11239,35 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
GSP_PHYS_RMCALL_VA_GOLDEN9_PRIV, status,
rpc_result, boot_stage.rmcall_channel);
}
+
+ /*
+ * Bit 16: the FECS init-only sysmem entry (PA + size + sysmem
+ * attr 0x6, bInitialize=1, bNonmapped=1) - the form the accepted
+ * PM entry uses, with the mode-24 sysmem buffer the bit released
+ * above. Sent after the FECS VA-only booking so the pair is
+ * complete either way.
+ */
+ if ((mask & GSP_PHYS_RMCALL_FWCLIENT_MASK_FECS_SYSMEM) &&
+ boot_stage.rmcall_fecs_pa) {
+ gsp_phys_rmcall_promote_entry_fill(p, 0, 9,
+ boot_stage.rmcall_fecs_pa, 0, 0x1000u,
+ GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR, 1, 1);
+ 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 (FECS sysmem init-only)");
+ pr_info("vgsp-boot: rm-call: PROMOTE_CTX FECS sysmem init-only: bufferId=9 pa=0x%llx size=0x1000 physAttr=0x%x status=0x%x rpc_result=0x%x (hObject=0x%x)\n",
+ boot_stage.rmcall_fecs_pa,
+ GSP_PHYS_RMCALL_GR_CTX_PHYS_ATTR, status,
+ rpc_result, boot_stage.rmcall_channel);
+ } else if (mask & GSP_PHYS_RMCALL_FWCLIENT_MASK_FECS_SYSMEM) {
+ pr_warn("vgsp-boot: rm-call: PROMOTE_CTX FECS sysmem init-only skipped: no sysmem FECS buffer prepared\n");
+ }
} 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);
@@ -11715,7 +11877,9 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0)
if ((boot_stage.rmcall_gr_promote ==
GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN9 ||
boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) &&
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
gsp_phys_rmcall_engine_is_gr()) {
pr_err("vgsp-boot: rm-call: stage 3 aborted: mode-%u golden replay failed (%d); the golden construct is atomic and is not retried\n",
boot_stage.rmcall_gr_promote, ret);
@@ -11771,12 +11935,17 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0)
* early in gsp_phys_rmcall_gr_ctx_promote).
*/
if (gsp_phys_rmcall_engine_is_gr() &&
- boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC) {
- pr_info("vgsp-boot: rm-call: mode 28: execution channel switched from V6 0x%x to golden execution channel 0x%x (client ring gpFifoVa=0x%llx userd=sysmem, device-parented); the V6 channel stays unscheduled\n",
+ (boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST)) {
+ pr_info("vgsp-boot: rm-call: mode 28/29: execution channel switched from V6 0x%x to golden execution channel 0x%x (client ring gpFifoVa=0x%llx userd=%s, device-parented); the V6 channel stays unscheduled\n",
boot_stage.rmcall_channel,
GSP_PHYS_RMCALL_HANDLE_GOLDEN_CHANNEL,
- GSP_PHYS_RMCALL_VA_GPFIFO);
+ GSP_PHYS_RMCALL_VA_GPFIFO,
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST ?
+ "sysmem" : "captured");
boot_stage.rmcall_channel =
GSP_PHYS_RMCALL_HANDLE_GOLDEN_CHANNEL;
boot_stage.rmcall_channel_server_mem = false;
@@ -11793,11 +11962,17 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0)
*/
if (gsp_phys_rmcall_engine_is_gr()) {
gsp_phys_rmcall_golden_3d_on_ladder(bar0);
- ret = gsp_phys_rmcall_alloc_gr_object(bar0);
- if (ret) {
- pr_err("vgsp-boot: rm-call: stage 3 aborted: TURING_COMPUTE_A (0xc5c0) engine object alloc failed (%d); the GR ladder has no engine object to bind and is not retried\n",
- ret);
- return ret;
+ if (boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) {
+ pr_info("vgsp-boot: rm-call: mode 29: skipping the TURING_COMPUTE_A (0xc5c0) object alloc: every GR object construct on the client-wired golden channel deadlocked the server (m3a-m3g); the golden execution lane runs object-less (the SET_OBJECT 0xc5c0 binding is the live experiment)\n");
+ boot_stage.rmcall_gr_object = 0;
+ } else {
+ ret = gsp_phys_rmcall_alloc_gr_object(bar0);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: stage 3 aborted: TURING_COMPUTE_A (0xc5c0) engine object alloc failed (%d); the GR ladder has no engine object to bind and is not retried\n",
+ ret);
+ return ret;
+ }
}
/*
* gr_promote_param=0 stops here: the whole pre-promote half
@@ -12016,10 +12191,18 @@ struct gsp_phys_rmcall_ce_submit {
*/
static u32 gsp_phys_rmcall_userd_ctl_off(void)
{
- if (boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC &&
- gsp_phys_rmcall_engine_is_gr())
+ if ((boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST) &&
+ gsp_phys_rmcall_engine_is_gr()) {
+ if (boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_GOLDEN_EXEC_LAST &&
+ (gsp_phys_rmcall_golden_exec_shape_value() &
+ GSP_PHYS_RMCALL_GOLDEN_EXEC_SHAPE_USERD_INDEX0))
+ return 0;
return GSP_PHYS_RMCALL_USERD_CTL_OFF_CAPTURED;
+ }
return 0;
}
@@ -12267,14 +12450,24 @@ static int gsp_phys_rmcall_gr_sem_push_locked(void __iomem *bar0)
if (poll == GSP_PHYS_RMCALL_SEM_PAYLOAD)
break;
if (time_after_eq(jiffies, deadline)) {
- gpget = get_unaligned_le32((u8 *)userd + gsp_phys_rmcall_userd_ctl_off() +
+ u32 off = gsp_phys_rmcall_userd_ctl_off();
+ u32 alt = off ? 0u :
+ GSP_PHYS_RMCALL_USERD_CTL_OFF_CAPTURED;
+
+ gpget = get_unaligned_le32((u8 *)userd + off +
GSP_PHYS_RMCALL_USERD_GPGET_OFF);
- gpput = get_unaligned_le32((u8 *)userd + gsp_phys_rmcall_userd_ctl_off() +
+ gpput = get_unaligned_le32((u8 *)userd + off +
GSP_PHYS_RMCALL_USERD_GPPUT_OFF);
- pr_err("vgsp-boot: rm-call: REAL GR SEM FAILED: no release within %u ms (sem=0x%08x want=0x%08x GPGet=%u GPPut=%u engine=%s); the channel did not execute the GR block\n",
+ pr_err("vgsp-boot: rm-call: REAL GR SEM FAILED: no release within %u ms (sem=0x%08x want=0x%08x GPGet=%u GPPut=%u engine=%s); the channel did not execute the GR block (ctl=0x%x GPGet=%u GPPut=%u | alt ctl=0x%x GPGet=%u GPPut=%u)\n",
GSP_PHYS_RMCALL_TIMEOUT_MS, poll,
GSP_PHYS_RMCALL_SEM_PAYLOAD, gpget, gpput,
- gsp_phys_rmcall_engine_name());
+ gsp_phys_rmcall_engine_name(),
+ off, gpget, gpput,
+ alt,
+ get_unaligned_le32((u8 *)userd + alt +
+ GSP_PHYS_RMCALL_USERD_GPGET_OFF),
+ get_unaligned_le32((u8 *)userd + alt +
+ GSP_PHYS_RMCALL_USERD_GPPUT_OFF));
gsp_phys_status_drain(NULL);
return -ETIMEDOUT;
}
diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c
index 61ec22e..47a7b32 100644
--- a/kernel/gsp_phys_gpu.c
+++ b/kernel/gsp_phys_gpu.c
@@ -551,8 +551,8 @@ static int gsp_phys_rmcall_gr_promote_set(const char *val,
return ret;
if (gsp_phys_rmcall_gr_promote_param < 0 ||
- gsp_phys_rmcall_gr_promote_param > 28) {
- pr_warn("vgsp: gsp_phys_rmcall_gr_promote=%d is outside 0..28; clamping to 0 (no PROMOTE_CTX)\n",
+ gsp_phys_rmcall_gr_promote_param > 29) {
+ pr_warn("vgsp: gsp_phys_rmcall_gr_promote=%d is outside 0..29; clamping to 0 (no PROMOTE_CTX)\n",
gsp_phys_rmcall_gr_promote_param);
gsp_phys_rmcall_gr_promote_param = 0;
}
@@ -571,7 +571,7 @@ module_param_cb(gsp_phys_rmcall_gr_promote,
&gsp_phys_rmcall_gr_promote_ops,
&gsp_phys_rmcall_gr_promote_param, 0644);
MODULE_PARM_DESC(gsp_phys_rmcall_gr_promote,
- "GR context-promote bisection (default 0: never send PROMOTE_CTX; 1: single entry init+nonmapped=0 size=raw+subctx, the p6h1b shape; 2: two-phase PA-only nonmapped then VA-only with the same fields; 3: single entry size=raw; 4: two-phase with a zero-field VA-only step; 5: batched entryCount=2 PA-only init + zero-field VA-only; 6: no-entry hVirtMemory, NV01_MEMORY_VIRTUAL (class 0x70) on the VAS at the context window + PROMOTE_CTX entryCount=0; 7: no-entry bare virtAddress+size, entryCount=0; 8: single MAIN entry like 1 on the KMD-managed channel (V6 SKIP_CTXBUFFER_ALLOC), server creates the virtual context memdesc itself; 9: same V6 channel with the stock client's zero-field VA-only MAIN entry, bInitialize=0; 10: same V6 channel, GPU_INITIALIZE_CTX (0x2080012d) installs the physical context memdesc then PROMOTE_CTX entryCount=0 bare virtAddress+size; 11: mode 10 with a server FBMEM context buffer, VIDMEM physAttr 0x4; 12: V5 UVM/vGPU-faithful PA-only MAIN entry (bInitialize=1 bNonmapped=1, no VA) and continue to BIND/SCHEDULE/submit; 13: mode 12 plus a PATCH PA-only promote first, sized from GET_ENGINE_CONTEXT_PROPERTIES engineId 0x10; 14: KMD channel (V6) + PATCH PA-only then the single-entry MAIN init+VA (the flow that books the context VA and commits ENG_CTX_VALID); 15: mode 14 with a server FBMEM MAIN context buffer and VIDMEM physAttr 0x4; 16: mode 14 plus a PM ctxsw PA-only promote first; 17: no client PROMOTE_CTX, paired with gsp_phys_srv_ctxbuf=1 so the GSP-RM server-manages and commits the context; 18: mode 8 shape plus a client FERMI_CONTEXT_SHARE_A on the TSG (hContextShare) whose construct allocates the GraphicsSubcontext; 19: the stock guest's exact 9-entry promote set (MAIN 2 MB PA+VA, PATCH, global buffers, FECS event, private access maps) on V5; 20: mode 6's no-entry hVirtMemory promote on the KMD-managed V6 channel (SKIP_CTXBUFFER_ALLOC), untested - the combination the V5 refusal (0x1f) points at; 21: mode 7's no-entry bare (virtAddress, size) promote on the V6 KMD-managed channel; 22: GPU_INITIALIZE_CTX then mode 20's no-entry hVirtMemory promote; 23: the hVirtMemory no-entry promote backed by the server-owned FBMEM context object (GSP_RM_ALLOC class 0x40) on the server-managed shared V5 channel - a physical memdesc reaches the per-buffer commit without the ADDR_VIRTUAL vaList gate; 24: the reference FWCLIENT non-3D set {MAIN, PM, PATCH, FECS_EVENT, PRIV_ACCESS_MAP, UNRESTRICTED_PRIV_ACCESS_MAP} as one control on the V6 KMD-managed channel, combined PA+VA entries where the ladder has a VA (MAIN PDB-mapped; PATCH/FECS/UNRESTRICTED booking-only), PM and PRIV_ACCESS_MAP init-only (no VA source), unsourceable buffers omitted and logged); 25: the real golden-client construct on the golden replay handles (captured channel flags 0x00200320 + single atomic 9-entry PROMOTE_CTX on the golden channel), then the V6 FWCLIENT follow-on promote on the golden-initialized GR-instance state; requires gsp_phys_rmcall_golden=1 and gsp_phys_rmcall_engine=1; 26/27: golden9 promote on the V6 execution channel (dead ends); 28: the golden execution lane - the golden channel gets a client GPFIFO ring (VA_GPFIFO), a sysmem host-writable USERD and the ladder TSG as parent, keeps the 9-entry promote, and the ladder switches execution to it (V6 stays unscheduled); values outside 0..28 clamp to 0 with a warning");
+ "GR context-promote bisection (default 0: never send PROMOTE_CTX; 1: single entry init+nonmapped=0 size=raw+subctx, the p6h1b shape; 2: two-phase PA-only nonmapped then VA-only with the same fields; 3: single entry size=raw; 4: two-phase with a zero-field VA-only step; 5: batched entryCount=2 PA-only init + zero-field VA-only; 6: no-entry hVirtMemory, NV01_MEMORY_VIRTUAL (class 0x70) on the VAS at the context window + PROMOTE_CTX entryCount=0; 7: no-entry bare virtAddress+size, entryCount=0; 8: single MAIN entry like 1 on the KMD-managed channel (V6 SKIP_CTXBUFFER_ALLOC), server creates the virtual context memdesc itself; 9: same V6 channel with the stock client's zero-field VA-only MAIN entry, bInitialize=0; 10: same V6 channel, GPU_INITIALIZE_CTX (0x2080012d) installs the physical context memdesc then PROMOTE_CTX entryCount=0 bare virtAddress+size; 11: mode 10 with a server FBMEM context buffer, VIDMEM physAttr 0x4; 12: V5 UVM/vGPU-faithful PA-only MAIN entry (bInitialize=1 bNonmapped=1, no VA) and continue to BIND/SCHEDULE/submit; 13: mode 12 plus a PATCH PA-only promote first, sized from GET_ENGINE_CONTEXT_PROPERTIES engineId 0x10; 14: KMD channel (V6) + PATCH PA-only then the single-entry MAIN init+VA (the flow that books the context VA and commits ENG_CTX_VALID); 15: mode 14 with a server FBMEM MAIN context buffer and VIDMEM physAttr 0x4; 16: mode 14 plus a PM ctxsw PA-only promote first; 17: no client PROMOTE_CTX, paired with gsp_phys_srv_ctxbuf=1 so the GSP-RM server-manages and commits the context; 18: mode 8 shape plus a client FERMI_CONTEXT_SHARE_A on the TSG (hContextShare) whose construct allocates the GraphicsSubcontext; 19: the stock guest's exact 9-entry promote set (MAIN 2 MB PA+VA, PATCH, global buffers, FECS event, private access maps) on V5; 20: mode 6's no-entry hVirtMemory promote on the KMD-managed V6 channel (SKIP_CTXBUFFER_ALLOC), untested - the combination the V5 refusal (0x1f) points at; 21: mode 7's no-entry bare (virtAddress, size) promote on the V6 KMD-managed channel; 22: GPU_INITIALIZE_CTX then mode 20's no-entry hVirtMemory promote; 23: the hVirtMemory no-entry promote backed by the server-owned FBMEM context object (GSP_RM_ALLOC class 0x40) on the server-managed shared V5 channel - a physical memdesc reaches the per-buffer commit without the ADDR_VIRTUAL vaList gate; 24: the reference FWCLIENT non-3D set {MAIN, PM, PATCH, FECS_EVENT, PRIV_ACCESS_MAP, UNRESTRICTED_PRIV_ACCESS_MAP} as one control on the V6 KMD-managed channel, combined PA+VA entries where the ladder has a VA (MAIN PDB-mapped; PATCH/FECS/UNRESTRICTED booking-only), PM and PRIV_ACCESS_MAP init-only (no VA source), unsourceable buffers omitted and logged); 25: the real golden-client construct on the golden replay handles (captured channel flags 0x00200320 + single atomic 9-entry PROMOTE_CTX on the golden channel), then the V6 FWCLIENT follow-on promote on the golden-initialized GR-instance state; requires gsp_phys_rmcall_golden=1 and gsp_phys_rmcall_engine=1; 26/27: golden9 promote on the V6 execution channel (dead ends); 28: the golden execution lane - the golden channel gets a client GPFIFO ring (VA_GPFIFO), a sysmem host-writable USERD and the ladder TSG as parent, keeps the 9-entry promote, and the ladder switches execution to it (V6 stays unscheduled); 29: mode 28 minus the TURING_COMPUTE_A (0xc5c0) object construct on the client-wired golden channel (every GR object construct there deadlocks RM), i.e. the construct-last golden execution lane; values outside 0..29 clamp to 0 with a warning");
int gsp_phys_rmcall_gr_promote_value(void)
{