Serve the non-blocking futex shapes from EL1
Merged
JS
2mo ago+5811+5811+0123456789012345678901234567890123456789-1144-1144-0123456789012345678901234567890123456789
Serves the two futex shapes that cannot block from the EL1 shim and separates an unrelated vCPU watchdog rewrite that
had been sitting in the same change.
Commits
- Arm one repeating vCPU watchdog, not two a call. The run loop armed
and disarmedalarm()around everyhv_vcpu_run, and on macOS that is
setitimer(ITIMER_REAL), so it cost two real syscalls per guest syscall:
693 ns against a 1226 ns bare HVF round trip. One repeating timer plus a
seqlock progress word replaces it. Unrelated to futex, hence its own
commit. - Serve the non-blocking futex shapes from EL1. A
FUTEX_WAITwhose
word already moved answers EAGAIN at EL1 (51 ns against a 2000 ns HVC
round trip), and aFUTEX_WAKEwith nobody parked answers 0 from a
per-bucket census the wait paths publish intoshim_data(1927 ns to
77 ns). Also widens the bucket table to 1024 with a new hash, and fixes
undefined behavior in theFUTEX_WAKE_OPoperand decode, which was
undefined for half its input range and included the shift operand that
was CVE-2018-6927. - Refuse to requeue a PI waiter, as Linux does.
- Give the analyzer Darwin's shapes, not Linux's. Five declarations
where Frama-C's modeled libc uses the Linux layout and macOS does not,
which is what kept the socket and abstract-socket paths outside the
analyzer. - Stop rebuilding guest state at EL1.
- Spin at EL1, and serve a timed futex wait too. Measured against the
branch point: wake-wait-handoff 1104 ns to 103, wait-timed 1503 ns to 52. - Prove the futex deadline arithmetic.
verify-futexdeadlinedischarges
128 of 128 obligations with-wp-rte.
Close #315
Summary by cubic
Serves non-blocking, timed, and wake futex shapes from the EL1 shim instead of round-tripping to the host, replaces the per-call alarm() watchdog with a repeating timer, fixes signal and ptrace handling inside the shim, and lets the Frama-C analyzer parse 5 more sources.
Futex
- A
FUTEX_WAITwith a moved word answersEAGAINat EL1 (51 ns vs 2000 ns); the shim also spins on a matching word and serves timed waits, cutting a contended wake-wait-handoff from 1104 ns to 103 ns. - The EL1 wake path (77 ns vs 1927 ns for a wake with nobody parked) serves both wake shapes; it was briefly routed to the host when a contract assert flagged the bucket census, but the assert read a transient population and never survived a re-read, so the census holds and
test-shim-futex-statsasserts the counters move. - Fixes undefined behavior in the
FUTEX_WAKE_OPoperand decode and masks an out-of-range shift operand to its low five bits, matching Linux; the shift fix is Linux commit 30d6e0a4190d, not CVE-2018-6927, which names a negative-countfutex_requeueoverflow still unmeasured in TODO.md. - Refuses to requeue a PI waiter, matching Linux.
- Open defect: a signal during SVC return can re-execute the SVC as
ENOSYSunder load.
Watchdog, signals, and tooling
- The run loop arms one repeating watchdog and publishes progress via a seqlock; this removes the two real syscalls per guest syscall that
alarm()cost. - Signal delivery and ptrace stops taken inside the shim now establish EL0 before building a frame;
PTRACE_INTERRUPTuses a new attention bit. - Adds Darwin-shaped stubs for
sockaddr_un(one-byte family),sockaddr_storage,ipc_perm,msqid_ds,stat, andpthread_setname_np, pluscheck-stub-shadowto keep the rename trick sound; the gate honors theFRAMACoverride, including an emptyFRAMAC=as a clean skip. - Proves the futex deadline arithmetic (
verify-futexdeadlinedischarges 128 of 128 obligations);futex_make_deadlinestays unproved since the analyzer has no body forguest_read_small. - Five checks could not report what they guard:
test-ptrace-interrupt's stop-PC ceiling never separated guest from shim PCs (now 16 GiB),test-matrix.shcounted that test without running it,bench-futex-contendignored spawn results, two tests read errno afterpthread_create, which never sets it,test-sleep-longaccepted an unparsable argument, andtest-shim-futex-statsaborted before its counter checks.