summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_sema_service.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 15:19:34 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-29 15:19:34 -0400
commit40411a6837620097efe2cf15f322f0526ae45385 (patch)
tree1851b23dda57385a021f70aed67e0253e4bb17c4 /kernel/gsp_sema_service.c
parentf737696b6ab728c4045517ae8341734f1ac3cc74 (diff)
downloadopen-iov-40411a6837620097efe2cf15f322f0526ae45385.tar.gz
open-iov-40411a6837620097efe2cf15f322f0526ae45385.zip
sema-svc: never apply swept-page releases with no live channel (guest boot corruption); tooling guards
Diffstat (limited to 'kernel/gsp_sema_service.c')
-rw-r--r--kernel/gsp_sema_service.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index ae8f7da..b29e833 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -2668,6 +2668,29 @@ static u32 svc_apply_page_data(struct nv_vgpu_device *vgpu, const u8 *buf,
u64 pa_page)
{
u32 off, applied = 0;
+ bool any = false;
+ unsigned long flags;
+ int ci;
+
+ /*
+ * No live channel: no client can be waiting on a release, so a
+ * "release" decoded from an arbitrary swept page can only be a false
+ * positive, and its write lands through whatever translation the VA
+ * happens to have (observed: 2 applied writes while the guest kernel
+ * was booting corrupted a task's CPU field and panicked the guest
+ * scheduler). Only apply swept-page releases while a client exists;
+ * real releases are carried by the channels' readable pushes then.
+ */
+ spin_lock_irqsave(&svc.chan_lock, flags);
+ for (ci = 0; ci < SVC_MAX_CHANNELS; ci++) {
+ if (svc.chan[ci].valid) {
+ any = true;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&svc.chan_lock, flags);
+ if (!any)
+ return 0;
/*
* Decoded execution: walk the page as a method stream and perform the