diff options
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index dc27a5d..b4c2872 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -2967,6 +2967,13 @@ MODULE_PARM_DESC(gsp_rm_binapi07_fwd, "Forward only the guest GL core's BINAPI 0x20810107 query to the live GSP session (default 0; diagnostic/experiment)"); /* + * The live session's BINAPI object (class 0x2081) created on demand by the + * 0x20810107 experiment; 0 until the first query allocates it. One device per + * module load, so a file-static is enough; reset by unload. + */ +static u32 gsp_rm_binapi07_be_object; + +/* * Bounded logging for the P3 forward counters: the first four fallbacks (so a * session that cannot forward is visible) and every 64th event. Never called * when the parameter is off. @@ -3034,12 +3041,14 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx, * driver's feature flag clear and the EGL surface init tears * down (EGL_BAD_ALLOC at eglMakeCurrent). The guest-side * handles (hClient 0xc1d..., a 0xbeef object) have no backend - * counterpart, so translate to the live session's internal - * subdevice: the GSP-side handler is expected to key off the - * client session, not the caller's handle. The reply is - * logged either way; an error falls back to the emulated - * generic success until the semantics are known. Gated by its - * own parameter so the P3 whitelist can stay off. + * counterpart: allocate a real BINAPI object (class 0x2081) on + * the live session once, then send the query to it. The first + * attempt (subdevice translation) came back NV_ERR_NOT_SUPPORTED + * (0x56) - the server dispatches the method by the OBJECT's + * class, so a subdevice cannot answer a BINAPI method. The + * reply is logged either way; an error falls back to the + * emulated generic success until the semantics are known. + * Gated by its own parameter so the P3 whitelist can stay off. */ if (!gsp_rm_binapi07_fwd_param) return false; @@ -3063,6 +3072,41 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx, if (gsp_phys_backend_static_get(&snap)) goto fallback; + if (guest_handles && !gsp_rm_binapi07_be_object) { + /* + * Allocate the backend's BINAPI object: rpc_gsp_rm_alloc_v03_00 + * { hClient, hParent, hObject=0, hClass, status, paramsSize=0, + * flags, reserved[4] }. The guest's own alloc used the DEVICE + * as parent (hParent=0xbeef0004), so mirror that. The reply + * carries status at +16 and the chosen handle at +32. + */ + u8 *areq; + void *arsp = NULL; + u32 arsp_len = 0, ast = 0xffffffff, ah = 0; + u32 acls = 0x2081; + + areq = kzalloc(32, GFP_KERNEL); + if (!areq) + goto fallback; + memcpy(areq + 0, &snap.h_internal_client, 4); + memcpy(areq + 4, &snap.h_internal_device, 4); + memcpy(areq + 12, &acls, 4); + ret = gsp_phys_backend_rpc(GSPRM_RPC_FUNC_GSP_RM_ALLOC, areq, + 32, &arsp, &arsp_len, 500); + kfree(areq); + if (!ret && arsp && arsp_len >= 36) { + memcpy(&ast, (u8 *)arsp + 16, 4); + memcpy(&ah, (u8 *)arsp + 32, 4); + } + kfree(arsp); + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: BINAPI-EXPERIMENT backend alloc class=0x2081 (ret=%d): status=0x%x hObject=0x%x", + ret, ast, ah); + if (ret || ast != 0 || !ah) + goto fallback; + gsp_rm_binapi07_be_object = ah; + } + /* Translate the guest's emulated internal handles; any other handle * domain stays emulated. */ if (!guest_handles && @@ -3076,7 +3120,7 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx, goto fallback; memset(&fwd_hdr, 0, sizeof(fwd_hdr)); fwd_hdr.hClient = snap.h_internal_client; - fwd_hdr.hObject = guest_handles ? snap.h_internal_subdevice : + fwd_hdr.hObject = guest_handles ? gsp_rm_binapi07_be_object : (req->hObject == TU104_H_INTERNAL_DEVICE ? snap.h_internal_device : snap.h_internal_subdevice); fwd_hdr.cmd = req->cmd; |
