diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-22 15:47:32 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-22 15:47:32 -0400 |
| commit | 737aabc28bb4340e80cf801abf85cfc9e6443644 (patch) | |
| tree | b79567240a0c4992f8954a88770fb1d6588d50e1 /kernel/gsp_rm_emulation.c | |
| parent | a42fdb2cbe6a9b294a160860f38485ba1eb93c34 (diff) | |
| download | open-iov-737aabc28bb4340e80cf801abf85cfc9e6443644.tar.gz open-iov-737aabc28bb4340e80cf801abf85cfc9e6443644.zip | |
r487 THE GL/VULKAN VASPACE WALL: clamp RM_CONTROL replies to the 64 KB wire record bound (16 x 4096; guest GspMsgQueueReceiveStatus rejects hdr + rpc.length beyond it - 'Incorrect message length 67448', rpcRecvPoll 0x3a, NV_ERR_INVALID_PARAMETER). The stock driver sends PERF_VPSTATES_INFO (0x2080a0a4, paramsSize 67392) during Xorg VASpace construction; the generic reply echoed the whole buffer as a 17-element record the guest refused, vmmCreateVaspace returned ffff and GL died with 'Failed to allocate VASpace object' / EGL_BAD_ALLOC on every prior session. A real GSP-RM cannot reply past the bound either; the echo is clamped with the tail zeroed
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index cd9cbf2..10633ab 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -3409,6 +3409,34 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, break; } + /* + * r487 THE GL/VULKAN VASPACE WALL (Xorg/EGL/GZDOOM, every session to + * date): the wire RPC record is bounded at 16 x 4096 bytes + * (GSP_MSG_QUEUE_ELEMENT_SIZE_MIN * 16 = 65536; the guest's + * GspMsgQueueReceiveStatus rejects any record whose + * hdr + rpc.length exceeds it - observed "Incorrect message length + * 67448", rpcRecvPoll status 0x3a, NV_ERR_INVALID_PARAMETER at + * rpc.c:9998). The stock driver sends large in/out controls + * (NV2080_CTRL_CMD_PERF_VPSTATES_INFO 0x2080a0a4 paramsSize=67392 + * during Xorg VASpace construction) and the generic reply echoed the + * whole params buffer - a 17-element record the guest refused, so + * the control failed, vmmCreateVaspace returned ffff and GL died + * with "Failed to allocate VASpace object" / EGL_BAD_ALLOC. A real + * GSP-RM cannot reply past the wire bound either; clamp the echoed + * params to the largest record the queue carries + * (65536 - guest elem hdr 8 - rpc hdr 32 - ctrl hdr 24), the tail + * staying zero exactly like the small-control generic reply. + */ +#define GSPRM_WIRE_REPLY_PARAMS_MAX \ + (GSPRM_QUEUE_ELEMENT_SIZE * 16 - 8 - 32 - GSP_RM_CTRL_HDR_SIZE) + if (out_params_size > GSPRM_WIRE_REPLY_PARAMS_MAX) { + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: RM_CONTROL cmd=0x%x out=%u clamped to %u (wire record limit; guest would reject the record)", + req.cmd, out_params_size, + (u32)GSPRM_WIRE_REPLY_PARAMS_MAX); + out_params_size = GSPRM_WIRE_REPLY_PARAMS_MAX; + } + /* Build the reply header */ memcpy(reply + 0, &req.hClient, 4); memcpy(reply + 4, &req.hObject, 4); |
