summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 07:23:52 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-25 07:23:52 -0400
commite3c1cdc5ee049797fe40ae648d2a936c7384d517 (patch)
treed5e894848e9db33000273f913b672838e14356be
parent8d8567c91f282078251d7bd2fc301e7fd438ec36 (diff)
downloadopen-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.c35
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;
}