Commit 7cd1f73b37ea ("selftests/bpf: Fix build of callx tests with GCC") gated the callx progs on __clang__. GCC had indirect call support which was recently refurbished along with a __BPF_FEATURE_CALLX macro [1], so gate on that as well so once this GCC is released, the tests start passing. Put the arch and compiler conditions in a CAN_USE_CALLX macro in bpf_misc.h, and use it all the test programs. While at it, mark the placeholder programs left for unsupported toolchains and arches with __skip(), so they report SKIP rather than OK. [1] https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=ffe3ead4a8ad704b557b0cfa4f823df647c65a0d Measured on bpf-next with a stock bpf-gcc that defines __BPF_FEATURE_CALLX, test_progs before and after: 76 subtests run that previously did not exist in the report, 75 OK and one @unpriv SKIP, with no failures. The two dummy placeholders retire and callx_rodata_lskel goes SKIP -> OK. Signed-off-by: Vineet Gupta --- .../testing/selftests/bpf/prog_tests/callx_rodata_lskel.c | 2 +- tools/testing/selftests/bpf/progs/bpf_misc.h | 7 +++++++ tools/testing/selftests/bpf/progs/callx_rodata.c | 4 ++-- tools/testing/selftests/bpf/progs/verifier_callx.c | 5 ++--- tools/testing/selftests/bpf/progs/verifier_callx_rodata.c | 5 ++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c b/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c index f6ef67c3141e..acd821fb568f 100644 --- a/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c +++ b/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c @@ -36,7 +36,7 @@ static void __test_callx_rodata_lskel(void) if (!ASSERT_OK_PTR(skel, "open")) return; - /* gcc doesn't support indirect calls */ + /* toolchain or JIT can't do callx */ if (skel->rodata->skip) { test__skip(); goto out; diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h index d7f706c3bc4a..1b264480e128 100644 --- a/tools/testing/selftests/bpf/progs/bpf_misc.h +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h @@ -295,6 +295,13 @@ #define CAN_USE_LOAD_ACQ_STORE_REL #endif +/* clang always emits callx, gcc only when it defines __BPF_FEATURE_CALLX */ +#if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \ + (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \ + (defined(__clang__) || defined(__BPF_FEATURE_CALLX)) +#define CAN_USE_CALLX +#endif + #if defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) #define SPEC_V1 #endif diff --git a/tools/testing/selftests/bpf/progs/callx_rodata.c b/tools/testing/selftests/bpf/progs/callx_rodata.c index e3f8335f80f8..8c28f01b7113 100644 --- a/tools/testing/selftests/bpf/progs/callx_rodata.c +++ b/tools/testing/selftests/bpf/progs/callx_rodata.c @@ -4,13 +4,14 @@ #include #include #include +#include "bpf_misc.h" /* set by user space before the programs are loaded, it's in .rodata too */ const volatile int bias = 1; int op_idx; -#ifdef __clang__ +#ifdef CAN_USE_CALLX const volatile bool skip = false; @@ -48,7 +49,6 @@ int both_ops(void *ctx) #else -/* gcc doesn't support indirect calls */ const volatile bool skip = true; SEC("socket") diff --git a/tools/testing/selftests/bpf/progs/verifier_callx.c b/tools/testing/selftests/bpf/progs/verifier_callx.c index 7e59188d9fca..ca1aef34ab72 100644 --- a/tools/testing/selftests/bpf/progs/verifier_callx.c +++ b/tools/testing/selftests/bpf/progs/verifier_callx.c @@ -6,9 +6,7 @@ #include "bpf_misc.h" #include "../../../include/linux/filter.h" -/* gcc doesn't support indirect calls */ -#if defined(__clang__) && (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \ - (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) +#ifdef CAN_USE_CALLX #define CALLX_INSN(DST, SRC, OFF, IMM) \ BPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, DST, SRC, OFF, IMM) @@ -1075,6 +1073,7 @@ int callx_c_ops_on_stack(void *ctx) #else SEC("socket") +__skip("callx needs arch JIT and compiler support") __success int dummy(void *ctx) { diff --git a/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c b/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c index 6cf58ca9ac5b..ab3e3b64616b 100644 --- a/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c +++ b/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c @@ -6,9 +6,7 @@ #include "bpf_misc.h" #include "../../../include/linux/filter.h" -/* gcc doesn't support indirect calls */ -#if defined(__clang__) && (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \ - (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) +#ifdef CAN_USE_CALLX /* * Read-only data with pointers to functions, where the compiler puts tables @@ -892,6 +890,7 @@ int callx_c_packed_struct(void *ctx) #else SEC("socket") +__skip("callx needs arch JIT and compiler support") __success int dummy(void *ctx) { -- 2.53.0-Meta