Re: [PATCH bpf-next v5 06/11] bpf: Add verifier support for 16-byte returns in R0:R2
Yonghong Song <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On 8/14/26 4:53 PM, Eduard Zingerman wrote: > On Thu, 2026-08-13 at 13:02 -0700, Yonghong Song wrote: >> 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. >> >> This patch models 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 R0 already is. 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: its own return value is the program exit code, read out of R0 >> alone, 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 with >> -EOPNOTSUPP rather than supported. >> >> [1] https://github.com/llvm/llvm-project/pull/190894 >> [2] https://github.com/llvm/llvm-project/pull/206876 >> >> Signed-off-by: Yonghong Song <[email protected]> >> --- > Acked-by: Eduard Zingerman <[email protected]> > >> @@ -19404,6 +19458,13 @@ int bpf_check_attach_target(struct bpf_verifier_log *log, >> return -EOPNOTSUPP; >> } >> >> + if (prog_extension && tgt_info->fmodel.ret_size > 8) { >> + bpf_log(log, >> + "Cannot replace function %s with a >8 byte return value\n", >> + tname); >> + return -EOPNOTSUPP; >> + } >> + > As commented in v4 [1], this check belongs to btf_check_type_match(). > > [1] https://lore.kernel.org/bpf/[email protected]/ Okay, will do. > >> /* >> * *.multi programs don't need an address during program >> * verification, we just take the module ref if needed.