summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-26 02:03:37 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-26 02:03:37 -0400
commit7ac4d61c5a06fda4c9d4a398fb49f400b2b76f15 (patch)
tree3400e4fd6cba29bb6e4525d788509acd5803d3ee /kernel
parent70459a9782098fe409dcf49ec2496e568c826903 (diff)
downloadopen-iov-7ac4d61c5a06fda4c9d4a398fb49f400b2b76f15.tar.gz
open-iov-7ac4d61c5a06fda4c9d4a398fb49f400b2b76f15.zip
gsp_rm: cap event records between replies so the status ring cannot wrap
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_rm_emulation.c25
-rw-r--r--kernel/gsp_rm_emulation.h4
2 files changed, 29 insertions, 0 deletions
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);
diff --git a/kernel/gsp_rm_emulation.h b/kernel/gsp_rm_emulation.h
index 8b9612b..2938c92 100644
--- a/kernel/gsp_rm_emulation.h
+++ b/kernel/gsp_rm_emulation.h
@@ -49,6 +49,8 @@ struct gsp_emu_context;
#define GSPRM_RPC_FUNC_UPDATE_BAR_PDE 70
#define GSPRM_RPC_EVENT_POST_EVENT 0x1003
#define GSPRM_MAX_EVENTS 128
+/* Max event records written between two replies (status-ring safety). */
+#define GSPRM_EVENT_BURST_MAX 24
#define GSPRM_RPC_EVENT_GSP_INIT_DONE 0x1001
/* rpc_set_guest_system_info_v03_00: version fields the driver reads back
@@ -192,6 +194,8 @@ struct gsp_rm_emu {
} events[GSPRM_MAX_EVENTS];
u32 events_n;
u64 events_posted;
+ u64 events_dropped;
+ u32 event_burst; /* event records written since the last reply */
};
int gsp_rm_emu_init(struct nv_vgpu_device *vgpu, struct gsp_emu_context *ctx);