This is quite important when you want to run this code in production. You don't want to accidently crash your kernel.
This is quite important when you want to run this code in production. You don't want to accidently crash your kernel.
For instance, you could just write your kernel module in a sufficiently safe language, like Rust, and have the same benefits. You could even pre-compile eBPF for the exact same level of safety. Still no need for the bpf() system call or the eBPF VM or JIT in the kernel.
* Strictly typed -- registers, and memory are type checked at compilation time. If you use something like Rust, you'd have to bring rustc into the kernel
* Guaranteed to terminate -- you cannot jump backwards, and there is an upper bound on the instruction count
* Bounded memory -- The registers, and accessible memory via maps are a fixed size. We don't have a stack per se.
Compiling Rust to this is possible, but it'd require quite a bit of infrastructure in the kernel to verify that the code is safe, versus the simplicity of eBPF. Early attempts at a general purpose in-kernel VM included passing an AST in, and then doing safety checking on the AST, but they proved too complicated to do safely.
I'm arguing against the in-kernel eBPF infrastructure: bpf system call, the JIT and the VM.
I think it makes more sense to just compile eBPF (or rust or whatever safe language you want) to a kernel module.
Accepting compiled stuff in the form of a kernel module requires root privileges and requires that the kernel essentially have complete trust in the code being loaded.
Loading eBPF eliminates the need to trust the process/user doing the loading to that level.