diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 03:30:27 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-23 03:30:27 -0400 |
| commit | cba06da506d8e7a3f92d90f55d247ce870e76ee3 (patch) | |
| tree | c7186702178b767e212be451d783ef141a7b64fd /kernel | |
| parent | a1d27eef42b8232e309eca7ecad5141026ee07db (diff) | |
| download | open-iov-cba06da506d8e7a3f92d90f55d247ce870e76ee3.tar.gz open-iov-cba06da506d8e7a3f92d90f55d247ce870e76ee3.zip | |
r524 the BINAPI-07 oracle client: build the captured real-client sequence on the live session (root -> device 0xcaf00000 -> subdevice 0xcaf00004 -> class-0x2081 child 0xcaf00099) and send the query as that client, so the server dispatches from a genuine BINAPI object
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 166 |
1 files changed, 122 insertions, 44 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 2054086..37f7054 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -2967,13 +2967,126 @@ 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. + * The live session's oracle client/object for the 0x20810107 experiment, + * created on demand; 0 until the first query builds it. One device per module + * load, so file-statics are enough; reset by unload. */ +static u32 gsp_rm_binapi07_be_client; static u32 gsp_rm_binapi07_be_object; /* + * One GSP_RM_ALLOC (fn 103) against the live backend, built exactly like the + * rm-call ladder's helper (rpc_gsp_rm_alloc_v03_00: hClient, hParent, + * hObject, hClass, status, paramsSize, flags, reserved[4] + params). + * object_is_out selects the reply read: a ROOT alloc returns the + * server-chosen client handle in params[0] (payload +32), anything else + * echoes the client-chosen hObject at +8; status is at +16 in both cases. + */ +static int gsp_rm_binapi07_backend_alloc(u32 h_client, u32 h_parent, + u32 h_object, u32 h_class, + const void *params, u32 params_len, + bool object_is_out, + u32 *out_object, u32 *out_status) +{ + u8 *areq; + void *arsp = NULL; + u32 arsp_len = 0, st = 0xffffffff, ho = 0; + int ret; + + areq = kzalloc(32 + params_len, GFP_KERNEL); + if (!areq) + return -ENOMEM; + memcpy(areq + 0, &h_client, 4); + memcpy(areq + 4, &h_parent, 4); + memcpy(areq + 8, &h_object, 4); + memcpy(areq + 12, &h_class, 4); + memcpy(areq + 20, ¶ms_len, 4); + if (params_len) + memcpy(areq + 32, params, params_len); + + ret = gsp_phys_backend_rpc(GSPRM_RPC_FUNC_GSP_RM_ALLOC, areq, + 32 + params_len, &arsp, &arsp_len, 500); + kfree(areq); + if (!ret && arsp) { + if (arsp_len >= 20) + memcpy(&st, (u8 *)arsp + 16, 4); + if (object_is_out) { + if (arsp_len >= 36) + memcpy(&ho, (u8 *)arsp + 32, 4); + } else if (arsp_len >= 12) { + memcpy(&ho, (u8 *)arsp + 8, 4); + } + } + kfree(arsp); + if (out_object) + *out_object = ho; + if (out_status) + *out_status = st; + return ret; +} + +/* + * Build the oracle client on the live session: the captured real-client + * sequence for a class-0x2081 consumer (root -> device 0xcaf00000 -> + * subdevice 0xcaf00004 -> class-0x2081 child). The subdevice attempt alone + * had answered NV_ERR_NOT_SUPPORTED (0x56) because the server dispatches the + * method from the OBJECT's class, so a real class-0x2081 object is needed. + * Returns 0 with *out_client/*out_object set on success. + */ +static int gsp_rm_binapi07_backend_setup(struct gsp_emu_context *ctx, + u32 *out_client, u32 *out_object) +{ + u8 p120[120], p56[56], p4[4]; + u32 st = 0xffffffff, cli = 0, dev = 0xcaf00000u; + u32 sub = 0xcaf00004u, bin = 0xcaf00099u; + int ret; + + /* 1. Root: hClient=0, the server picks and returns the handle. */ + memset(p120, 0, sizeof(p120)); + ret = gsp_rm_binapi07_backend_alloc(0, 0, 0, 0x0, p120, 120, true, + &cli, &st); + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: BINAPI-EXPERIMENT oracle root alloc: ret=%d status=0x%x hClient=0x%x", + ret, st, cli); + if (ret || st != 0 || !cli) + return -EIO; + + /* 2. Device (class 0x80): deviceId 0, hClientShare = hClient. */ + memset(p56, 0, sizeof(p56)); + memcpy(p56 + 4, &cli, 4); + ret = gsp_rm_binapi07_backend_alloc(cli, cli, dev, 0x80, p56, 56, + false, &dev, &st); + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: BINAPI-EXPERIMENT oracle device alloc: ret=%d status=0x%x hDevice=0x%x", + ret, st, dev); + if (ret || st != 0 || !dev) + return -EIO; + + /* 3. Subdevice (class 0x2080): subDeviceId 0. */ + memset(p4, 0, sizeof(p4)); + ret = gsp_rm_binapi07_backend_alloc(cli, dev, sub, 0x2080, p4, 4, + false, &sub, &st); + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: BINAPI-EXPERIMENT oracle subdevice alloc: ret=%d status=0x%x hSubdevice=0x%x", + ret, st, sub); + if (ret || st != 0 || !sub) + return -EIO; + + /* 4. BINAPI (class 0x2081) under the subdevice, 4 zero params. */ + ret = gsp_rm_binapi07_backend_alloc(cli, sub, bin, 0x2081, p4, 4, + false, &bin, &st); + nv_vgpu_info(ctx->vgpu, + "vgsp-rm: BINAPI-EXPERIMENT oracle BINAPI alloc: ret=%d status=0x%x hObject=0x%x", + ret, st, bin); + if (ret || st != 0 || !bin) + return -EIO; + + *out_client = cli; + *out_object = bin; + return 0; +} + +/* * 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. @@ -3073,48 +3186,12 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx, 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 - * SUBDEVICE as parent (hParent=0xbeef0004 where 0xbeef0004 is - * the class-0x2080 child 0xbeef0003; the first attempt with the - * device parent came back NV_ERR_INVALID_OBJECT_PARENT, 0x36), - * 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; + u32 cli = 0, obj = 0; - areq = kzalloc(32, GFP_KERNEL); - if (!areq) - goto fallback; - memcpy(areq + 0, &snap.h_internal_client, 4); - memcpy(areq + 4, &snap.h_internal_subdevice, 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 >= 32) { - /* - * An alloc with paramsSize=0 echoes the 32-byte - * rpc_gsp_rm_alloc_v03_00: hObject (the chosen - * handle) at +8, status at +16. (The rm-call ladder - * reads +32 for ROOT allocs, whose params carry the - * handle; with no params the reply is 32 B.) - */ - memcpy(&ast, (u8 *)arsp + 16, 4); - memcpy(&ah, (u8 *)arsp + 8, 4); - } - kfree(arsp); - nv_vgpu_info(ctx->vgpu, - "vgsp-rm: BINAPI-EXPERIMENT backend alloc class=0x2081 (ret=%d len=%u): status=0x%x hObject=0x%x", - ret, arsp_len, ast, ah); - if (ret || ast != 0 || !ah) + if (gsp_rm_binapi07_backend_setup(ctx, &cli, &obj)) goto fallback; - gsp_rm_binapi07_be_object = ah; + gsp_rm_binapi07_be_client = cli; + gsp_rm_binapi07_be_object = obj; } /* Translate the guest's emulated internal handles; any other handle @@ -3129,7 +3206,8 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx, if (!fwd_req) goto fallback; memset(&fwd_hdr, 0, sizeof(fwd_hdr)); - fwd_hdr.hClient = snap.h_internal_client; + fwd_hdr.hClient = guest_handles ? gsp_rm_binapi07_be_client : + snap.h_internal_client; fwd_hdr.hObject = guest_handles ? gsp_rm_binapi07_be_object : (req->hObject == TU104_H_INTERNAL_DEVICE ? snap.h_internal_device : snap.h_internal_subdevice); |
