summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-21 20:08:39 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-21 20:08:39 -0400
commit1e73a2e00c76e25e4ce2980e5d04a533b0c6158d (patch)
treeaebdceb64f185719fe03a273c6fce334db305a29
parent0630028527ae401e15a99cf1145829e9725a13ad (diff)
downloadopen-iov-1e73a2e00c76e25e4ce2980e5d04a533b0c6158d.tar.gz
open-iov-1e73a2e00c76e25e4ce2980e5d04a533b0c6158d.zip
kernel: Booter-Unload success + SM order table (unload/reload cycle works)
- gsp_emu_poll_boot generic SEC2 kick path: clear SEC2_MAILBOX0=0 (success) - Booter Unload during GPU shutdown read a stale 0xff, failing the unload and killing the subsequent re-init ('Booter failed with non-zero error code: 0xff' -> RmInitAdapter 0x40). A SEC2 kick after a completed boot is a GSP shutdown/reload: clear boot state. Driver unload/reload cycle (last close -> RmShutdown, next open -> RmInitAdapter) now works. - STATIC_KGR_GET_GLOBAL_SM_ORDER(0x20800a22): TU104 topology 6 GPC x 4 TPC x 2 SM = 48 SMs/24 TPCs on GR0. kgrStaticInit is init-critical (NV_CHECK_OK_OR_GOTO); zeros left numSm=0 and NVML spun on empty topology.
-rw-r--r--kernel/gsp_emulation.c14
-rw-r--r--kernel/gsp_rm_emulation.c54
-rw-r--r--kernel/gsp_rm_tu104.h27
3 files changed, 93 insertions, 2 deletions
diff --git a/kernel/gsp_emulation.c b/kernel/gsp_emulation.c
index 5522bf3..bca8a52 100644
--- a/kernel/gsp_emulation.c
+++ b/kernel/gsp_emulation.c
@@ -234,13 +234,23 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx)
return;
}
- /* Any other STARTCPU kick (resume/unload/etc.): just complete it */
+ /* Any other STARTCPU kick (resume/unload/etc.): complete it.
+ * SEC2 kicks report their ucode result in SEC2_MAILBOX0 (0=success) -
+ * e.g. Booter Unload during GPU shutdown. Without clearing it the
+ * driver reads a stale/garbage error code (0xff) and the unload
+ * fails, killing the subsequent re-init. A SEC2 kick after a
+ * completed boot is a GSP shutdown/reload: drop the boot state
+ * (GSP no longer active, queue dead). */
if (gsp_cpuctl & GSP_EMU_CPUCTL_STARTCPU)
gsp_emu_shadow_write32(ctx, GSP_EMU_REG_GSP_CPUCTL,
GSP_EMU_CPUCTL_HALTED);
- if (sec2_cpuctl & GSP_EMU_CPUCTL_STARTCPU)
+ if (sec2_cpuctl & GSP_EMU_CPUCTL_STARTCPU) {
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_SEC2_MAILBOX0, 0);
gsp_emu_shadow_write32(ctx, GSP_EMU_REG_SEC2_CPUCTL,
GSP_EMU_CPUCTL_HALTED);
+ if (ctx->boot_stage == GSP_BOOT_STAGE_BOOTER_DONE)
+ gsp_emu_clear_boot_state(ctx, "Booter unload/reload kick");
+ }
}
/* ============================================================
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 665f073..8f8f9c2 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -1009,6 +1009,54 @@ static void gsp_rm_handle_ce_get_fault_method_buffer_size(
nv_vgpu_info(ctx->vgpu, "GSPRM: CE_GET_FAULT_METHOD_BUFFER_SIZE -> %u", val32);
}
+/*
+ * STATIC_KGR_GET_GLOBAL_SM_ORDER (0x20800a22)
+ *
+ * kgrStaticInit copies globalSmOrder[grIdx] into the GR engine's static
+ * info - init-critical (NV_CHECK_OK_OR_GOTO, cannot fail). Zeros leave
+ * numSm=0 and the driver/nvidia-smi spin on empty topology. Report the
+ * TU104 layout: 6 GPCs x 4 TPCs x 2 SMs = 48 SMs on GR0, engines 1-7 empty.
+ * params: globalSmOrder[8] x (globalSmId[240]x12B + numSm(2) + numTpc(2)).
+ */
+static void gsp_rm_handle_kgr_get_global_sm_order(struct gsp_emu_context *ctx,
+ u32 sequence,
+ u32 *out_status,
+ u8 *out_params,
+ u32 *out_params_size)
+{
+ struct tu104_gr_global_sm_order *order =
+ (struct tu104_gr_global_sm_order *)out_params; /* engine 0 */
+ u32 idx = 0;
+ u32 gpc, tpc, sm;
+
+ memset(out_params, 0, TU104_GR_MAX_ENGINES *
+ sizeof(struct tu104_gr_global_sm_order));
+
+ for (gpc = 0; gpc < TU104_NUM_GPC; gpc++) {
+ for (tpc = 0; tpc < TU104_TPC_PER_GPC; tpc++) {
+ for (sm = 0; sm < TU104_SM_PER_TPC; sm++) {
+ struct tu104_gr_sm_id *e = &order->globalSmId[idx++];
+
+ e->gpcId = gpc;
+ e->localTpcId = tpc;
+ e->localSmId = sm;
+ e->globalTpcId = gpc * TU104_TPC_PER_GPC + tpc;
+ e->virtualGpcId = gpc;
+ e->migratableTpcId = e->globalTpcId;
+ }
+ }
+ }
+ order->numSm = TU104_NUM_SM;
+ order->numTpc = TU104_NUM_TPC;
+
+ *out_params_size = TU104_GR_MAX_ENGINES *
+ sizeof(struct tu104_gr_global_sm_order);
+ *out_status = 0;
+
+ nv_vgpu_info(ctx->vgpu, "GSPRM: KGR_GET_GLOBAL_SM_ORDER -> %u SMs, %u TPCs on GR0",
+ TU104_NUM_SM, TU104_NUM_TPC);
+}
+
static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
const u8 *elem, u32 sequence)
{
@@ -1097,6 +1145,12 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size);
break;
+ case TU104_CTRL_STATIC_KGR_GET_GLOBAL_SM_ORDER:
+ gsp_rm_handle_kgr_get_global_sm_order(ctx, sequence,
+ &out_status,
+ reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size);
+ break;
+
default:
/* Unknown control command - return success with zeroed params.
* Do NOT echo the request: pure queries pass uninitialized
diff --git a/kernel/gsp_rm_tu104.h b/kernel/gsp_rm_tu104.h
index c6dfb56..5a5fecd 100644
--- a/kernel/gsp_rm_tu104.h
+++ b/kernel/gsp_rm_tu104.h
@@ -700,6 +700,33 @@ static const struct tu104_internal_device_info tu104_internal_device_table[] = {
#define TU104_CTRL_INTERNAL_DISPLAY_GET_IP_VERSION 0x20800a4b
#define TU104_CTRL_I2C_TRANSACTION 0x402c0105
#define TU104_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE 0x20802a08
+#define TU104_CTRL_STATIC_KGR_GET_GLOBAL_SM_ORDER 0x20800a22
+
+/* TU104 SM topology: 6 GPCs x 4 TPCs x 2 SMs = 48 SMs, 24 TPCs (RTX 2080 SUPER) */
+#define TU104_NUM_GPC 6
+#define TU104_TPC_PER_GPC 4
+#define TU104_SM_PER_TPC 2
+#define TU104_NUM_SM (TU104_NUM_GPC * TU104_TPC_PER_GPC * TU104_SM_PER_TPC)
+#define TU104_NUM_TPC (TU104_NUM_GPC * TU104_TPC_PER_GPC)
+
+/* NV2080_CTRL_INTERNAL_STATIC_GR_GLOBAL_SM_ORDER (ctrl2080internal.h) */
+#define TU104_GR_MAX_SM 240
+#define TU104_GR_MAX_ENGINES 8
+
+struct tu104_gr_sm_id {
+ u16 gpcId;
+ u16 localTpcId;
+ u16 localSmId;
+ u16 globalTpcId;
+ u16 virtualGpcId;
+ u16 migratableTpcId;
+};
+
+struct tu104_gr_global_sm_order {
+ struct tu104_gr_sm_id globalSmId[TU104_GR_MAX_SM];
+ u16 numSm;
+ u16 numTpc;
+};
/* CE fault method buffer size (ceGetFaultMethodBufferSize_GV100 formula,
* Turing inherits: 135 * (13*totalCes + 2), page-aligned; TU104 has 5 PCEs) */