summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 15:17:34 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 15:17:34 -0400
commit2745906f5cc359dff8eb13178eca6226d9f41a14 (patch)
tree5f4bddff4980286d857e24f0205fad4d7bf2f570 /kernel
parent2eb02d6b0e7aa1a2170d94978d513a550067d775 (diff)
downloadopen-iov-2745906f5cc359dff8eb13178eca6226d9f41a14.tar.gz
open-iov-2745906f5cc359dff8eb13178eca6226d9f41a14.zip
kernel: GR promote mode 18 (client FERMI_CONTEXT_SHARE_A via hContextShare)
- gsp_phys_booter: mode 18 allocates a FERMI_CONTEXT_SHARE_A (0x9067) on the TSG with the ladder VAS and carries it as hContextShare on the V6 KMD channel, so the share construct can allocate the GraphicsSubcontext the single-MAIN promote needs; clamp 0..18 - docs/eng-ops: GR promote bisection row updated with the session-2 results (modes 12-18: PA-only accepted but no ENG_CTX_VALID; PATCH/PM/FBMEM and server-managed registry all leave the KMD promote at 0x40; wall is the commit/RAMFC path)
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c106
-rw-r--r--kernel/gsp_phys_gpu.c6
2 files changed, 105 insertions, 7 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index c77e2e2..afbfe28 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -229,6 +229,14 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_CLASS_CHANNEL 0xc46fu
#define GSP_PHYS_RMCALL_CLASS_CE 0xc5b5u
#define GSP_PHYS_RMCALL_CLASS_VASPACE 0x90f1u
+/*
+ * FERMI_CONTEXT_SHARE_A (0x9067): the client context-share object a Volta+
+ * channel attaches to via hContextShare. Its constructor runs
+ * kctxshareInit_PHYSICAL, which allocates the per-veid GraphicsSubcontext
+ * that grctxGetSubctxHeaderVa / _grctxAllocSubctxHeader require - the
+ * leading candidate for the 0x40 the V6 KMD promote returns.
+ */
+#define GSP_PHYS_RMCALL_CLASS_CTXSHARE 0x9067u
#define GSP_PHYS_RMCALL_CTRL_GET_WORK_SUBMIT_TOKEN 0xc36f0108u
#define GSP_PHYS_RMCALL_CTRL_SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX 0xc36f010au
#define GSP_PHYS_RMCALL_CTRL_GPFIFO_SCHEDULE 0xa06f0103u
@@ -405,8 +413,15 @@ bool gsp_phys_boot_requested(void)
* GR channel valid where every client-owned-buffer promote returned 0x40.
*/
#define GSP_PHYS_RMCALL_GR_PROMOTE_SERVER 17u
+/*
+ * Mode 18 (2026-10-02): mode 8 (V6 KMD single MAIN init+VA) plus an explicit
+ * client FERMI_CONTEXT_SHARE_A allocated on the TSG before the channel and
+ * carried as hContextShare. Its construct allocates the GraphicsSubcontext
+ * (VEID 0) whose absence is the leading candidate for the promote's 0x40.
+ */
+#define GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE 18u
#define GSP_PHYS_RMCALL_GR_PROMOTE_MAX \
- (GSP_PHYS_RMCALL_GR_PROMOTE_SERVER)
+ (GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE)
/*
* Work-submit token notifier slot. The default index is
@@ -586,6 +601,7 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_HANDLE_MEM_STRIDE 4u
#define GSP_PHYS_RMCALL_HANDLE_MEM_VIRT 0xcaf00030u
#define GSP_PHYS_RMCALL_HANDLE_CTX_FB 0xcaf00038u
+#define GSP_PHYS_RMCALL_HANDLE_CTXSHARE 0xcaf0003cu
/*
* NVOS04_FLAGS_CHANNEL_SKIP_SCRUBBER bit 23 (alloc/alloc_channel.h:223-225);
@@ -1212,6 +1228,10 @@ static struct gsp_phys_boot_stage {
u32 rmcall_subdevice;
u32 rmcall_vas; /* explicit FERMI_VASPACE_A handle */
u32 rmcall_tsg;
+ u32 rmcall_ctxshare; /* explicit FERMI_CONTEXT_SHARE_A handle
+ * (mode 18: the client context share
+ * whose construct allocates the
+ * GraphicsSubcontext) */
u32 rmcall_channel;
u32 rmcall_channel_variant; /* winning stage-3 variant (0=none; see
* the variant table for its number) */
@@ -1857,6 +1877,7 @@ static void gsp_phys_rmcall_reset(void)
boot_stage.rmcall_subdevice = 0;
boot_stage.rmcall_vas = 0;
boot_stage.rmcall_tsg = 0;
+ boot_stage.rmcall_ctxshare = 0;
boot_stage.rmcall_channel = 0;
boot_stage.rmcall_channel_variant = 0;
boot_stage.rmcall_channel_server_mem = false;
@@ -5695,6 +5716,14 @@ struct gsp_phys_rmcall_tsg_params {
u8 pad[3];
};
+/* NV_CTXSHARE_ALLOCATION_PARAMETERS (nvos.h:2834-2838), 12 bytes:
+ * hVASpace/flags/subctxId; SYNC (flags 0) returns VEID 0 as subctxId. */
+struct gsp_phys_rmcall_ctxshare_params {
+ __le32 h_va_space;
+ __le32 flags;
+ __le32 subctx_id;
+};
+
/*
* NV_CHANNEL_ALLOC_PARAMS (alloc/alloc_channel.h:296-342), 368 bytes.
* hUserdMemory[0]=0 with a physical userdMem descriptor is legal
@@ -6663,6 +6692,8 @@ static const char *gsp_phys_rmcall_gr_promote_name(void)
return "as mode 14 plus a PM ctxsw PA-only promote first";
case GSP_PHYS_RMCALL_GR_PROMOTE_SERVER:
return "no client promote; server-managed ctx buffers (gsp_phys_srv_ctxbuf=1)";
+ case GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE:
+ return "mode 8 shape plus a client FERMI_CONTEXT_SHARE_A (hContextShare) that allocates the GraphicsSubcontext";
default:
return "off (PROMOTE_CTX never sent)";
}
@@ -6743,6 +6774,14 @@ gsp_phys_rmcall_channel_params_init(struct gsp_phys_rmcall_channel_params *ch,
ch->sub_device_id = cpu_to_le32(0);
ch->internal_flags = cpu_to_le32(v->internal_flags);
/*
+ * Mode 18: attach the channel to the client-allocated context share
+ * (its construct allocated the GraphicsSubcontext the promote needs)
+ * instead of letting the server create a legacy share.
+ */
+ if (boot_stage.rmcall_ctxshare)
+ ch->h_context_share =
+ cpu_to_le32(boot_stage.rmcall_ctxshare);
+ /*
* The error-context notifier must be an FBMEM memdesc on GSP
* (kernel_channel.c:1924-1925) and the server builds pErrContextMemDesc
* from these fields; carry the stage-3 FBMEM allocation when it exists.
@@ -6828,7 +6867,9 @@ static int gsp_phys_rmcall_alloc_channel(void __iomem *bar0)
boot_stage.rmcall_gr_promote ==
GSP_PHYS_RMCALL_GR_PROMOTE_KMD_FB ||
boot_stage.rmcall_gr_promote ==
- GSP_PHYS_RMCALL_GR_PROMOTE_KMD_PM)) {
+ GSP_PHYS_RMCALL_GR_PROMOTE_KMD_PM ||
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE)) {
vars = &gsp_phys_rmcall_channel_variant_skipctx;
attempts = 1;
}
@@ -7668,7 +7709,8 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
mode == GSP_PHYS_RMCALL_GR_PROMOTE_OLDIFACE_FB ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_FB ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_PM) &&
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_KMD_PM ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE) &&
boot_stage.rmcall_channel_variant !=
gsp_phys_rmcall_channel_variant_skipctx.id) {
pr_err("vgsp-boot: rm-call: mode %u requires the SKIP_CTXBUFFER_ALLOC channel (V%u %s); winning variant is V%u; no PROMOTE_CTX is sent and the ladder aborts with no retry\n",
@@ -7973,7 +8015,8 @@ static int gsp_phys_rmcall_gr_ctx_promote(void __iomem *bar0)
boot_stage.rmcall_gr_promote_step = 2;
} else if (mode == GSP_PHYS_RMCALL_GR_PROMOTE_SINGLE ||
mode == GSP_PHYS_RMCALL_GR_PROMOTE_SINGLE_RAW ||
- mode == GSP_PHYS_RMCALL_GR_PROMOTE_SKIPCTX_SINGLE) {
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_SKIPCTX_SINGLE ||
+ mode == GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE) {
/*
* Modes 1, 3 and 8: one MAIN entry carrying both the PA
* (bInitialize=1) and the external-VAS VA (bNonmapped=0);
@@ -8327,6 +8370,44 @@ static void gsp_phys_rmcall_gr_ctx_info(void __iomem *bar0)
* sysmem so the ladder's GP_PUT write reaches the hardware USERD (no BAR1
* aperture exists here for an FBMEM page).
*/
+/*
+ * Mode-18 context share: allocate a FERMI_CONTEXT_SHARE_A (0x9067) under the
+ * TSG with our FERMI_VASPACE_A and SUBCONTEXT_SYNC (VEID 0). The server's
+ * construct path runs kctxshareInit_PHYSICAL, which allocates the per-veid
+ * GraphicsSubcontext that grctxGetSubctxHeaderVa / _grctxAllocSubctxHeader
+ * need (the leading candidate for the V6 KMD promote's 0x40). The channel
+ * then attaches to this share through hContextShare instead of the legacy
+ * share. A failure aborts the ladder with no retry.
+ */
+static int gsp_phys_rmcall_alloc_ctxshare(void __iomem *bar0)
+{
+ struct gsp_phys_rmcall_ctxshare_params cs;
+ u32 status = 0;
+ int ret;
+
+ if (boot_stage.rmcall_ctxshare)
+ return 0;
+ memset(&cs, 0, sizeof(cs));
+ cs.h_va_space = cpu_to_le32(boot_stage.rmcall_vas);
+ cs.flags = cpu_to_le32(0); /* SUBCONTEXT_SYNC -> VEID 0 */
+ cs.subctx_id = cpu_to_le32(0xffffffffu);
+ ret = gsp_phys_rmcall_alloc(bar0, boot_stage.rmcall_client,
+ boot_stage.rmcall_tsg,
+ GSP_PHYS_RMCALL_HANDLE_CTXSHARE,
+ GSP_PHYS_RMCALL_CLASS_CTXSHARE,
+ &cs, sizeof(cs), false, NULL,
+ "FERMI_CONTEXT_SHARE_A", true,
+ NULL, &status);
+ pr_info("vgsp-boot: rm-call: FERMI_CONTEXT_SHARE_A alloc: hClass=0x%x status=0x%x subctxId=0x%x (hParent=hTsg=0x%x hVASpace=0x%x flags=SYNC)%s\n",
+ GSP_PHYS_RMCALL_CLASS_CTXSHARE, status,
+ le32_to_cpu(cs.subctx_id), boot_stage.rmcall_tsg,
+ boot_stage.rmcall_vas, ret ? " (rejected)" : "");
+ if (ret)
+ return ret;
+ boot_stage.rmcall_ctxshare = GSP_PHYS_RMCALL_HANDLE_CTXSHARE;
+ return 0;
+}
+
static int gsp_phys_rmcall_stage3(void __iomem *bar0)
{
struct gsp_phys_rmcall_vas_params vas;
@@ -8438,6 +8519,23 @@ static int gsp_phys_rmcall_stage3(void __iomem *bar0)
boot_stage.rmcall_tsg = GSP_PHYS_RMCALL_HANDLE_TSG;
/*
+ * Mode 18: allocate the client context share (and with it the
+ * GraphicsSubcontext) after the TSG and before the channel, so the
+ * channel attaches to it via hContextShare instead of the legacy
+ * share.
+ */
+ if (gsp_phys_rmcall_engine_is_gr() &&
+ boot_stage.rmcall_gr_promote ==
+ GSP_PHYS_RMCALL_GR_PROMOTE_CTXSHARE) {
+ ret = gsp_phys_rmcall_alloc_ctxshare(bar0);
+ if (ret) {
+ pr_err("vgsp-boot: rm-call: stage 3 aborted: FERMI_CONTEXT_SHARE_A alloc failed (%d); the channel has no client context share and the GR context cannot be promoted (no retry)\n",
+ ret);
+ return ret;
+ }
+ }
+
+ /*
* Allocate the channel's error-context notifier page in FBMEM before
* the channel alloc so every variant carries the memdesc. A failure is
* logged and tolerated: the channel then keeps the zeroed (server
diff --git a/kernel/gsp_phys_gpu.c b/kernel/gsp_phys_gpu.c
index d8eed89..c352056 100644
--- a/kernel/gsp_phys_gpu.c
+++ b/kernel/gsp_phys_gpu.c
@@ -424,8 +424,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 > 17) {
- pr_warn("vgsp: gsp_phys_rmcall_gr_promote=%d is outside 0..17; clamping to 0 (no PROMOTE_CTX)\n",
+ gsp_phys_rmcall_gr_promote_param > 18) {
+ pr_warn("vgsp: gsp_phys_rmcall_gr_promote=%d is outside 0..18; clamping to 0 (no PROMOTE_CTX)\n",
gsp_phys_rmcall_gr_promote_param);
gsp_phys_rmcall_gr_promote_param = 0;
}
@@ -444,7 +444,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); values outside 0..17 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); values outside 0..18 clamp to 0 with a warning");
int gsp_phys_rmcall_gr_promote_value(void)
{