From 7ac4d61c5a06fda4c9d4a398fb49f400b2b76f15 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Sat, 26 Sep 2026 02:03:37 -0400 Subject: gsp_rm: cap event records between replies so the status ring cannot wrap --- kernel/gsp_rm_emulation.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'kernel/gsp_rm_emulation.c') diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index a1c653e..52cf645 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -478,6 +478,31 @@ static int gsp_rm_send(struct gsp_emu_context *ctx, u32 function, * service's thread. */ mutex_lock(&rm->stat_lock); + /* + * Bound the number of event records written between replies. Events are + * only wake-ups (the client re-reads channel state), so dropping some is + * harmless, but an unbounded event burst can wrap the status ring while + * a client is blocked waiting for its reply - the read then returns a + * newer record and the client aborts with "Bad sequence number". + */ + if (function == GSPRM_RPC_EVENT_POST_EVENT) { + if (rm->event_burst >= GSPRM_EVENT_BURST_MAX) { + rm->events_dropped++; + if (rm->events_dropped <= 8 || + (rm->events_dropped % 1000) == 0) + nv_vgpu_info(ctx->vgpu, + "GSPRM: event burst capped (%u), dropped total=%llu", + GSPRM_EVENT_BURST_MAX, + rm->events_dropped); + mutex_unlock(&rm->stat_lock); + kfree(buf); + return -EAGAIN; + } + rm->event_burst++; + } else { + rm->event_burst = 0; + } + record_size = gsp_rm_build_record(rm, buf, buf_size, function, sequence, result, data, data_len, &elem_count); -- cgit v1.2.3