diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-22 16:55:19 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-22 16:55:19 -0400 |
| commit | b366b162a4442f694639d7622a0e00f0cfc6fee8 (patch) | |
| tree | 5c10d6f963467fd0c6e4c8596a5f95599f5596ff /kernel/gsp_rm_emulation.c | |
| parent | 3855bb22d0400507def51881ebb688428963b7f9 (diff) | |
| download | open-iov-b366b162a4442f694639d7622a0e00f0cfc6fee8.tar.gz open-iov-b366b162a4442f694639d7622a0e00f0cfc6fee8.zip | |
r493 THE 3D-ENGINE WALL: serve the live GSP's own KGR static data to the guest
The X driver's nvSelect3DClass -> nv3dAllocDevice maps GR_GET_INFO index
SM_VERSION (0x0c) through an SM-version -> SPA-version table; the emulated
KGR_GET_INFO fill never set index 0x0c, so SM_VERSION read back as
SM_VERSION_NONE (0) and every Xorg/EGL session died at 'Failed to select a
3D engine' (the class list and the engine list were never the problem: the
X log carries neither 'Failed to determine graphics capabilities' nor
'Failed to determine engines list').
The physical backend already asks the LIVE GSP the real client's whole KGR
query set at mode-35 boot (gsp_phys_rmcall_user_lane_kgr_queries) and threw
the replies away. Retain them (generation-keyed, invalidated with the
backend static cache) and serve the identical bytes in the guest-side
GSP_RM_CONTROL dispatch for the same commands, so the guest's GL/3D stack
reads the device's true GR static values (SM_VERSION 0x75, warps, caps,
topology, ctx-buffer tables) instead of fabricated approximations. Falls
through to the emulated handlers unchanged when no capture exists (backend
not READY, other boot mode, cmd not captured) and never answers with more
bytes than the guest requested.
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 5e3820f..be12c05 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -3107,6 +3107,42 @@ static int gsp_rm_send_rm_control(struct gsp_emu_context *ctx, u32 sequence, return 0; } +/* + * Real-GSP KGR static-data snapshots (mode-35 boot capture; see + * gsp_phys_kgr_snap_get in gsp_phys_booter.c). The physical backend asks the + * live GSP the real client's KGR query set at boot and retains the replies; + * serve the identical bytes for the same commands so the guest's GL/3D stack + * reads the device's true GR static values. Concrete consumer: the X + * driver's 3D-engine selection maps GR_GET_INFO index SM_VERSION (0x0c) + * through a table and fails with "Failed to select a 3D engine" when it + * reads back as SM_VERSION_NONE (0); the live GSP's KGR_GET_INFO reply + * carries the real value (0x75 on TU104). Returns true when the reply was + * served from the snapshot (out_params_size set); false falls through to the + * emulated handler unchanged. + */ +static bool gsp_rm_kgr_snap_serve(struct gsp_emu_context *ctx, u32 cmd, + u32 req_params_size, + u8 *out_params, u32 out_len, + u32 *out_params_size) +{ + u32 n = 0; + int ret; + + ret = gsp_phys_kgr_snap_get(cmd, out_params, out_len, &n); + if (ret || !n) + return false; + + /* Never answer with more bytes than the guest asked for. */ + if (n > req_params_size) + return false; + + *out_params_size = n; + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: KGR cmd=0x%x served from the real-GSP snapshot (%u bytes)", + cmd, n); + return true; +} + static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, const u8 *elem, u32 sequence) { @@ -3148,6 +3184,19 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, return; } + /* + * KGR static-data snapshots (mode-35 boot capture): the live GSP's own + * replies to the real client's KGR query set are served byte-identically + * for the same commands, so the guest's GL/3D stack sees the device's + * true GR static values. Falls through to the emulated switch when no + * snapshot exists (backend not READY, other boot mode, cmd not captured). + */ + if (gsp_rm_kgr_snap_serve(ctx, req.cmd, req.paramsSize, + reply + GSP_RM_CTRL_HDR_SIZE, + reply_data_len - GSP_RM_CTRL_HDR_SIZE, + &out_params_size)) + goto rm_control_reply; + switch (req.cmd) { case TU104_CTRL_FIFO_GET_DEVICE_INFO_TABLE: gsp_rm_handle_fifo_device_table(ctx, sequence, &req, @@ -3488,6 +3537,7 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, * correct. */ +rm_control_reply: /* Build the reply header */ memcpy(reply + 0, &req.hClient, 4); memcpy(reply + 4, &req.hObject, 4); |
