summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 03:09:46 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-23 03:09:46 -0400
commit91cf282af8a7919972f03224e34feb9bc4df46f2 (patch)
tree4e94ac8321f7bd6279d25981f6c6374462f015f0 /kernel
parent367357927c1c7524a8dbcc97d2747bc72c2b0f68 (diff)
downloadopen-iov-91cf282af8a7919972f03224e34feb9bc4df46f2.tar.gz
open-iov-91cf282af8a7919972f03224e34feb9bc4df46f2.zip
r519 the BINAPI 0x20810107 experiment: forward the guest GL core's reserved-interface query to the live GSP session (internal subdevice translation) and log the server's own status/bytes as evidence; scoped to the observed 2-byte shape, fail-open to the emulated generic reply
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_rm_emulation.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index efd350b..10bfa93 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -3004,6 +3004,8 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx,
u32 out_params_size;
int ret;
+ bool guest_handles = false;
+
/* Wave 1 whitelist: compile-time side-effect-free queries only. */
switch (req->cmd) {
case TU104_CTRL_BUS_GET_PCI_BAR_INFO:
@@ -3011,6 +3013,22 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx,
case TU104_CTRL_FB_GET_INFO_V2:
case TU104_CTRL_INTERNAL_GMMU_GET_STATIC_INFO:
break;
+ case 0x20810107: /* NV2081_BINAPI reserved-interface method 7 */
+ /*
+ * EXPERIMENT (r519): the guest GL core allocates a BINAPI
+ * object (class 0x2081) and sends this 2-byte query during
+ * 3D-surface init; our {0,0} generic reply leaves the
+ * 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.
+ */
+ guest_handles = true;
+ break;
default:
return false;
}
@@ -3021,15 +3039,20 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx,
if (req->paramsSize > GSPRM_MAX_SINGLE_ELEM_DATA - GSP_RM_CTRL_HDR_SIZE)
goto fallback;
+ /* The experiment is scoped to the observed shape: 2-byte in/out. */
+ if (guest_handles && req->paramsSize != 2)
+ goto fallback;
+
/* A valid snapshot implies a READY session and the adopted handles. */
if (gsp_phys_backend_static_get(&snap))
goto fallback;
/* Translate the guest's emulated internal handles; any other handle
* domain stays emulated. */
- if (req->hClient != TU104_H_INTERNAL_CLIENT ||
- (req->hObject != TU104_H_INTERNAL_DEVICE &&
- req->hObject != TU104_H_INTERNAL_SUBDEVICE))
+ if (!guest_handles &&
+ (req->hClient != TU104_H_INTERNAL_CLIENT ||
+ (req->hObject != TU104_H_INTERNAL_DEVICE &&
+ req->hObject != TU104_H_INTERNAL_SUBDEVICE)))
goto fallback;
fwd_req = kmalloc(GSP_RM_CTRL_HDR_SIZE + req->paramsSize, GFP_KERNEL);
@@ -3037,8 +3060,9 @@ 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 = req->hObject == TU104_H_INTERNAL_DEVICE ?
- snap.h_internal_device : snap.h_internal_subdevice;
+ fwd_hdr.hObject = guest_handles ? snap.h_internal_subdevice :
+ (req->hObject == TU104_H_INTERNAL_DEVICE ?
+ snap.h_internal_device : snap.h_internal_subdevice);
fwd_hdr.cmd = req->cmd;
fwd_hdr.paramsSize = req->paramsSize;
fwd_hdr.flags = req->flags;
@@ -3058,6 +3082,27 @@ static bool gsp_rm_ctrl_forward(struct gsp_emu_context *ctx,
}
/*
+ * r519 experiment evidence: log the live GSP's own answer to the
+ * BINAPI query (status + first params bytes) before deciding.
+ */
+ if (req->cmd == 0x20810107) {
+ u32 st = 0xffffffff, ps = 0xffffffff;
+ u8 b[8] = { 0 };
+
+ if (rsp && rsp_len >= GSP_RM_CTRL_HDR_SIZE) {
+ memcpy(&st, (u8 *)rsp + 12, 4);
+ memcpy(&ps, (u8 *)rsp + 16, 4);
+ if (ps <= 8 && ps <= rsp_len - GSP_RM_CTRL_HDR_SIZE)
+ memcpy(b, (u8 *)rsp + GSP_RM_CTRL_HDR_SIZE,
+ ps);
+ }
+ nv_vgpu_info(ctx->vgpu,
+ "vgsp-rm: BINAPI-EXPERIMENT 0x20810107 forwarded to live GSP: rsp_len=%u status=0x%x outSize=%u bytes=%02x %02x %02x %02x %02x %02x %02x %02x",
+ rsp_len, st, ps, b[0], b[1], b[2], b[3], b[4],
+ b[5], b[6], b[7]);
+ }
+
+ /*
* The reply is rpc_gsp_rm_control_v03_00: status at +12, paramsSize
* at +16, echoed params at +24 - the same 24-byte prefix the emulated
* handler builds below. The RPC-level rpc_result was already checked