diff options
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index b338a6f..b8a3e37 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -3159,11 +3159,22 @@ static void gsp_rm_handle_rm_alloc(struct gsp_emu_context *ctx, gsp_rm_register_channel(ctx, ho, params, params_size); /* - * NV01_EVENT (allocated with class 0x79 in the guest ABI; params are - * NV0005_ALLOC_PARAMETERS {hParentClient, hSrcResource, hClass, - * notifyIndex, data}). The driver allocates one per channel and waits - * for the GPU to post the event before it considers submitted work - * complete - remember them so completed work can be signalled back. + * NV01_EVENT (params are NV0005_ALLOC_PARAMETERS {hParentClient, + * hSrcResource, hClass, notifyIndex, data}). The driver allocates one + * per channel and waits for the GPU to post the event before it + * considers submitted work complete - remember them so completed work + * can be signalled back. + * + * r682: the guest ABI uses THREE event classes and only the + * NV01_EVENT_OS_EVENT (0x79) shape was registered: libcuda's channel + * events arrive as 0x79, but the modern nvkms/Vulkan path allocates + * NV01_EVENT_KERNEL_CALLBACK_EX (0x7E, nvos.h) - observed live as + * `GSP_RM_ALLOC class=0x7e paramsSize=24 hParent=<subdevice> + * hObject=0xcaf00003` from the second RM client while its main + * thread sat in the vkCreateDevice wait loop (readiness word in a + * /dev/nvidiactl notification page, never signalled). Register 0x78 + * (KERNEL_CALLBACK) and 0x7E alongside 0x79 so the completion + * wake-ups reach those events too. * * The table is append+retire: FREE retires records (valid=false) but * never shrinks events_n, so long-lived boots with many client @@ -3176,7 +3187,8 @@ static void gsp_rm_handle_rm_alloc(struct gsp_emu_context *ctx, * first retired slot for a new registration, and log loudly when the * table is genuinely full of live entries. */ - if (class_id == 0x79 && params_size >= 24) { + if ((class_id == 0x79 || class_id == 0x7e || class_id == 0x78) && + params_size >= 24) { u32 h_src = 0, notify_index = 0, hclass = 0; u64 data64 = 0; int hc_off = -1, i; @@ -3194,16 +3206,17 @@ static void gsp_rm_handle_rm_alloc(struct gsp_emu_context *ctx, rm->events_n, ho); else { /* - * Locate hClass (0x79) inside the params instead of - * trusting a fixed offset: NV0005_ALLOC_PARAMETERS is - * {hParentClient, hSrcResource, hClass, notifyIndex, - * data}, with hSrcResource immediately before hClass. + * Locate hClass (0x78/0x79/0x7e) inside the params + * instead of trusting a fixed offset: + * NV0005_ALLOC_PARAMETERS is {hParentClient, + * hSrcResource, hClass, notifyIndex, data}, with + * hSrcResource immediately before hClass. */ for (i = 0; i + 4 <= (int)params_size; i += 4) { u32 v; memcpy(&v, params + i, 4); - if (v == 0x79) { + if (v == 0x79 || v == 0x7e || v == 0x78) { hc_off = i; break; } |
