summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorYonghong Song <yonghong.song@linux.dev>2026-08-18 22:53:09 -0700
committerEduard Zingerman <eddyz87@gmail.com>2026-08-21 10:49:28 -0700
commit0630ad00d96d9cf600c5c340cdecb363caa9d1cc (patch)
tree8f1346b2de66693be0beb156247c151ba8ba5a31 /scripts
parent991fb7823106bb2faa8a4871bc1d7c745201bac9 (diff)
downloadlinux-next-0630ad00d96d9cf600c5c340cdecb363caa9d1cc.tar.gz
linux-next-0630ad00d96d9cf600c5c340cdecb363caa9d1cc.zip
bpf: Add verifier support for 16-byte returns in R0: R2
LLVM 23 added support for returning a value in two registers for an __int128, or a struct/union whose size is greater than 8 but not more than 16 bytes. See LLVM patches [1] and [2]. Before LLVM 23 the BPF backend could not return these values at all. A by-value struct or union return (of any size) was rejected at compile time with: error: aggregate returns are not supported and an __int128 return failed later in the backend with: fatal error: error in backend: unable to allocate function return #1 Both are resolved in LLVM 23, which lowers such returns into the R0:R2 register pair. Model that pair at calls to global and static BPF subprograms and at kfunc calls: R2 is marked alongside R0 at the call, propagated out of a callee at its exit, and held to the same scalar-only and no-stack-pointer rules that already apply to R0. A struct returned by a kfunc must be composed of scalars, since its bytes reach the program as raw register contents and a pointer field would otherwise be laundered into a scalar. An extension program is the one caller of the convention that cannot take part in it: only R0 is checked at its exit, since that is the program exit code, so it has no way to hand back an upper half. Replacing a function whose return value is larger than 8 bytes is therefore rejected in btf_check_func_type_match(). That function compares btf_type->info, which carries no size for an int, so an 8 byte long and a 16 byte __int128 compared equal; sizes up to 8 bytes stay interchangeable, as they always have been, so this only rejects what the R0:R2 convention newly makes incompatible. [1] https://github.com/llvm/llvm-project/pull/190894 [2] https://github.com/llvm/llvm-project/pull/206876 Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260819055309.3297684-1-yonghong.song@linux.dev Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Diffstat (limited to 'scripts')
0 files changed, 0 insertions, 0 deletions