diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-25 07:23:52 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-25 07:23:52 -0400 |
| commit | e3c1cdc5ee049797fe40ae648d2a936c7384d517 (patch) | |
| tree | d5e894848e9db33000273f913b672838e14356be | |
| parent | 8d8567c91f282078251d7bd2fc301e7fd438ec36 (diff) | |
| download | open-iov-e3c1cdc5ee049797fe40ae648d2a936c7384d517.tar.gz open-iov-e3c1cdc5ee049797fe40ae648d2a936c7384d517.zip | |
vgsp-rm r682: register NV01_EVENT_KERNEL_CALLBACK (0x78) and NV01_EVENT_KERNEL_CALLBACK_EX (0x7E) events alongside OS_EVENT (0x79)
The driver's modern nvkms/Vulkan path allocates its per-channel
completion events with class 0x7E (nvos.h NV01_EVENT_KERNEL_CALLBACK_EX;
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, whose readiness word lives in a
/dev/nvidiactl notification page that only an event completion can
signal). The event registration scanned the params for hClass 0x79 only,
so 0x7E allocations were never registered and their completion wake-ups
(post_channel_event/post_all_events) could never reach them. Accept all
three event classes; the NV0005_ALLOC_PARAMETERS layout is the same
{hParentClient, hSrcResource, hClass, notifyIndex, data}.
| -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; } |
