summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 03:21:10 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 03:21:10 -0400
commitd940dd1dee888c21799fa1e103de2477f337fc54 (patch)
tree2d8146af2cf2bcea7f1601660ba24f89017e0c97
parent25afdc64fc799ba2729d617ac02195d386d10710 (diff)
downloadopen-iov-d940dd1dee888c21799fa1e103de2477f337fc54.tar.gz
open-iov-d940dd1dee888c21799fa1e103de2477f337fc54.zip
r521 the BINAPI-07 oracle step 2: allocate a real class-0x2081 object on the live session (GSP_RM_ALLOC as the internal client/device parent) and send the query to it - the subdevice attempt answered NV_ERR_NOT_SUPPORTED because the server dispatches by the object's class
-rw-r--r--kernel/gsp_rm_emulation.c58
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;