diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 15:19:34 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-29 15:19:34 -0400 |
| commit | 40411a6837620097efe2cf15f322f0526ae45385 (patch) | |
| tree | 1851b23dda57385a021f70aed67e0253e4bb17c4 | |
| parent | f737696b6ab728c4045517ae8341734f1ac3cc74 (diff) | |
| download | open-iov-40411a6837620097efe2cf15f322f0526ae45385.tar.gz open-iov-40411a6837620097efe2cf15f322f0526ae45385.zip | |
sema-svc: never apply swept-page releases with no live channel (guest boot corruption); tooling guards
| -rw-r--r-- | kernel/gsp_sema_service.c | 23 | ||||
| -rw-r--r-- | tools/guest-diag/pin_gr_stream.py | 7 | ||||
| -rwxr-xr-x | tools/guest-diag/semfix_uvmt.py | 10 |
3 files changed, 36 insertions, 4 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 diff --git a/tools/guest-diag/pin_gr_stream.py b/tools/guest-diag/pin_gr_stream.py index 22c202b..c1ef7b2 100644 --- a/tools/guest-diag/pin_gr_stream.py +++ b/tools/guest-diag/pin_gr_stream.py @@ -45,8 +45,11 @@ def install_and_start(): b64 = subprocess.run(["base64", "-w0"], stdin=f, capture_output=True, text=True).stdout cmd = ("echo '%s' | base64 -d > /tmp/guest_pin_stream.py; " - "[ -f /tmp/guest_pin_stream.pid ] && sudo kill " - "$(cat /tmp/guest_pin_stream.pid) 2>/dev/null; " + "if [ -f /tmp/guest_pin_stream.pid ]; then " + "p=$(cat /tmp/guest_pin_stream.pid 2>/dev/null); " + "[ -n \"$p\" ] && grep -q guest_pin_stream " + "/proc/$p/cmdline 2>/dev/null && sudo kill $p 2>/dev/null; " + "fi; " "sudo rm -f /tmp/guest_pin_stream.pid; " "sudo setsid nohup python3 /tmp/guest_pin_stream.py %d %d %s %s %s " ">/tmp/guest_pin_stream.log 2>&1 & sleep 2; " diff --git a/tools/guest-diag/semfix_uvmt.py b/tools/guest-diag/semfix_uvmt.py index 12577ab..0d31394 100755 --- a/tools/guest-diag/semfix_uvmt.py +++ b/tools/guest-diag/semfix_uvmt.py @@ -115,11 +115,17 @@ def state_str(sem, st): def dmesg_releases(seen): - """Print/append new host-decoded releases (sema-push lines).""" + """Print/append new host-decoded releases (sema-push lines). + + Only lines after the last "sema-svc: thread started" marker count: dmesg + keeps the previous module load's lines and the old client's releases. + """ try: r = subprocess.run( ["sudo", "-n", "sh", "-c", - "dmesg -T | grep 'sema-push' | tail -300"], + "dmesg -T | awk '/sema-svc: thread started/{n=NR} " + "{l[NR]=$0} END{for(i=n+1;i<=NR;i++) print l[i]}' " + "| grep 'sema-push' | tail -300"], capture_output=True, text=True, timeout=10) except Exception: return |
