diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-21 19:04:05 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-21 19:04:05 -0400 |
| commit | 6b686f70d8ff3e6340e8307c95847cd1eed4f2ae (patch) | |
| tree | 71cf22aff298900e4073427534eab4ce93a6ef84 /kernel/gsp_rm_emulation.c | |
| parent | 256c5308423befddc20bdf7e59a663f3f1b683ae (diff) | |
| download | open-iov-6b686f70d8ff3e6340e8307c95847cd1eed4f2ae.tar.gz open-iov-6b686f70d8ff3e6340e8307c95847cd1eed4f2ae.zip | |
kernel: Fix FIFO table fortify_panic + GSP boot-state reset on queue death + ISO fbRegion
- gsp_rm_handle_fifo_device_table: read baseIndex from the queue element
buffer (req_data + hdr), not past the local 24-byte header struct -
FORTIFY proved the old memcpy always overflows -> fortify_panic killed
gsp_emu_0 mid RmInitNvDevice (guest timed out on fn 76).
- gsp_emu_clear_boot_state: clear WPR2/RISCV/mailboxes/stage tracker and
reset GSP-RM queue state. Turing guests produce no observable BAR0
writes on unload, so the next probe's _kgspBootGspRm failed with
'unexpected WPR2 already up'. Trigger on ENGINE reset and on detected
queue death (insane writePtr jump / garbage element signature).
- GspStaticConfigInfo fbRegion[0].supportISO=1: memmgrCalcReservedFbSpace
asserts some region supports ISO 'even with no display'; without it
kdispStateInitLocked couldn't allocate clientChannelTable.
- .gitignore: scripts/git-push-vgpu.sh (local per-machine helper)
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index e152e5c..1ed63ab 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -526,7 +526,12 @@ static void gsp_rm_build_static_info(u8 *buf) val64 = 0; memcpy(®ion->reserved, &val64, 8); val32 = 0; memcpy(®ion->performance, &val32, 4); region->supportCompressed = 0; - region->supportISO = 0; + /* memmgrCalcReservedFbSpace asserts that SOME region supports + * ISO "even if we have no display" - without it the reserved + * space split fails and kdisp can't allocate its channel + * table. A single ISO-capable region satisfies fast/slow/iso + * assignment. */ + region->supportISO = 1; region->bProtected = 0; memset(region->blackList, 0, sizeof(region->blackList)); } @@ -670,6 +675,7 @@ struct gsp_rm_control_req { static void gsp_rm_handle_fifo_device_table(struct gsp_emu_context *ctx, u32 sequence, struct gsp_rm_control_req *req, + const u8 *req_params, u32 *out_status, u8 *out_params, u32 *out_params_size) { @@ -678,8 +684,14 @@ static void gsp_rm_handle_fifo_device_table(struct gsp_emu_context *ctx, fifo_params = (struct tu104_fifo_get_device_info_params *)out_params; base = 0; - if (req->paramsSize >= 4) - memcpy(&base, (u8 *)(req + 1), 4); + /* baseIndex is the first field of the request params, which live in + * the queue element buffer (NOT after the local header struct!). Only + * readable when the whole request fits in the first element. */ + if (req->paramsSize >= 4 && + req->paramsSize + GSP_RM_CTRL_HDR_SIZE <= GSPRM_MAX_SINGLE_ELEM_DATA) + memcpy(&base, req_params, 4); + if (base >= TU104_FIFO_TABLE_MAX_DEVICES) + base = 0; /* How many entries to return in this page */ count = TU104_ENGINE_TABLE_SIZE - base; @@ -847,6 +859,7 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, switch (req.cmd) { case TU104_CTRL_FIFO_GET_DEVICE_INFO_TABLE: gsp_rm_handle_fifo_device_table(ctx, sequence, &req, + req_data + GSP_RM_CTRL_HDR_SIZE, &out_status, reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size); break; @@ -975,9 +988,15 @@ static void gsp_rm_poll_commands(struct gsp_emu_context *ctx) if (tx.writePtr < rm->cmd_read || (tx.writePtr - rm->cmd_read) > rm->cmd_msgcount) { - nv_vgpu_warn(ctx->vgpu, "GSPRM: cmd writePtr jumped %u -> %u, resyncing", + /* The writePtr is monotonic for the life of a boot. A backward + * or insane jump means the queue buffer was torn down - the + * guest driver unloaded (or crashed) without an observable + * GSP shutdown. Declare the emulated GSP dead: clear WPR2 / + * RISCV / boot stages so the next probe's WPR2-up check + * passes and it re-boots from scratch. */ + nv_vgpu_warn(ctx->vgpu, "GSPRM: cmd writePtr jumped %u -> %u, GSP boot declared dead", rm->cmd_read, tx.writePtr); - rm->cmd_read = tx.writePtr; + gsp_emu_clear_boot_state(ctx, "stale GSP-RM queue"); return; } @@ -1003,12 +1022,17 @@ static void gsp_rm_poll_commands(struct gsp_emu_context *ctx) if (signature != GSPRM_RPC_SIGNATURE || elem_count == 0 || elem_count > rm->cmd_msgcount) { - nv_vgpu_warn(ctx->vgpu, "GSPRM: bad element idx=%u sig=0x%x elemCount=%u fn=%u, skipping", + /* The driver always writes a valid element BEFORE + * bumping writePtr. An advanced writePtr with garbage + * content means the queue buffer is stale (freed and + * reused by the guest after unload/crash) - declare + * the emulated GSP dead so the next probe re-boots. */ + nv_vgpu_warn(ctx->vgpu, "GSPRM: garbage element idx=%u sig=0x%x elemCount=%u fn=%u, GSP boot declared dead", rm->cmd_read, signature, elem_count, hdr->function); - rm->cmd_read++; kfree(elem); - continue; + gsp_emu_clear_boot_state(ctx, "garbage GSP-RM queue"); + return; } gsp_rm_handle_element(ctx, elem); |
