freenode
Kernel & Low-Level

BPF gains exception cleanup pads so Rust Drop can unwind safely

A 22-patch bpf-next series adds bpf_unwind(), verifier and x86 JIT support so frames can release locks and references instead of being discarded.

Yonghong Song has posted a seventh revision of a 22-patch series that lets BPF programs run exception cleanup landing pads when unwinding, removing a hard blocker for Rust BPF code that needs Drop glue on the panic path.

Today bpf_throw() walks to the exception boundary and discards every frame in between. Any frame that holds an RCU read lock, a preemption-disabled section, or a referenced kernel pointer never gets to release it, so the verifier simply forbids such frames from throwing. Rust's Drop path is exactly that release work, which is why a Rust BPF program cannot treat bpf_throw() as its panic path.

LLVM 23 already emits the compiler side: for each invoke that may unwind across an owned value, the BPF backend writes a flat table of (begin, end, landing_pad) records into a .bpf_cleanup section. A suspended frame whose call site falls in that range resumes at the pad, which ends by calling a kernel-provided resume helper. Song's series is the kernel half. It accepts that table at program load, teaches the verifier that a covered call can also transfer to its pad, and introduces a new bpf_unwind() kfunc that dispatches those pads as it walks the stack, rather than overloading bpf_throw()'s discard semantics.

The work also extends the libbpf linker so objects carrying the new relocation forms can link, updates the x86 JIT to rewrite return-address slots when handing control to a pad, and adds selftests that spell out by hand the shapes a frontend would emit, including pads that drop locks and references the frame actually held. Frames that leave holding something they did not enter with, nested unwinds, and pads reached by illegal control flow are rejected.

If merged, the change is the missing runtime piece for exception-style cleanup in BPF and for using Rust Drop across calls that can fail.