From bd01273cd1b221f55eb484e8b7fd742417a4d4bd Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 23 Oct 2026 20:09:08 -0400 Subject: r578 diag: event-function reachability probe (gsp_rm_ev_func) The r577 A/B (sequence, bNotifyList, hClient) all yielded nv_post_event=0 with every record consumed by the guest: the drop is content-independent. This knob posts event records with a caller-chosen RPC function instead of POST_EVENT 0x1003; posting an event whose handler has an unmistakable guest side effect (UCODE_LIBOS_PRINT 0x100C trips NV_ASSERT_FAILED on an unsupported ucode; OS_ERROR_LOG 0x1006 logs an errString) proves whether the guest dispatches our status-queue event records at all - dispatch vs consumed-without-dispatch decides the next probe (inside _kgspRpcPostEvent or earlier in the drain). --- kernel/gsp_rm_emulation.c | 27 ++++++++++++++++++++++----- kernel/gsp_rm_emulation.h | 1 + kernel/main.c | 2 ++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index f44c01b..357997c 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -770,6 +770,19 @@ static void gsp_rm_evlog_post(struct nv_vgpu_device *vgpu, unsigned gsp_rm_ev_seq; unsigned gsp_rm_ev_nlist; unsigned gsp_rm_ev_cl; +/* + * r578: reachability probe for the guest-RM event drop. When nonzero, event + * records carry this RPC function instead of POST_EVENT (0x1003). Posting a + * function with an unmistakable guest-side side effect (e.g. + * NV_VGPU_MSG_EVENT_UCODE_LIBOS_PRINT 0x100C with an unsupported ucodeEngDesc + * trips NV_ASSERT_FAILED in _kgspRpcUcodeLibosPrint, or + * NV_VGPU_MSG_EVENT_OS_ERROR_LOG 0x1006 logs an errString) proves whether + * the guest ever DISPATCHES our status-queue event records: visible side + * effect => the dispatch works and POST_EVENT is dropped inside + * _kgspRpcPostEvent; no side effect => the records are consumed without + * dispatch. + */ +unsigned gsp_rm_ev_func; static void gsp_rm_fill_ev_payload(const struct gsp_rm_emu *rm, u32 i, u8 *payload) @@ -793,6 +806,11 @@ static u32 gsp_rm_ev_sequence(const struct gsp_rm_emu *rm) return gsp_rm_ev_seq ? rm->stat_seq : 0; } +static u32 gsp_rm_ev_function(void) +{ + return gsp_rm_ev_func ? gsp_rm_ev_func : GSPRM_RPC_EVENT_POST_EVENT; +} + /* * Post the GPU event that tells the guest's CPU-side RM a channel's * submitted work is complete. A real GPU raises an interrupt, the host GSP @@ -827,8 +845,7 @@ int gsp_rm_post_channel_event(struct nv_vgpu_device *vgpu, u32 h_src) gsp_rm_fill_ev_payload(rm, i, payload); { - int rc = gsp_rm_send_flags(ctx, - GSPRM_RPC_EVENT_POST_EVENT, + int rc = gsp_rm_send_flags(ctx, gsp_rm_ev_function(), gsp_rm_ev_sequence(rm), 0, payload, sizeof(payload), true); @@ -854,7 +871,7 @@ int gsp_rm_post_channel_event(struct nv_vgpu_device *vgpu, u32 h_src) gsp_rm_fill_ev_payload(rm, i, payload); { int rc = gsp_rm_send_flags(ctx, - GSPRM_RPC_EVENT_POST_EVENT, + gsp_rm_ev_function(), gsp_rm_ev_sequence(rm), 0, payload, sizeof(payload), @@ -896,7 +913,7 @@ static int gsp_rm_post_event_idx(struct gsp_emu_context *ctx, u32 idx) gsp_rm_fill_ev_payload(rm, idx, payload); - rc = gsp_rm_send(ctx, GSPRM_RPC_EVENT_POST_EVENT, + rc = gsp_rm_send(ctx, gsp_rm_ev_function(), gsp_rm_ev_sequence(rm), 0, payload, sizeof(payload)); if (!rc) rm->events[idx].last_post = jiffies; @@ -977,7 +994,7 @@ int gsp_rm_post_all_events(struct nv_vgpu_device *vgpu) gsp_rm_fill_ev_payload(rm, i, payload); { - int rc = gsp_rm_send(ctx, GSPRM_RPC_EVENT_POST_EVENT, + int rc = gsp_rm_send(ctx, gsp_rm_ev_function(), gsp_rm_ev_sequence(rm), 0, payload, sizeof(payload)); diff --git a/kernel/gsp_rm_emulation.h b/kernel/gsp_rm_emulation.h index 85ee4d9..a0bd4c7 100644 --- a/kernel/gsp_rm_emulation.h +++ b/kernel/gsp_rm_emulation.h @@ -224,6 +224,7 @@ extern unsigned gsp_rm_ev_log_max; extern unsigned gsp_rm_ev_seq; extern unsigned gsp_rm_ev_nlist; extern unsigned gsp_rm_ev_cl; +extern unsigned gsp_rm_ev_func; int gsp_rm_emu_init(struct nv_vgpu_device *vgpu, struct gsp_emu_context *ctx); void gsp_rm_emu_fini(struct gsp_emu_context *ctx); diff --git a/kernel/main.c b/kernel/main.c index 8d02e5b..d821762 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -2822,6 +2822,8 @@ module_param_named(gsp_rm_ev_nlist, gsp_rm_ev_nlist, uint, 0644); MODULE_PARM_DESC(gsp_rm_ev_nlist, "set bNotifyList on event records (default 0: specific-hEvent dispatch)"); module_param_named(gsp_rm_ev_cl, gsp_rm_ev_cl, uint, 0644); MODULE_PARM_DESC(gsp_rm_ev_cl, "override event record hClient (default 0: the allocating client)"); +module_param_named(gsp_rm_ev_func, gsp_rm_ev_func, uint, 0644); +MODULE_PARM_DESC(gsp_rm_ev_func, "reachability probe: event records carry this RPC function instead of POST_EVENT 0x1003 (default 0)"); module_param_named(gsp_sema_walk_trace, gsp_sema_walk_trace, uint, 0644); MODULE_PARM_DESC(gsp_sema_walk_trace, "Trace GMMU walks for unresolved high-VA operands (default 0: off)"); -- cgit v1.2.3