diff options
Diffstat (limited to 'kernel')
| -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); |
