Re: [PATCH bpf-next v5 09/11] selftests/bpf: Add C tests for 16-byte returns in R0:R2
Yonghong Song <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
On 8/14/26 5:47 PM, Eduard Zingerman wrote: > On Thu, 2026-08-13 at 13:02 -0700, Yonghong Song wrote: >> Add selftests that exercise a 16-byte return value passed in the R0:R2 >> register pair, written in C so that they depend on the compiler lowering >> the register-pair return. Covered are an __int128 return, a 16-byte struct >> return (from a static and from a global subprogram) and a 16-byte union >> return, plus __int128 and 16-byte struct returns from a kfunc. The union >> program shares an object with the struct ones. >> >> The R0:R2 convention is only emitted by LLVM 23 and newer, and a by-value >> aggregate return does not compile at all before that, so the programs sit >> behind a __clang_major__ guard. An older compiler builds the dummy test in >> the #else branch instead, which keeps each object non-empty and says in >> its description why nothing was exercised. >> >> The kfunc tests are tagged __arch_x86_64/__arch_arm64 and skip elsewhere. >> Those are the architectures whose JIT advertises >> bpf_jit_supports_kfunc_ret_reg_pair(), which bpf_add_kfunc_call() requires >> before it accepts a kfunc returning more than 8 bytes, and they are also >> the only ones building the kfuncs. >> >> Signed-off-by: Yonghong Song <[email protected]> >> --- > Acked-by: Eduard Zingerman <[email protected]> > >> .../selftests/bpf/prog_tests/aggregate_ret.c | 13 ++ >> .../bpf/progs/aggregate_ret_int128_c.c | 49 ++++++++ >> .../bpf/progs/aggregate_ret_kfunc_c.c | 65 ++++++++++ >> .../bpf/progs/aggregate_ret_struct_c.c | 114 ++++++++++++++++++ > Nit: I'd merge all three files into one and move loader to prog_tests/verifier.c. > Also not sure about union vs struct tests. Okay, will do. > >> diff --git a/tools/testing/selftests/bpf/progs/aggregate_ret_int128_c.c b/tools/testing/selftests/bpf/progs/aggregate_ret_int128_c.c >> new file mode 100644 >> index 000000000000..913cc374215d >> --- /dev/null >> +++ b/tools/testing/selftests/bpf/progs/aggregate_ret_int128_c.c > ... > >> +#if defined(__clang_major__) && __clang_major__ >= 23 > ... > >> +#else >> + >> +SEC("socket") >> +__description("aggregate_ret_int128_c: needs LLVM 23, dummy test") >> +__success >> +int dummy_test(void) >> +{ >> + return 0; >> +} > Q: what would happen w/o #else branch? Is loading an empty object an error? With #else branch, we will have: #1/1 aggregate_ret/aggregate_ret_int128_c: needs LLVM 23, dummy test:OK #1/2 aggregate_ret/aggregate_ret_struct_c: needs LLVM 23, dummy test:OK #1/3 aggregate_ret/aggregate_ret_kfunc_c: needs LLVM 23, dummy test:OK Without #else branch, all the above three subtests will be gone. I probably will keep it so user knows the current limitation. Once CI compiler becomes llvm23, the above three will go through real tests. > >> +#endif > ...