BPF gains by-value struct and __int128 argument support
A verifier and JIT series lets global functions and kfuncs take small scalar aggregates without the old rejections and register miscounts.
The BPF verifier and JITs are set to accept struct, union, and __int128 arguments passed by value to global functions and kfuncs, work submitted by Yonghong Song on the BPF list.
Today a by-value struct or union is rejected outright, with messages such as that a STRUCT argument type is not supported. An __int128 is accepted but counted as one argument while the compiler places it in two registers, so every later parameter is checked against the wrong register and the program fails on a register its source never names.
The fix models each argument as one slot per eightbyte, matching how the compiler lowers values of at most 16 bytes into one or two consecutive registers. Only scalar-only aggregates are allowed: a pointer member would arrive as an opaque scalar and lose the provenance and reference tracking the verifier relies on. Global functions still have no stack arguments, so all slots must fit in the argument registers.
Kfunc calls are harder because the BPF convention and the native ABIs disagree. Where BPF would split a value across the last register and the stack, x86-64 moves the whole value to the stack and reuses the register for the next argument; arm64 rounds a 16-byte aligned value up to an even register. The series describes those differences with a small per-architecture ABI table and teaches the x86-64 and arm64 JITs to place and move arguments accordingly.
Selftests cover pairs of register-sized halves, smaller structs, consecutive aggregates, and rejection of pointer-bearing or oversized values. A few arm64 __int128 cases remain gated pending a pahole fix so BTF generation matches the ABI’s even-register rule. Automated review also flagged that some kfunc return-sum checks are commutative and may miss pure slot swaps, and that the arm64 trampoline’s handling of 16-byte aligned arguments may need a follow-up once this path is live.
The change matters for anyone writing typed BPF helpers or kfuncs that naturally take small aggregates or 128-bit values: callers no longer have to flatten those arguments by hand or hit mysterious register errors after an __int128.