Re: [PATCH bpf-next v5 06/11] bpf: Add verifier support for 16-byte returns in R0:R2

Eduard Zingerman <[email protected]>
Newsgroups org.kernel.vger.bpf
Message-ID <[email protected]>
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]/

>  		/*
>  		 * *.multi programs don't need an address during program
>  		 * verification, we just take the module ref if needed.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.