summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_emulation.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-22 02:16:18 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-22 02:16:18 -0400
commit5eac589d9a7af8f8b321b00398575070b9a88513 (patch)
treeb0c6d12d92a145fcf2d6fc32f3ee2b794eed4c43 /kernel/gsp_emulation.c
parent427b9e1e10c3258bb031be142700b18c83296c69 (diff)
downloadopen-iov-5eac589d9a7af8f8b321b00398575070b9a88513.tar.gz
open-iov-5eac589d9a7af8f8b321b00398575070b9a88513.zip
kernel: floorsweeping masks + interrupt tree + WPR2 race + fn-10 handler
- STATIC_KGR_GET_FLOORSWEEPING_MASKS(0x20800a26): TU104 gpcMask=0x3f (6 GPCs), 4 TPC/GPC. numGpcs==0 killed krcWatchdogInit -> RmInitAdapter bailed ('numGpcs > 0' assert at kernel_graphics_object.c:191). - CPU interrupt tree (osVerifyInterrupts): driver accesses VF window at virtualRegPhysOffset=NV_VIRTUAL_FUNCTION_FULL_PHYS_OFFSET(0xB80000)+off, NOT 0x1640 (was watching wrong offset). On LEAF_TRIGGER write, set LEAF/TOP pending bits + inject MSI-X so the sanity-test ISR runs - osVerifySystemEnvironment now passes. - WPR2 race: clear boot state BEFORE CPUCTL=HALTED on Booter-unload kick so WPR2 is down when driver checks kgspIsWpr2Up ('WPR2 is still up'). - Dedicated GSP_RM_FREE(10) handler: echo NVOS00_PARAMETERS + status=NV_OK (proper free_v03_00 form). fn-10 timeout persists despite this - characterized as driver-side reply-matching issue, not content.
Diffstat (limited to 'kernel/gsp_emulation.c')
-rw-r--r--kernel/gsp_emulation.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/kernel/gsp_emulation.c b/kernel/gsp_emulation.c
index c8f8041..94af0d2 100644
--- a/kernel/gsp_emulation.c
+++ b/kernel/gsp_emulation.c
@@ -179,6 +179,39 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx)
u32 sec2_cpuctl = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_SEC2_CPUCTL);
u32 engine = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_GSP_ENGINE);
u32 mmu_inv = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_MMU_INVALIDATE);
+ u32 sw_vector;
+
+ /* Software-interrupt trigger: the driver writes a vector to
+ * CPU_INTR_LEAF_TRIGGER to fire it (the osVerifyInterrupts sanity
+ * test uses the doorbell vector). Set the pending bits in the LEAF
+ * and TOP interrupt-tree registers and inject MSI-X so the guest's
+ * ISR runs - without this the sanity test times out and
+ * osVerifySystemEnvironment fails, bailing RmInitAdapter. */
+ sw_vector = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_CPU_INTR_LEAF_TRIGGER);
+ if (sw_vector) {
+ u32 leaf_idx = sw_vector / 32;
+ u32 leaf_bit = sw_vector % 32;
+ u32 subtree = sw_vector / 64;
+ u32 top_idx = subtree / 32;
+ u32 top_bit = subtree % 32;
+ u32 leaf_val = gsp_emu_shadow_read32(ctx,
+ GSP_EMU_REG_CPU_INTR_LEAF_BASE + leaf_idx * 4);
+ u32 top_val = gsp_emu_shadow_read32(ctx,
+ GSP_EMU_REG_CPU_INTR_TOP_BASE + top_idx * 4);
+
+ gsp_emu_shadow_write32(ctx,
+ GSP_EMU_REG_CPU_INTR_LEAF_BASE + leaf_idx * 4,
+ leaf_val | (1U << leaf_bit));
+ gsp_emu_shadow_write32(ctx,
+ GSP_EMU_REG_CPU_INTR_TOP_BASE + top_idx * 4,
+ top_val | (1U << top_bit));
+ gsp_emu_shadow_write32(ctx, GSP_EMU_REG_CPU_INTR_LEAF_TRIGGER, 0);
+
+ nv_vgpu_info(ctx->vgpu, "GSP-BOOT: SW interrupt vector %u -> LEAF[%u]|=0x%x TOP[%u]|=0x%x, MSI-X",
+ sw_vector, leaf_idx, 1U << leaf_bit, top_idx,
+ 1U << top_bit);
+ gsp_emu_inject_completion_interrupt(ctx, 0);
+ }
/* TLB invalidate auto-complete: the driver sets TRIGGER then spins
* polling for it to clear (kgmmuCheckPendingInvalidates). Report
@@ -267,16 +300,18 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx)
* 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). */
+ * (GSP no longer active, queue dead). Clear boot state FIRST so
+ * WPR2 is already down when the driver sees CPUCTL=HALTED and
+ * checks kgspIsWpr2Up (avoids "Booter Unload: WPR2 is still up"). */
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 (ctx->boot_stage == GSP_BOOT_STAGE_BOOTER_DONE)
+ gsp_emu_clear_boot_state(ctx, "Booter unload/reload kick");
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");
}
}