| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/11/03 17:09 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch modifies only BPF selftests and test build files under tools/testing/selftests/bpf/. These changes do not affect the compiled kernel image (vmlinux) or kernel modules, and are therefore not fuzzed.",
"WorthFuzzing": false
} |
| 1/1 | 2026/11/03 17:09 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 266692487b044af568d80b9006f1762ee168c8a0\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Nov 3 17:09:55 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile\nindex c99e0f623e1034..77682bf28c6ece 100644\n--- a/tools/testing/selftests/bpf/Makefile\n+++ b/tools/testing/selftests/bpf/Makefile\n@@ -376,7 +376,7 @@ CLANG_TARGET_ARCH = --target=$(notdir $(CROSS_COMPILE:%-=%))\n endif\n \n CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH))\n-CLANG_CFLAGS = $(CLANG_SYS_INCLUDES)\n+CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) $(CLANG_BPF_CFLAGS)\n \n # genkey writes both outputs. Pattern rules group them even on make\n # versions before 4.3, preventing concurrent genkey invocations.\n@@ -511,7 +511,7 @@ BINARY := test_progs\n BPF_CC := $(CLANG)\n BPF_CC_MSG := CLNG-BPF\n BPF_SYS_INCLUDES := $(CLANG_SYS_INCLUDES)\n-BPF_CC_FLAGS := -O2 $(BPF_TARGET_ENDIAN) -mcpu=v3\n+BPF_CC_FLAGS := -O2 $(BPF_TARGET_ENDIAN) -mcpu=v3 $(CLANG_BPF_CFLAGS)\n BPF_DEFINES := -DENABLE_ATOMICS_TESTS\n include Makefile.skel\n \n@@ -527,12 +527,12 @@ $(OUTPUT)/test_progs: $(RUNNER_PREREQS) $(BPF_OBJS) $(ALL_SKELS) FORCE\n \n $(OUTPUT)/test_progs-no_alu32: $(RUNNER_PREREQS) FORCE\n \t+$(Q)$(RUNNER_MAKE) RUNNER=test_progs FLAVOR=no_alu32 TESTS_DIR=prog_tests \\\n-\t\t$(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v2'\n+\t\t$(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v2 $(CLANG_BPF_CFLAGS)'\n \n ifneq ($(CLANG_CPUV4),)\n $(OUTPUT)/test_progs-cpuv4: $(RUNNER_PREREQS) FORCE\n \t+$(Q)$(RUNNER_MAKE) RUNNER=test_progs FLAVOR=cpuv4 TESTS_DIR=prog_tests \\\n-\t\t$(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v4' \\\n+\t\t$(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v4 $(CLANG_BPF_CFLAGS)' \\\n \t\tBPF_DEFINES=-DENABLE_ATOMICS_TESTS\n endif\n \ndiff --git a/tools/testing/selftests/bpf/Makefile.buildvars b/tools/testing/selftests/bpf/Makefile.buildvars\nindex d2a0c0031b87d5..4d25a736376ca0 100644\n--- a/tools/testing/selftests/bpf/Makefile.buildvars\n+++ b/tools/testing/selftests/bpf/Makefile.buildvars\n@@ -132,13 +132,15 @@ BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN)\t\\\n \t -I$(abspath $(OUTPUT)/../usr/include)\t\t\t\\\n \t -std=gnu11\t\t \t\t\t\t\t\\\n \t -fno-strict-aliasing \t\t\t\t\t\\\n-\t -Wno-microsoft-anon-tag\t\t\t\t\t\\\n \t -fms-extensions\t\t\t\t\t\t\\\n \t -Wno-compare-distinct-pointer-types\t\t\t\\\n-\t -Wno-initializer-overrides\t\t\t\t\t\\\n \t #\n # TODO: enable me -Wsign-compare\n \n+# Warning flags that only clang has. GCC accepts an unknown -Wno-foo\n+# silently and then notes it on the next diagnostic it emits.\n+CLANG_BPF_CFLAGS := -Wno-microsoft-anon-tag -Wno-initializer-overrides\n+\n VERIFY_SIG_SETUP := $(CURDIR)/verify_sig_setup.sh\n VERIFICATION_CERT := $(BUILD_DIR)/signing_key.der\n PRIVATE_KEY := $(BUILD_DIR)/signing_key.pem\ndiff --git a/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h b/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h\nindex 82aafe879fae26..4f2c6050215fcd 100644\n--- a/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h\n+++ b/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h\n@@ -49,7 +49,23 @@ void __arena* bpf_arena_alloc_pages(void *map, void __arena *addr, __u32 page_cn\n int bpf_arena_reserve_pages(void *map, void __arena *addr, __u32 page_cnt) __ksym __weak;\n void bpf_arena_free_pages(void *map, void __arena *ptr, __u32 page_cnt) __ksym __weak;\n \n+/*\n+ * GCC's -Warray-bounds fires on the member access: the map definition the\n+ * object file carries is smaller than struct bpf_arena. Make the pointer\n+ * opaque to it, as the open-coded form in progs/stream.c already does.\n+ * clang does not warn and does not need the barrier, which costs a reload\n+ * of the map address at every call site.\n+ */\n+#ifdef __clang__\n #define arena_base(map) ((void __arena *)((struct bpf_arena *)(map))-\u003euser_vm_start)\n+#else\n+#define arena_base(map)\t\t\t\t\t\t\t\\\n+({\t\t\t\t\t\t\t\t\t\\\n+\tstruct bpf_arena *__ma = (void *)(map);\t\t\t\t\\\n+\tbarrier_var(__ma);\t\t\t\t\t\t\\\n+\t(void __arena *)__ma-\u003euser_vm_start;\t\t\t\t\\\n+})\n+#endif\n \n #else /* when compiled as user space code */\n \ndiff --git a/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c b/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c\nindex f6ef67c3141ee8..acd821fb568f53 100644\n--- a/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c\n+++ b/tools/testing/selftests/bpf/prog_tests/callx_rodata_lskel.c\n@@ -36,7 +36,7 @@ static void __test_callx_rodata_lskel(void)\n \tif (!ASSERT_OK_PTR(skel, \"open\"))\n \t\treturn;\n \n-\t/* gcc doesn't support indirect calls */\n+\t/* toolchain or JIT can't do callx */\n \tif (skel-\u003erodata-\u003eskip) {\n \t\ttest__skip();\n \t\tgoto out;\ndiff --git a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c\nindex e7580b9f0fc2ac..11b7dab77ff7a9 100644\n--- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c\n+++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c\n@@ -31,6 +31,12 @@ static void arena_arg(void)\n \tif (!ASSERT_OK_PTR(skel, \"struct_ops_arena__open_and_load\"))\n \t\treturn;\n \n+\tif (skel-\u003edata-\u003eskip_tests) {\n+\t\tprintf(\"%s:SKIP: no addr_space_cast support in the BPF compiler\\n\", __func__);\n+\t\ttest__skip();\n+\t\tgoto out;\n+\t}\n+\n \tlink = bpf_map__attach_struct_ops(skel-\u003emaps.testmod_arena);\n \tif (!ASSERT_OK_PTR(link, \"attach_struct_ops\"))\n \t\tgoto out;\n@@ -142,6 +148,13 @@ static void arena_member(void)\n \tif (!ASSERT_OK_PTR(skel, \"struct_ops_arena_member__open_and_load\"))\n \t\treturn;\n \n+\tif (skel-\u003edata-\u003eskip_tests) {\n+\t\tprintf(\"%s:SKIP: no addr_space_cast support in the BPF compiler\\n\", __func__);\n+\t\ttest__skip();\n+\t\tstruct_ops_arena_member__destroy(skel);\n+\t\treturn;\n+\t}\n+\n \tattach_and_trigger(skel-\u003emaps.testmod_arena_member, skel-\u003eprogs.trigger);\n \tstruct_ops_arena_member__destroy(skel);\n }\n@@ -186,6 +199,13 @@ static void arena_autobind(void)\n \tassert_prog_map(bpf_program__fd(skel-\u003eprogs.test_arena_cb), info.id, \"test_arena_cb\");\n \tassert_prog_map(bpf_program__fd(skel-\u003eprogs.unrelated), info.id, \"unrelated\");\n \n+\tif (skel-\u003edata-\u003eskip_tests) {\n+\t\tprintf(\"%s:SKIP: no addr_space_cast support in the BPF compiler\\n\", __func__);\n+\t\ttest__skip();\n+\t\tstruct_ops_arena_autobind__destroy(skel);\n+\t\treturn;\n+\t}\n+\n \tattach_and_trigger(skel-\u003emaps.testmod_arena_autobind, skel-\u003eprogs.trigger);\n out:\n \tstruct_ops_arena_autobind__destroy(skel);\n@@ -268,6 +288,13 @@ static void arena_member_render(void)\n \tif (!ASSERT_OK_PTR(skel, \"struct_ops_arena_member_render__open_and_load\"))\n \t\treturn;\n \n+\tif (skel-\u003edata-\u003eskip_tests) {\n+\t\tprintf(\"%s:SKIP: no addr_space_cast support in the BPF compiler\\n\", __func__);\n+\t\ttest__skip();\n+\t\tstruct_ops_arena_member_render__destroy(skel);\n+\t\treturn;\n+\t}\n+\n \tattach_and_trigger(skel-\u003emaps.testmod_arena_member_render, skel-\u003eprogs.trigger);\n \tstruct_ops_arena_member_render__destroy(skel);\n }\ndiff --git a/tools/testing/selftests/bpf/progs/arena_kfunc.c b/tools/testing/selftests/bpf/progs/arena_kfunc.c\nindex 5d1cb1a7e8ee4e..757aa061857176 100644\n--- a/tools/testing/selftests/bpf/progs/arena_kfunc.c\n+++ b/tools/testing/selftests/bpf/progs/arena_kfunc.c\n@@ -29,9 +29,9 @@ SEC(\"syscall\")\n __arch_x86_64\n __arch_arm64\n __success __retval(0)\n+__skip_without_arena\n int arena_arg_forms(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tu64 __arena *val;\n \tu64 ret;\n \n@@ -59,7 +59,6 @@ int arena_arg_forms(void *ctx)\n \t\treturn 4;\n \n \tbpf_arena_free_pages(\u0026arena, (void __arena *)val, 1);\n-#endif\n \treturn 0;\n }\n \n@@ -75,7 +74,6 @@ __arch_arm64\n __success __retval(0)\n int arena_arg_rebase(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tu64 __arena *val;\n \tu64 base, off;\n \n@@ -107,7 +105,6 @@ int arena_arg_rebase(void *ctx)\n \t\treturn 7;\n \n \tbpf_arena_free_pages(\u0026arena, (void __arena *)val, 1);\n-#endif\n \treturn 0;\n }\n \n@@ -115,9 +112,9 @@ SEC(\"syscall\")\n __arch_x86_64\n __arch_arm64\n __success __retval(0)\n+__skip_without_arena\n int arena_args5(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tu64 __arena *val;\n \n \tval = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n@@ -139,7 +136,6 @@ int arena_args5(void *ctx)\n \t\treturn 3;\n \n \tbpf_arena_free_pages(\u0026arena, (void __arena *)val, 1);\n-#endif\n \treturn 0;\n }\n \n@@ -147,9 +143,9 @@ SEC(\"syscall\")\n __arch_x86_64\n __arch_arm64\n __success __retval(0)\n+__skip_without_arena\n int arena_arg_mixed(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tu64 __arena *val;\n \n \tval = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n@@ -166,7 +162,6 @@ int arena_arg_mixed(void *ctx)\n \t\treturn 3;\n \n \tbpf_arena_free_pages(\u0026arena, (void __arena *)val, 1);\n-#endif\n \treturn 0;\n }\n \n@@ -177,7 +172,6 @@ __arch_arm64\n __success __retval(0)\n int arena_arg_unpopulated(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tu64 __arena *val;\n \n \tval = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n@@ -188,7 +182,6 @@ int arena_arg_unpopulated(void *ctx)\n \tbpf_kfunc_arena_arg_test((u64 *)stash);\n \n \tbpf_arena_free_pages(\u0026arena, (void __arena *)val, 1);\n-#endif\n \treturn 0;\n }\n \n@@ -220,9 +213,9 @@ SEC(\"syscall\")\n __arch_x86_64\n __arch_arm64\n __success __retval(0)\n+__skip_without_arena\n int arena_arg_subprog(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tu64 __arena *val;\n \tint ret;\n \n@@ -238,9 +231,6 @@ int arena_arg_subprog(void *ctx)\n \n \tbpf_arena_free_pages(\u0026arena, (void __arena *)val, 1);\n \treturn ret;\n-#else\n-\treturn 0;\n-#endif\n }\n \n SEC(\"syscall\")\ndiff --git a/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c b/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c\nindex b5a01cbc33a735..97912a7b6b5e54 100644\n--- a/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c\n+++ b/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c\n@@ -112,6 +112,15 @@ int arena_arg_jit_args5(void *ctx)\n \t\t\t\t (u64 *)\u0026val[4]);\n \treturn 0;\n }\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n+\treturn 0;\n+}\n \n #endif /* __BPF_FEATURE_ADDR_SPACE_CAST */\n \ndiff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h\nindex d7f706c3bc4af0..ed1ed1b5bd0977 100644\n--- a/tools/testing/selftests/bpf/progs/bpf_misc.h\n+++ b/tools/testing/selftests/bpf/progs/bpf_misc.h\n@@ -116,6 +116,10 @@\n * feature the toolchain or JIT cannot provide, so a run does\n * not report OK for coverage it never executed.\n *\n+ * __skip_without_arena\n+ * __skip() with a fixed reason when the compiler cannot do\n+ * the arena address space, nothing otherwise.\n+ *\n * __log_level Log level to use for the program, numeric value expected.\n *\n * __flag Adds one flag use for the program, the following values are valid:\n@@ -156,6 +160,16 @@\n #define __success\t\t__test_tag(\"test_expect_success\")\n #define __description(desc)\t__test_tag(\"test_description=\" desc)\n #define __skip(reason)\t\t__test_tag(\"test_skip=\" reason)\n+\n+/*\n+ * Without compiler arena support, report the test as SKIP rather than let it\n+ * pass vacuously or fail to load.\n+ */\n+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST\n+#define __skip_without_arena\n+#else\n+#define __skip_without_arena\t__skip(\"compiler does not support the arena address space\")\n+#endif\n #define __msg_unpriv(msg)\t__test_tag(\"test_expect_msg_unpriv=\" msg)\n #define __not_msg_unpriv(msg)\t__test_tag(\"test_expect_not_msg_unpriv=\" msg)\n #define __msg_next_unpriv(msg)\t__test_tag(\"test_expect_msg_next_unpriv=\" msg)\n@@ -295,6 +309,13 @@\n #define CAN_USE_LOAD_ACQ_STORE_REL\n #endif\n \n+/* clang always emits callx, gcc only when it defines __BPF_FEATURE_CALLX */\n+#if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) ||\t\\\n+ (defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026\t\t\\\n+\t(defined(__clang__) || defined(__BPF_FEATURE_CALLX))\n+#define CAN_USE_CALLX\n+#endif\n+\n #if defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86)\n #define SPEC_V1\n #endif\ndiff --git a/tools/testing/selftests/bpf/progs/callx_rodata.c b/tools/testing/selftests/bpf/progs/callx_rodata.c\nindex e3f8335f80f851..8c28f01b7113a0 100644\n--- a/tools/testing/selftests/bpf/progs/callx_rodata.c\n+++ b/tools/testing/selftests/bpf/progs/callx_rodata.c\n@@ -4,13 +4,14 @@\n #include \u003cstdbool.h\u003e\n #include \u003clinux/bpf.h\u003e\n #include \u003cbpf/bpf_helpers.h\u003e\n+#include \"bpf_misc.h\"\n \n /* set by user space before the programs are loaded, it's in .rodata too */\n const volatile int bias = 1;\n \n int op_idx;\n \n-#ifdef __clang__\n+#ifdef CAN_USE_CALLX\n \n const volatile bool skip = false;\n \n@@ -48,7 +49,6 @@ int both_ops(void *ctx)\n \n #else\n \n-/* gcc doesn't support indirect calls */\n const volatile bool skip = true;\n \n SEC(\"socket\")\ndiff --git a/tools/testing/selftests/bpf/progs/compute_live_registers.c b/tools/testing/selftests/bpf/progs/compute_live_registers.c\nindex 1ff24bbc7beb79..e0543160035804 100644\n--- a/tools/testing/selftests/bpf/progs/compute_live_registers.c\n+++ b/tools/testing/selftests/bpf/progs/compute_live_registers.c\n@@ -403,6 +403,16 @@ __naked void addr_space_cast(void)\n \t\t __imm_addr(arena)\n \t\t: __clobber_all);\n }\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n+\treturn 0;\n+}\n+\n #endif\n \n static __used __naked int aux1(void)\ndiff --git a/tools/testing/selftests/bpf/progs/jit_insns_arena.c b/tools/testing/selftests/bpf/progs/jit_insns_arena.c\nindex 95736eae2a5884..ccda60e9652430 100644\n--- a/tools/testing/selftests/bpf/progs/jit_insns_arena.c\n+++ b/tools/testing/selftests/bpf/progs/jit_insns_arena.c\n@@ -106,6 +106,16 @@ int cast_to_user(void *ctx)\n \t: \"r1\", \"r2\", \"r7\", \"r9\");\n \treturn res != 0;\n }\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n+\treturn 0;\n+}\n+\n #endif\n \n char _license[] SEC(\"license\") = \"GPL\";\ndiff --git a/tools/testing/selftests/bpf/progs/stream.c b/tools/testing/selftests/bpf/progs/stream.c\nindex 1ae015c4e6b4cc..dc56779cac062d 100644\n--- a/tools/testing/selftests/bpf/progs/stream.c\n+++ b/tools/testing/selftests/bpf/progs/stream.c\n@@ -5,7 +5,6 @@\n #include \u003cbpf/bpf_helpers.h\u003e\n #include \"bpf_misc.h\"\n #include \"bpf_experimental.h\"\n-#include \u003cbpf_arena_common.h\u003e\n \n struct arr_elem {\n \tstruct bpf_res_spin_lock lock;\n@@ -381,9 +380,10 @@ int stream_arena_cmpxchg_fault(void *ctx)\n \n static __noinline void subprog(void)\n {\n-\tint __arena *addr = (int __arena *)0xdeadbeef;\n+\tint *addr = (int *)0xdeadbeef;\n \n \tarena_ptr = \u0026arena;\n+\tbpf_addr_space_cast(addr, 0, 1);\n \t*addr = 1;\n }\n \n@@ -404,9 +404,10 @@ int stream_arena_subprog_fault(void *ctx)\n \n static __noinline int timer_cb(void *map, int *key, struct bpf_timer *timer)\n {\n-\tint __arena *addr = (int __arena *)0xdeadbeef;\n+\tint *addr = (int *)0xdeadbeef;\n \n \tarena_ptr = \u0026arena;\n+\tbpf_addr_space_cast(addr, 0, 1);\n \t*addr = 1;\n \treturn 0;\n }\ndiff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena.c b/tools/testing/selftests/bpf/progs/struct_ops_arena.c\nindex 8aa8639df91f01..612ca868c8fec1 100644\n--- a/tools/testing/selftests/bpf/progs/struct_ops_arena.c\n+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena.c\n@@ -83,6 +83,16 @@ struct bpf_testmod_ops3 testmod_arena = {\n \t.test_arena_multislot = (void *)test_arena_multislot_cb,\n };\n \n+/*\n+ * These tests are not driven by test_loader, so __skip_without_arena\n+ * cannot reach them; the host side reads this flag and skips instead.\n+ */\n+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST\n+bool skip_tests __attribute((__section__(\".data\"))) = false;\n+#else\n+bool skip_tests = true;\n+#endif\n+\n SEC(\"syscall\")\n int trigger(void *ctx)\n {\ndiff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c b/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c\nindex 495faa0f4a8b89..de026d901dcb71 100644\n--- a/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c\n+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c\n@@ -42,6 +42,16 @@ int unrelated(void *ctx)\n \treturn 0;\n }\n \n+/*\n+ * These tests are not driven by test_loader, so __skip_without_arena\n+ * cannot reach them; the host side reads this flag and skips instead.\n+ */\n+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST\n+bool skip_tests __attribute((__section__(\".data\"))) = false;\n+#else\n+bool skip_tests = true;\n+#endif\n+\n SEC(\"syscall\")\n int trigger(void *ctx)\n {\ndiff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c b/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c\nindex a2218cd8161976..4ec0aead3e959a 100644\n--- a/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c\n+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c\n@@ -77,6 +77,16 @@ struct bpf_testmod_ops3 testmod_arena_member = {\n \t.test_arena_member = (void *)test_arena_member_cb,\n };\n \n+/*\n+ * These tests are not driven by test_loader, so __skip_without_arena\n+ * cannot reach them; the host side reads this flag and skips instead.\n+ */\n+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST\n+bool skip_tests __attribute((__section__(\".data\"))) = false;\n+#else\n+bool skip_tests = true;\n+#endif\n+\n SEC(\"syscall\")\n int trigger(void *ctx)\n {\ndiff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c b/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c\nindex 09b4c740bdca7f..3ccbc6e716261a 100644\n--- a/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c\n+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c\n@@ -60,6 +60,16 @@ struct bpf_testmod_ops3 testmod_arena_member_render = {\n \t.test_arena_member = (void *)test_arena_member_render_cb,\n };\n \n+/*\n+ * These tests are not driven by test_loader, so __skip_without_arena\n+ * cannot reach them; the host side reads this flag and skips instead.\n+ */\n+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST\n+bool skip_tests __attribute((__section__(\".data\"))) = false;\n+#else\n+bool skip_tests = true;\n+#endif\n+\n SEC(\"syscall\")\n int trigger(void *ctx)\n {\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_arena.c b/tools/testing/selftests/bpf/progs/verifier_arena.c\nindex b17a6dfc100df4..3b13f6aa6b62b6 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_arena.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_arena.c\n@@ -27,9 +27,9 @@ struct {\n \n SEC(\"socket\")\n __success __retval(0)\n+__skip_without_arena\n int basic_alloc1_nosleep(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile int __arena *page1, *page2, *no_page;\n \n \tpage1 = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n@@ -52,15 +52,14 @@ int basic_alloc1_nosleep(void *ctx)\n \t\treturn 6;\n \tif (*page2 != 0 \u0026\u0026 *page2 != 2) /* use-after-free should return 0 or the stored value */\n \t\treturn 7;\n-#endif\n \treturn 0;\n }\n \n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int basic_alloc1(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile int __arena *page1, *page2, *no_page, *page3;\n \n \tpage1 = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n@@ -91,7 +90,6 @@ int basic_alloc1(void *ctx)\n \t\treturn 9;\n \tif (*page1 != 1)\n \t\treturn 10;\n-#endif\n \treturn 0;\n }\n \n@@ -125,9 +123,9 @@ int free_scalar_below_arena(void *ctx)\n \n SEC(\"socket\")\n __success __retval(0)\n+__skip_without_arena\n int basic_alloc2_nosleep(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile char __arena *page1, *page2, *page3, *page4;\n \n \tpage1 = bpf_arena_alloc_pages(\u0026arena, NULL, 2, NUMA_NO_NODE, 0);\n@@ -157,15 +155,14 @@ int basic_alloc2_nosleep(void *ctx)\n \t\treturn 7;\n \tif (*page4 != 0)\n \t\treturn 8;\n-#endif\n \treturn 0;\n }\n \n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int basic_alloc2(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile char __arena *page1, *page2, *page3, *page4;\n \n \tpage1 = bpf_arena_alloc_pages(\u0026arena, NULL, 2, NUMA_NO_NODE, 0);\n@@ -195,7 +192,6 @@ int basic_alloc2(void *ctx)\n \t\treturn 7;\n \tif (*page4 != 0)\n \t\treturn 8;\n-#endif\n \treturn 0;\n }\n \n@@ -233,7 +229,6 @@ SEC(\"socket\")\n __success __retval(0)\n int basic_reserve1_nosleep(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -257,7 +252,6 @@ int basic_reserve1_nosleep(void *ctx)\n \tpage = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n \tif (page)\n \t\treturn 4;\n-#endif\n \treturn 0;\n }\n \n@@ -265,7 +259,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int basic_reserve1(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -289,7 +282,6 @@ int basic_reserve1(void *ctx)\n \tpage = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\n \tif (page)\n \t\treturn 4;\n-#endif\n \treturn 0;\n }\n \n@@ -297,7 +289,6 @@ SEC(\"socket\")\n __success __retval(0)\n int basic_reserve2_nosleep(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -309,7 +300,6 @@ int basic_reserve2_nosleep(void *ctx)\n \tpage = bpf_arena_alloc_pages(\u0026arena, page, 1, NUMA_NO_NODE, 0);\n \tif ((u64)page)\n \t\treturn 2;\n-#endif\n \treturn 0;\n }\n \n@@ -317,7 +307,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int basic_reserve2(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -329,7 +318,6 @@ int basic_reserve2(void *ctx)\n \tpage = bpf_arena_alloc_pages(\u0026arena, page, 1, NUMA_NO_NODE, 0);\n \tif ((u64)page)\n \t\treturn 2;\n-#endif\n \treturn 0;\n }\n \n@@ -338,7 +326,6 @@ SEC(\"socket\")\n __success __retval(0)\n int reserve_twice_nosleep(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -351,7 +338,6 @@ int reserve_twice_nosleep(void *ctx)\n \tret = bpf_arena_reserve_pages(\u0026arena, page, 1);\n \tif (ret != -EBUSY)\n \t\treturn 2;\n-#endif\n \treturn 0;\n }\n \n@@ -359,7 +345,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int reserve_twice(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -372,7 +357,6 @@ int reserve_twice(void *ctx)\n \tret = bpf_arena_reserve_pages(\u0026arena, page, 1);\n \tif (ret != -EBUSY)\n \t\treturn 2;\n-#endif\n \treturn 0;\n }\n \n@@ -381,7 +365,6 @@ SEC(\"socket\")\n __success __retval(0)\n int reserve_invalid_region_nosleep(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -403,7 +386,6 @@ int reserve_invalid_region_nosleep(void *ctx)\n \tret = bpf_arena_reserve_pages(\u0026arena, page, (1ULL \u003c\u003c 32) - 1);\n \tif (ret != -EINVAL)\n \t\treturn 4;\n-#endif\n \treturn 0;\n }\n \n@@ -411,7 +393,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int reserve_invalid_region(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -433,7 +414,6 @@ int reserve_invalid_region(void *ctx)\n \tret = bpf_arena_reserve_pages(\u0026arena, page, (1ULL \u003c\u003c 32) - 1);\n \tif (ret != -EINVAL)\n \t\treturn 4;\n-#endif\n \treturn 0;\n }\n \n@@ -478,7 +458,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int arena_kfuncs_under_bpf_lock(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *page;\n \tint ret;\n \n@@ -503,7 +482,6 @@ int arena_kfuncs_under_bpf_lock(void *ctx)\n \tbpf_arena_free_pages(\u0026arena, page, 1);\n \n \tbpf_spin_unlock(\u0026arena_bpf_test_lock);\n-#endif\n \n \treturn 0;\n }\n@@ -561,53 +539,64 @@ int arena_ptr_add_arena_ptr(void *ctx)\n \treturn 0;\n }\n \n+/*\n+ * Tests that one insn cannot be reached with a register holding a scalar\n+ * on one path and an arena pointer on the other.\n+ */\n SEC(\"syscall\")\n __failure __msg(\"same insn cannot be used with and without arena pointer\")\n-int mixed_arena_scalar_alu64_scalar_first(void *ctx)\n-{\n-\tvolatile register __u64 reg asm(\"r3\");\n-\t__u32 pick_arena = bpf_get_prandom_u32();\n-\n-\treg = 1ULL \u003c\u003c 32;\n-\n-\tif (pick_arena) {\n-\t\tasm volatile (\n-\t\t\t\"r9 = %[arena] ll;\"\n-\t\t\t\"%[reg] = 0;\"\n-\t\t\t\"%[reg] = addr_space_cast(%[reg], 0x0, 0x1);\"\n-\t\t\t: [reg] \"=r\"(reg)\n-\t\t\t: __imm_addr(arena)\n-\t\t\t: \"r9\"\n-\t\t);\n-\t}\n-\n-\treg += 1;\n-\n-\treturn 0;\n+__load_if_JITed()\n+__naked void mixed_arena_scalar_alu64_scalar_first(void)\n+{\n+\t/*\n+\t * The r9 load is never read. libbpf binds the object's arena to\n+\t * every program through fd_array, so the verifier knows about it\n+\t * without this; the load is the fallback for a kernel without\n+\t * fd_array_cnt and for the light skeleton loader.\n+\t */\n+\tasm volatile (\"\t\t\t\t\t\\\n+\tcall %[bpf_get_prandom_u32];\t\t\t\\\n+\tr6 = r0;\t\t\t\t\t\\\n+\tr3 = 1;\t\t\t\t\t\t\\\n+\tr3 \u003c\u003c= 32;\t\t\t\t\t\\\n+\tif w6 == 0 goto 1f;\t\t\t\t\\\n+\tr9 = %[arena] ll;\t\t\t\t\\\n+\tr3 = 0;\t\t\t\t\t\t\\\n+\tr3 = addr_space_cast(r3, 0, 1);\t\t\t\\\n+1:\tr3 += 1;\t\t\t\t\t\\\n+\tr0 = 0;\t\t\t\t\t\t\\\n+\texit;\t\t\t\t\t\t\\\n+\"\t:\n+\t: __imm_addr(arena),\n+\t __imm(bpf_get_prandom_u32)\n+\t: __clobber_all);\n }\n \n+/*\n+ * As mixed_arena_scalar_alu64_scalar_first(), including the r9 load, with\n+ * the arena pointer established first.\n+ */\n SEC(\"syscall\")\n __failure __msg(\"same insn cannot be used with and without arena pointer\")\n-int mixed_arena_scalar_alu64_arena_first(void *ctx)\n+__load_if_JITed()\n+__naked void mixed_arena_scalar_alu64_arena_first(void)\n {\n-\tvolatile register __u64 reg asm(\"r3\");\n-\t__u32 pick_scalar = bpf_get_prandom_u32();\n-\n-\tasm volatile (\n-\t\t\"r9 = %[arena] ll;\"\n-\t\t\"%[reg] = 0;\"\n-\t\t\"%[reg] = addr_space_cast(%[reg], 0x0, 0x1);\"\n-\t\t: [reg] \"=r\"(reg)\n-\t\t: __imm_addr(arena)\n-\t\t: \"r9\"\n-\t);\n-\n-\tif (pick_scalar)\n-\t\treg = 1ULL \u003c\u003c 32;\n-\n-\treg += 1;\n-\n-\treturn 0;\n+\tasm volatile (\"\t\t\t\t\t\\\n+\tcall %[bpf_get_prandom_u32];\t\t\t\\\n+\tr6 = r0;\t\t\t\t\t\\\n+\tr9 = %[arena] ll;\t\t\t\t\\\n+\tr3 = 0;\t\t\t\t\t\t\\\n+\tr3 = addr_space_cast(r3, 0, 1);\t\t\t\\\n+\tif w6 == 0 goto 1f;\t\t\t\t\\\n+\tr3 = 1;\t\t\t\t\t\t\\\n+\tr3 \u003c\u003c= 32;\t\t\t\t\t\\\n+1:\tr3 += 1;\t\t\t\t\t\\\n+\tr0 = 0;\t\t\t\t\t\t\\\n+\texit;\t\t\t\t\t\t\\\n+\"\t:\n+\t: __imm_addr(arena),\n+\t __imm(bpf_get_prandom_u32)\n+\t: __clobber_all);\n }\n \n SEC(\"syscall\")\n@@ -728,6 +717,15 @@ __naked void mixed_arena_stack_atomic(void)\n \t __imm(bpf_get_prandom_u32)\n \t: __clobber_all);\n }\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n+\treturn 0;\n+}\n \n #endif /* defined(__BPF_FEATURE_ADDR_SPACE_CAST) */\n \n@@ -771,6 +769,7 @@ u32 __arena volatile *check_arena_arg_quals2(u32 volatile __arena *arg1, u32 __a\n \n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int check_arena_arg_ret(void *ctx)\n {\n \tu32 __arena *page = bpf_arena_alloc_pages(\u0026arena, NULL, 1, NUMA_NO_NODE, 0);\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c b/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c\nindex 45d364b0bc85d1..31be4c944252aa 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c\n@@ -30,9 +30,9 @@ volatile char __arena global_data[GLOBAL_PAGES][PAGE_SIZE];\n \n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int check_reserve1(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tconst u8 magic = 0x5a;\n \t__u8 __arena *guard, *globals;\n \tvolatile char __arena *ptr;\n@@ -60,7 +60,6 @@ int check_reserve1(void *ctx)\n \t\tif (*ptr != magic)\n \t\t\treturn i + 3;\n \t}\n-#endif\n \treturn 0;\n }\n \n@@ -69,9 +68,9 @@ int check_reserve1(void *ctx)\n */\n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int check_relocation(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tconst u8 magic = 0xfa;\n \tu8 __arena *ptr;\n \n@@ -80,7 +79,6 @@ int check_relocation(void *ctx)\n \tif (*ptr != magic)\n \t\treturn 1;\n \n-#endif\n \treturn 0;\n }\n \ndiff --git a/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c b/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c\nindex b51594dbc0053b..cd48d6bd782e6f 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c\n@@ -30,9 +30,9 @@ char __arena global_data[ARENA_PAGES][PAGE_SIZE];\n \n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int check_reserve2(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvoid __arena *guard;\n \tint ret;\n \n@@ -42,7 +42,6 @@ int check_reserve2(void *ctx)\n \tret = bpf_arena_reserve_pages(\u0026arena, guard, 1);\n \tif (!ret)\n \t\treturn 1;\n-#endif\n \treturn 0;\n }\n \ndiff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c\nindex dbdea14ca76f54..6ef99793cac131 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c\n@@ -22,9 +22,9 @@ struct {\n \n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int big_alloc1(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile char __arena *page1, *page2, *no_page, *page3;\n \tu64 base;\n \n@@ -79,16 +79,15 @@ int big_alloc1(void *ctx)\n \t\treturn 13;\n \tif (*(page2 - PAGE_SIZE) != 0)\n \t\treturn 14;\n-#endif\n \treturn 0;\n }\n \n /* Try to access a reserved page. Behavior should be identical with accessing unallocated pages. */\n SEC(\"syscall\")\n __success __retval(0)\n+__skip_without_arena\n int access_reserved(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile char __arena *page;\n \tchar __arena *base;\n \tconst size_t len = 4;\n@@ -118,7 +117,6 @@ int access_reserved(void *ctx)\n \t\tif (*page)\n \t\t\treturn 2 + 2 * i + 1;\n \t}\n-#endif\n \treturn 0;\n }\n \n@@ -127,7 +125,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int request_partially_reserved(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tvolatile char __arena *page;\n \tchar __arena *base;\n \tint ret;\n@@ -142,7 +139,6 @@ int request_partially_reserved(void *ctx)\n \tpage = bpf_arena_alloc_pages(\u0026arena, base, 5, NUMA_NO_NODE, 0);\n \tif ((u64)page != 0ULL)\n \t\treturn 2;\n-#endif\n \treturn 0;\n }\n \n@@ -150,7 +146,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int free_reserved(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *addr;\n \tchar __arena *page;\n \tint ret;\n@@ -177,7 +172,6 @@ int free_reserved(void *ctx)\n \tpage = bpf_arena_alloc_pages(\u0026arena, addr + __PAGE_SIZE, 2, NUMA_NO_NODE, 0);\n \tif (!page)\n \t\treturn 3;\n-#endif\n \treturn 0;\n }\n \n@@ -292,7 +286,6 @@ SEC(\"socket\")\n __success __retval(0)\n int big_alloc3(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *pages;\n \tu64 i;\n \tint err = 0;\n@@ -314,8 +307,6 @@ int big_alloc3(void *ctx)\n \n \tbpf_arena_free_pages(\u0026arena, pages, LARGE_PAGE_CNT);\n \treturn err;\n-#endif\n-\treturn 0;\n }\n \n /* SYSCALL programs are always sleepable. */\n@@ -323,7 +314,6 @@ SEC(\"syscall\")\n __success __retval(0)\n int big_alloc4(void *ctx)\n {\n-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)\n \tchar __arena *pages;\n \tu64 i;\n \tint err = 0;\n@@ -345,8 +335,16 @@ int big_alloc4(void *ctx)\n \n \tbpf_arena_free_pages(\u0026arena, pages, LARGE_PAGE_CNT);\n \treturn err;\n-#endif\n+}\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n \treturn 0;\n }\n+\n #endif\n char _license[] SEC(\"license\") = \"GPL\";\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_callx.c b/tools/testing/selftests/bpf/progs/verifier_callx.c\nindex 7e59188d9fca96..ca1aef34ab7287 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_callx.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_callx.c\n@@ -6,9 +6,7 @@\n #include \"bpf_misc.h\"\n #include \"../../../include/linux/filter.h\"\n \n-/* gcc doesn't support indirect calls */\n-#if defined(__clang__) \u0026\u0026 (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n- (defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64))\n+#ifdef CAN_USE_CALLX\n \n #define CALLX_INSN(DST, SRC, OFF, IMM) \\\n \tBPF_RAW_INSN(BPF_JMP | BPF_CALL | BPF_X, DST, SRC, OFF, IMM)\n@@ -1075,6 +1073,7 @@ int callx_c_ops_on_stack(void *ctx)\n #else\n \n SEC(\"socket\")\n+__skip(\"callx needs arch JIT and compiler support\")\n __success\n int dummy(void *ctx)\n {\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c b/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c\nindex b2ee0c8e042bbc..642071fa749831 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_callx_rodata.c\n@@ -6,9 +6,7 @@\n #include \"bpf_misc.h\"\n #include \"../../../include/linux/filter.h\"\n \n-/* gcc doesn't support indirect calls */\n-#if defined(__clang__) \u0026\u0026 (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n- (defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64))\n+#ifdef CAN_USE_CALLX\n \n /*\n * Read-only data with pointers to functions, where the compiler puts tables\n@@ -992,6 +990,7 @@ int callx_c_packed_struct(void *ctx)\n #else\n \n SEC(\"socket\")\n+__skip(\"callx needs arch JIT and compiler support\")\n __success\n int dummy(void *ctx)\n {\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_ldsx.c b/tools/testing/selftests/bpf/progs/verifier_ldsx.c\nindex 49e8cd4bb4f996..35b20d0796db2b 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_ldsx.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_ldsx.c\n@@ -450,6 +450,15 @@ void kfunc_root(void)\n {\n \tbpf_arena_alloc_pages(0, 0, 0, 0, 0);\n }\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n+\treturn 0;\n+}\n \n #endif /* __BPF_FEATURE_ADDR_SPACE_CAST */\n \ndiff --git a/tools/testing/selftests/bpf/progs/verifier_zext.c b/tools/testing/selftests/bpf/progs/verifier_zext.c\nindex 572017fe28fbe1..dbfeeea4cf9f78 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_zext.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_zext.c\n@@ -381,6 +381,15 @@ __naked void zext_arena_cmpxchg32(void)\n \t\t BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_1, BPF_REG_2, 0))\n \t: __clobber_all);\n }\n+#else\n+\n+SEC(\"socket\")\n+__skip_without_arena\n+__success\n+int arena_unsupported(void)\n+{\n+\treturn 0;\n+}\n \n #endif\n \n"
} |
| 2/1 | 2026/11/03 17:09 | agent | patch-evaluator |
1mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies only BPF selftests and test build files under tools/testing/selftests/bpf/. These changes do not affect the compiled kernel image (vmlinux) or kernel modules, and are therefore not fuzzed.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.
Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.
Prompt: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 266692487b044af568d80b9006f1762ee168c8a0
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Nov 3 17:09:55 2026 +0000
syz-cluster: applied patch under review
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index c99e0f623e1034..77682bf28c6ece 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -376,7 +376,7 @@ CLANG_TARGET_ARCH = --target=$(notdir $(CROSS_COMPILE:%-=%))
endif
CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH))
-CLANG_CFLAGS = $(CLANG_SYS_INCLUDES)
+CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) $(CLANG_BPF_CFLAGS)
# genkey writes both outputs. Pattern rules group them even on make
# versions before 4.3, preventing concurrent genkey invocations.
@@ -511,7 +511,7 @@ BINARY := test_progs
BPF_CC := $(CLANG)
BPF_CC_MSG := CLNG-BPF
BPF_SYS_INCLUDES := $(CLANG_SYS_INCLUDES)
-BPF_CC_FLAGS := -O2 $(BPF_TARGET_ENDIAN) -mcpu=v3
+BPF_CC_FLAGS := -O2 $(BPF_TARGET_ENDIAN) -mcpu=v3 $(CLANG_BPF_CFLAGS)
BPF_DEFINES := -DENABLE_ATOMICS_TESTS
include Makefile.skel
@@ -527,12 +527,12 @@ $(OUTPUT)/test_progs: $(RUNNER_PREREQS) $(BPF_OBJS) $(ALL_SKELS) FORCE
$(OUTPUT)/test_progs-no_alu32: $(RUNNER_PREREQS) FORCE
+$(Q)$(RUNNER_MAKE) RUNNER=test_progs FLAVOR=no_alu32 TESTS_DIR=prog_tests \
- $(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v2'
+ $(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v2 $(CLANG_BPF_CFLAGS)'
ifneq ($(CLANG_CPUV4),)
$(OUTPUT)/test_progs-cpuv4: $(RUNNER_PREREQS) FORCE
+$(Q)$(RUNNER_MAKE) RUNNER=test_progs FLAVOR=cpuv4 TESTS_DIR=prog_tests \
- $(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v4' \
+ $(CLANG_RUNNER_ARGS) BPF_CC_FLAGS='-O2 $(BPF_TARGET_ENDIAN) -mcpu=v4 $(CLANG_BPF_CFLAGS)' \
BPF_DEFINES=-DENABLE_ATOMICS_TESTS
endif
diff --git a/tools/testing/selftests/bpf/Makefile.buildvars b/tools/testing/selftests/bpf/Makefile.buildvars
index d2a0c0031b87d5..4d25a736376ca0 100644
--- a/tools/testing/selftests/bpf/Makefile.buildvars
+++ b/tools/testing/selftests/bpf/Makefile.buildvars
@@ -132,13 +132,15 @@ BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN) \
-I$(abspath $(OUTPUT)/../usr/include) \
-std=gnu11 \
-fno-strict-aliasing \
- -Wno-microsoft-anon-tag \
-fms-extensions \
-Wno-compare-distinct-pointer-types \
- -Wno-initializer-overrides \
#
# TODO: enable me -Wsign-compare
+# Warning flags that only clang has. GCC accepts an unknown -Wno-foo
+# silently and then notes it on the next diagnostic it emits.
+CLANG_BPF_CFLAGS := -Wno-microsoft-anon-tag -Wno-initializer-overrides
+
VERIFY_SIG_SETUP := $(CURDIR)/verify_sig_setup.sh
VERIFICATION_CERT := $(BUILD_DIR)/signing_key.der
PRIVATE_KEY := $(BUILD_DIR)/signing_key.pem
diff --git a/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h b/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h
index 82aafe879fae26..4f2c6050215fcd 100644
--- a/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h
+++ b/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h
@@ -49,7 +49,23 @@ void __arena* bpf_arena_alloc_pages(void *map, void __arena *addr, __u32 page_cn
int bpf_arena_reserve_pages(void *map, void __arena *addr, __u32 page_cnt) __ksym __weak;
void bpf_arena_free_pages(void *map, void __arena *ptr, __u32 page_cnt) __ksym __weak;
+/*
+ * GCC's -Warray-bounds fires on the member access: the map definition the
+ * object file carries is smaller than struct bpf_arena. Make the pointer
+ * opaque to it, as the open-coded form in progs/stream.c already does.
+ * clang does not warn and does not need the barrier, which costs a reload
+ * of the map address at every call site.
+ */
+#ifdef __clang__
#define arena_base(map) ((void __arena *)((struct bpf_arena *)(map))->user_vm_start)
+#else
+#define arena_base(map) \
+({ \
+ struct bpf_arena *__ma = (void *)(map); \
+ barrier_var(__ma); \
+ (void __arena *)__ma->user_vm_start; \
+})
+#endif
#else /* when compiled as user space code */
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 f6ef67c3141ee8..acd821fb568f53 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/prog_tests/test_struct_ops_arena.c b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c
index e7580b9f0fc2ac..11b7dab77ff7a9 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_struct_ops_arena.c
@@ -31,6 +31,12 @@ static void arena_arg(void)
if (!ASSERT_OK_PTR(skel, "struct_ops_arena__open_and_load"))
return;
+ if (skel->data->skip_tests) {
+ printf("%s:SKIP: no addr_space_cast support in the BPF compiler\n", __func__);
+ test__skip();
+ goto out;
+ }
+
link = bpf_map__attach_struct_ops(skel->maps.testmod_arena);
if (!ASSERT_OK_PTR(link, "attach_struct_ops"))
goto out;
@@ -142,6 +148,13 @@ static void arena_member(void)
if (!ASSERT_OK_PTR(skel, "struct_ops_arena_member__open_and_load"))
return;
+ if (skel->data->skip_tests) {
+ printf("%s:SKIP: no addr_space_cast support in the BPF compiler\n", __func__);
+ test__skip();
+ struct_ops_arena_member__destroy(skel);
+ return;
+ }
+
attach_and_trigger(skel->maps.testmod_arena_member, skel->progs.trigger);
struct_ops_arena_member__destroy(skel);
}
@@ -186,6 +199,13 @@ static void arena_autobind(void)
assert_prog_map(bpf_program__fd(skel->progs.test_arena_cb), info.id, "test_arena_cb");
assert_prog_map(bpf_program__fd(skel->progs.unrelated), info.id, "unrelated");
+ if (skel->data->skip_tests) {
+ printf("%s:SKIP: no addr_space_cast support in the BPF compiler\n", __func__);
+ test__skip();
+ struct_ops_arena_autobind__destroy(skel);
+ return;
+ }
+
attach_and_trigger(skel->maps.testmod_arena_autobind, skel->progs.trigger);
out:
struct_ops_arena_autobind__destroy(skel);
@@ -268,6 +288,13 @@ static void arena_member_render(void)
if (!ASSERT_OK_PTR(skel, "struct_ops_arena_member_render__open_and_load"))
return;
+ if (skel->data->skip_tests) {
+ printf("%s:SKIP: no addr_space_cast support in the BPF compiler\n", __func__);
+ test__skip();
+ struct_ops_arena_member_render__destroy(skel);
+ return;
+ }
+
attach_and_trigger(skel->maps.testmod_arena_member_render, skel->progs.trigger);
struct_ops_arena_member_render__destroy(skel);
}
diff --git a/tools/testing/selftests/bpf/progs/arena_kfunc.c b/tools/testing/selftests/bpf/progs/arena_kfunc.c
index 5d1cb1a7e8ee4e..757aa061857176 100644
--- a/tools/testing/selftests/bpf/progs/arena_kfunc.c
+++ b/tools/testing/selftests/bpf/progs/arena_kfunc.c
@@ -29,9 +29,9 @@ SEC("syscall")
__arch_x86_64
__arch_arm64
__success __retval(0)
+__skip_without_arena
int arena_arg_forms(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
u64 __arena *val;
u64 ret;
@@ -59,7 +59,6 @@ int arena_arg_forms(void *ctx)
return 4;
bpf_arena_free_pages(&arena, (void __arena *)val, 1);
-#endif
return 0;
}
@@ -75,7 +74,6 @@ __arch_arm64
__success __retval(0)
int arena_arg_rebase(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
u64 __arena *val;
u64 base, off;
@@ -107,7 +105,6 @@ int arena_arg_rebase(void *ctx)
return 7;
bpf_arena_free_pages(&arena, (void __arena *)val, 1);
-#endif
return 0;
}
@@ -115,9 +112,9 @@ SEC("syscall")
__arch_x86_64
__arch_arm64
__success __retval(0)
+__skip_without_arena
int arena_args5(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
u64 __arena *val;
val = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
@@ -139,7 +136,6 @@ int arena_args5(void *ctx)
return 3;
bpf_arena_free_pages(&arena, (void __arena *)val, 1);
-#endif
return 0;
}
@@ -147,9 +143,9 @@ SEC("syscall")
__arch_x86_64
__arch_arm64
__success __retval(0)
+__skip_without_arena
int arena_arg_mixed(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
u64 __arena *val;
val = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
@@ -166,7 +162,6 @@ int arena_arg_mixed(void *ctx)
return 3;
bpf_arena_free_pages(&arena, (void __arena *)val, 1);
-#endif
return 0;
}
@@ -177,7 +172,6 @@ __arch_arm64
__success __retval(0)
int arena_arg_unpopulated(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
u64 __arena *val;
val = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
@@ -188,7 +182,6 @@ int arena_arg_unpopulated(void *ctx)
bpf_kfunc_arena_arg_test((u64 *)stash);
bpf_arena_free_pages(&arena, (void __arena *)val, 1);
-#endif
return 0;
}
@@ -220,9 +213,9 @@ SEC("syscall")
__arch_x86_64
__arch_arm64
__success __retval(0)
+__skip_without_arena
int arena_arg_subprog(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
u64 __arena *val;
int ret;
@@ -238,9 +231,6 @@ int arena_arg_subprog(void *ctx)
bpf_arena_free_pages(&arena, (void __arena *)val, 1);
return ret;
-#else
- return 0;
-#endif
}
SEC("syscall")
diff --git a/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c b/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c
index b5a01cbc33a735..97912a7b6b5e54 100644
--- a/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c
+++ b/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c
@@ -112,6 +112,15 @@ int arena_arg_jit_args5(void *ctx)
(u64 *)&val[4]);
return 0;
}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
+ return 0;
+}
#endif /* __BPF_FEATURE_ADDR_SPACE_CAST */
diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h
index d7f706c3bc4af0..ed1ed1b5bd0977 100644
--- a/tools/testing/selftests/bpf/progs/bpf_misc.h
+++ b/tools/testing/selftests/bpf/progs/bpf_misc.h
@@ -116,6 +116,10 @@
* feature the toolchain or JIT cannot provide, so a run does
* not report OK for coverage it never executed.
*
+ * __skip_without_arena
+ * __skip() with a fixed reason when the compiler cannot do
+ * the arena address space, nothing otherwise.
+ *
* __log_level Log level to use for the program, numeric value expected.
*
* __flag Adds one flag use for the program, the following values are valid:
@@ -156,6 +160,16 @@
#define __success __test_tag("test_expect_success")
#define __description(desc) __test_tag("test_description=" desc)
#define __skip(reason) __test_tag("test_skip=" reason)
+
+/*
+ * Without compiler arena support, report the test as SKIP rather than let it
+ * pass vacuously or fail to load.
+ */
+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST
+#define __skip_without_arena
+#else
+#define __skip_without_arena __skip("compiler does not support the arena address space")
+#endif
#define __msg_unpriv(msg) __test_tag("test_expect_msg_unpriv=" msg)
#define __not_msg_unpriv(msg) __test_tag("test_expect_not_msg_unpriv=" msg)
#define __msg_next_unpriv(msg) __test_tag("test_expect_msg_next_unpriv=" msg)
@@ -295,6 +309,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 e3f8335f80f851..8c28f01b7113a0 100644
--- a/tools/testing/selftests/bpf/progs/callx_rodata.c
+++ b/tools/testing/selftests/bpf/progs/callx_rodata.c
@@ -4,13 +4,14 @@
#include <stdbool.h>
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
+#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/compute_live_registers.c b/tools/testing/selftests/bpf/progs/compute_live_registers.c
index 1ff24bbc7beb79..e0543160035804 100644
--- a/tools/testing/selftests/bpf/progs/compute_live_registers.c
+++ b/tools/testing/selftests/bpf/progs/compute_live_registers.c
@@ -403,6 +403,16 @@ __naked void addr_space_cast(void)
__imm_addr(arena)
: __clobber_all);
}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
+ return 0;
+}
+
#endif
static __used __naked int aux1(void)
diff --git a/tools/testing/selftests/bpf/progs/jit_insns_arena.c b/tools/testing/selftests/bpf/progs/jit_insns_arena.c
index 95736eae2a5884..ccda60e9652430 100644
--- a/tools/testing/selftests/bpf/progs/jit_insns_arena.c
+++ b/tools/testing/selftests/bpf/progs/jit_insns_arena.c
@@ -106,6 +106,16 @@ int cast_to_user(void *ctx)
: "r1", "r2", "r7", "r9");
return res != 0;
}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
+ return 0;
+}
+
#endif
char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/stream.c b/tools/testing/selftests/bpf/progs/stream.c
index 1ae015c4e6b4cc..dc56779cac062d 100644
--- a/tools/testing/selftests/bpf/progs/stream.c
+++ b/tools/testing/selftests/bpf/progs/stream.c
@@ -5,7 +5,6 @@
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "bpf_experimental.h"
-#include <bpf_arena_common.h>
struct arr_elem {
struct bpf_res_spin_lock lock;
@@ -381,9 +380,10 @@ int stream_arena_cmpxchg_fault(void *ctx)
static __noinline void subprog(void)
{
- int __arena *addr = (int __arena *)0xdeadbeef;
+ int *addr = (int *)0xdeadbeef;
arena_ptr = &arena;
+ bpf_addr_space_cast(addr, 0, 1);
*addr = 1;
}
@@ -404,9 +404,10 @@ int stream_arena_subprog_fault(void *ctx)
static __noinline int timer_cb(void *map, int *key, struct bpf_timer *timer)
{
- int __arena *addr = (int __arena *)0xdeadbeef;
+ int *addr = (int *)0xdeadbeef;
arena_ptr = &arena;
+ bpf_addr_space_cast(addr, 0, 1);
*addr = 1;
return 0;
}
diff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena.c b/tools/testing/selftests/bpf/progs/struct_ops_arena.c
index 8aa8639df91f01..612ca868c8fec1 100644
--- a/tools/testing/selftests/bpf/progs/struct_ops_arena.c
+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena.c
@@ -83,6 +83,16 @@ struct bpf_testmod_ops3 testmod_arena = {
.test_arena_multislot = (void *)test_arena_multislot_cb,
};
+/*
+ * These tests are not driven by test_loader, so __skip_without_arena
+ * cannot reach them; the host side reads this flag and skips instead.
+ */
+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST
+bool skip_tests __attribute((__section__(".data"))) = false;
+#else
+bool skip_tests = true;
+#endif
+
SEC("syscall")
int trigger(void *ctx)
{
diff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c b/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c
index 495faa0f4a8b89..de026d901dcb71 100644
--- a/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c
+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena_autobind.c
@@ -42,6 +42,16 @@ int unrelated(void *ctx)
return 0;
}
+/*
+ * These tests are not driven by test_loader, so __skip_without_arena
+ * cannot reach them; the host side reads this flag and skips instead.
+ */
+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST
+bool skip_tests __attribute((__section__(".data"))) = false;
+#else
+bool skip_tests = true;
+#endif
+
SEC("syscall")
int trigger(void *ctx)
{
diff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c b/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c
index a2218cd8161976..4ec0aead3e959a 100644
--- a/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c
+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena_member.c
@@ -77,6 +77,16 @@ struct bpf_testmod_ops3 testmod_arena_member = {
.test_arena_member = (void *)test_arena_member_cb,
};
+/*
+ * These tests are not driven by test_loader, so __skip_without_arena
+ * cannot reach them; the host side reads this flag and skips instead.
+ */
+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST
+bool skip_tests __attribute((__section__(".data"))) = false;
+#else
+bool skip_tests = true;
+#endif
+
SEC("syscall")
int trigger(void *ctx)
{
diff --git a/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c b/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c
index 09b4c740bdca7f..3ccbc6e716261a 100644
--- a/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c
+++ b/tools/testing/selftests/bpf/progs/struct_ops_arena_member_render.c
@@ -60,6 +60,16 @@ struct bpf_testmod_ops3 testmod_arena_member_render = {
.test_arena_member = (void *)test_arena_member_render_cb,
};
+/*
+ * These tests are not driven by test_loader, so __skip_without_arena
+ * cannot reach them; the host side reads this flag and skips instead.
+ */
+#ifdef __BPF_FEATURE_ADDR_SPACE_CAST
+bool skip_tests __attribute((__section__(".data"))) = false;
+#else
+bool skip_tests = true;
+#endif
+
SEC("syscall")
int trigger(void *ctx)
{
diff --git a/tools/testing/selftests/bpf/progs/verifier_arena.c b/tools/testing/selftests/bpf/progs/verifier_arena.c
index b17a6dfc100df4..3b13f6aa6b62b6 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena.c
@@ -27,9 +27,9 @@ struct {
SEC("socket")
__success __retval(0)
+__skip_without_arena
int basic_alloc1_nosleep(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile int __arena *page1, *page2, *no_page;
page1 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
@@ -52,15 +52,14 @@ int basic_alloc1_nosleep(void *ctx)
return 6;
if (*page2 != 0 && *page2 != 2) /* use-after-free should return 0 or the stored value */
return 7;
-#endif
return 0;
}
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int basic_alloc1(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile int __arena *page1, *page2, *no_page, *page3;
page1 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
@@ -91,7 +90,6 @@ int basic_alloc1(void *ctx)
return 9;
if (*page1 != 1)
return 10;
-#endif
return 0;
}
@@ -125,9 +123,9 @@ int free_scalar_below_arena(void *ctx)
SEC("socket")
__success __retval(0)
+__skip_without_arena
int basic_alloc2_nosleep(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile char __arena *page1, *page2, *page3, *page4;
page1 = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0);
@@ -157,15 +155,14 @@ int basic_alloc2_nosleep(void *ctx)
return 7;
if (*page4 != 0)
return 8;
-#endif
return 0;
}
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int basic_alloc2(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile char __arena *page1, *page2, *page3, *page4;
page1 = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0);
@@ -195,7 +192,6 @@ int basic_alloc2(void *ctx)
return 7;
if (*page4 != 0)
return 8;
-#endif
return 0;
}
@@ -233,7 +229,6 @@ SEC("socket")
__success __retval(0)
int basic_reserve1_nosleep(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -257,7 +252,6 @@ int basic_reserve1_nosleep(void *ctx)
page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
if (page)
return 4;
-#endif
return 0;
}
@@ -265,7 +259,6 @@ SEC("syscall")
__success __retval(0)
int basic_reserve1(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -289,7 +282,6 @@ int basic_reserve1(void *ctx)
page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
if (page)
return 4;
-#endif
return 0;
}
@@ -297,7 +289,6 @@ SEC("socket")
__success __retval(0)
int basic_reserve2_nosleep(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -309,7 +300,6 @@ int basic_reserve2_nosleep(void *ctx)
page = bpf_arena_alloc_pages(&arena, page, 1, NUMA_NO_NODE, 0);
if ((u64)page)
return 2;
-#endif
return 0;
}
@@ -317,7 +307,6 @@ SEC("syscall")
__success __retval(0)
int basic_reserve2(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -329,7 +318,6 @@ int basic_reserve2(void *ctx)
page = bpf_arena_alloc_pages(&arena, page, 1, NUMA_NO_NODE, 0);
if ((u64)page)
return 2;
-#endif
return 0;
}
@@ -338,7 +326,6 @@ SEC("socket")
__success __retval(0)
int reserve_twice_nosleep(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -351,7 +338,6 @@ int reserve_twice_nosleep(void *ctx)
ret = bpf_arena_reserve_pages(&arena, page, 1);
if (ret != -EBUSY)
return 2;
-#endif
return 0;
}
@@ -359,7 +345,6 @@ SEC("syscall")
__success __retval(0)
int reserve_twice(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -372,7 +357,6 @@ int reserve_twice(void *ctx)
ret = bpf_arena_reserve_pages(&arena, page, 1);
if (ret != -EBUSY)
return 2;
-#endif
return 0;
}
@@ -381,7 +365,6 @@ SEC("socket")
__success __retval(0)
int reserve_invalid_region_nosleep(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -403,7 +386,6 @@ int reserve_invalid_region_nosleep(void *ctx)
ret = bpf_arena_reserve_pages(&arena, page, (1ULL << 32) - 1);
if (ret != -EINVAL)
return 4;
-#endif
return 0;
}
@@ -411,7 +393,6 @@ SEC("syscall")
__success __retval(0)
int reserve_invalid_region(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -433,7 +414,6 @@ int reserve_invalid_region(void *ctx)
ret = bpf_arena_reserve_pages(&arena, page, (1ULL << 32) - 1);
if (ret != -EINVAL)
return 4;
-#endif
return 0;
}
@@ -478,7 +458,6 @@ SEC("syscall")
__success __retval(0)
int arena_kfuncs_under_bpf_lock(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *page;
int ret;
@@ -503,7 +482,6 @@ int arena_kfuncs_under_bpf_lock(void *ctx)
bpf_arena_free_pages(&arena, page, 1);
bpf_spin_unlock(&arena_bpf_test_lock);
-#endif
return 0;
}
@@ -561,53 +539,64 @@ int arena_ptr_add_arena_ptr(void *ctx)
return 0;
}
+/*
+ * Tests that one insn cannot be reached with a register holding a scalar
+ * on one path and an arena pointer on the other.
+ */
SEC("syscall")
__failure __msg("same insn cannot be used with and without arena pointer")
-int mixed_arena_scalar_alu64_scalar_first(void *ctx)
-{
- volatile register __u64 reg asm("r3");
- __u32 pick_arena = bpf_get_prandom_u32();
-
- reg = 1ULL << 32;
-
- if (pick_arena) {
- asm volatile (
- "r9 = %[arena] ll;"
- "%[reg] = 0;"
- "%[reg] = addr_space_cast(%[reg], 0x0, 0x1);"
- : [reg] "=r"(reg)
- : __imm_addr(arena)
- : "r9"
- );
- }
-
- reg += 1;
-
- return 0;
+__load_if_JITed()
+__naked void mixed_arena_scalar_alu64_scalar_first(void)
+{
+ /*
+ * The r9 load is never read. libbpf binds the object's arena to
+ * every program through fd_array, so the verifier knows about it
+ * without this; the load is the fallback for a kernel without
+ * fd_array_cnt and for the light skeleton loader.
+ */
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r6 = r0; \
+ r3 = 1; \
+ r3 <<= 32; \
+ if w6 == 0 goto 1f; \
+ r9 = %[arena] ll; \
+ r3 = 0; \
+ r3 = addr_space_cast(r3, 0, 1); \
+1: r3 += 1; \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm_addr(arena),
+ __imm(bpf_get_prandom_u32)
+ : __clobber_all);
}
+/*
+ * As mixed_arena_scalar_alu64_scalar_first(), including the r9 load, with
+ * the arena pointer established first.
+ */
SEC("syscall")
__failure __msg("same insn cannot be used with and without arena pointer")
-int mixed_arena_scalar_alu64_arena_first(void *ctx)
+__load_if_JITed()
+__naked void mixed_arena_scalar_alu64_arena_first(void)
{
- volatile register __u64 reg asm("r3");
- __u32 pick_scalar = bpf_get_prandom_u32();
-
- asm volatile (
- "r9 = %[arena] ll;"
- "%[reg] = 0;"
- "%[reg] = addr_space_cast(%[reg], 0x0, 0x1);"
- : [reg] "=r"(reg)
- : __imm_addr(arena)
- : "r9"
- );
-
- if (pick_scalar)
- reg = 1ULL << 32;
-
- reg += 1;
-
- return 0;
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r6 = r0; \
+ r9 = %[arena] ll; \
+ r3 = 0; \
+ r3 = addr_space_cast(r3, 0, 1); \
+ if w6 == 0 goto 1f; \
+ r3 = 1; \
+ r3 <<= 32; \
+1: r3 += 1; \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm_addr(arena),
+ __imm(bpf_get_prandom_u32)
+ : __clobber_all);
}
SEC("syscall")
@@ -728,6 +717,15 @@ __naked void mixed_arena_stack_atomic(void)
__imm(bpf_get_prandom_u32)
: __clobber_all);
}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
+ return 0;
+}
#endif /* defined(__BPF_FEATURE_ADDR_SPACE_CAST) */
@@ -771,6 +769,7 @@ u32 __arena volatile *check_arena_arg_quals2(u32 volatile __arena *arg1, u32 __a
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int check_arena_arg_ret(void *ctx)
{
u32 __arena *page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c b/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c
index 45d364b0bc85d1..31be4c944252aa 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c
@@ -30,9 +30,9 @@ volatile char __arena global_data[GLOBAL_PAGES][PAGE_SIZE];
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int check_reserve1(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
const u8 magic = 0x5a;
__u8 __arena *guard, *globals;
volatile char __arena *ptr;
@@ -60,7 +60,6 @@ int check_reserve1(void *ctx)
if (*ptr != magic)
return i + 3;
}
-#endif
return 0;
}
@@ -69,9 +68,9 @@ int check_reserve1(void *ctx)
*/
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int check_relocation(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
const u8 magic = 0xfa;
u8 __arena *ptr;
@@ -80,7 +79,6 @@ int check_relocation(void *ctx)
if (*ptr != magic)
return 1;
-#endif
return 0;
}
diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c b/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c
index b51594dbc0053b..cd48d6bd782e6f 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena_globals2.c
@@ -30,9 +30,9 @@ char __arena global_data[ARENA_PAGES][PAGE_SIZE];
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int check_reserve2(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
void __arena *guard;
int ret;
@@ -42,7 +42,6 @@ int check_reserve2(void *ctx)
ret = bpf_arena_reserve_pages(&arena, guard, 1);
if (!ret)
return 1;
-#endif
return 0;
}
diff --git a/tools/testing/selftests/bpf/progs/verifier_arena_large.c b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
index dbdea14ca76f54..6ef99793cac131 100644
--- a/tools/testing/selftests/bpf/progs/verifier_arena_large.c
+++ b/tools/testing/selftests/bpf/progs/verifier_arena_large.c
@@ -22,9 +22,9 @@ struct {
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int big_alloc1(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile char __arena *page1, *page2, *no_page, *page3;
u64 base;
@@ -79,16 +79,15 @@ int big_alloc1(void *ctx)
return 13;
if (*(page2 - PAGE_SIZE) != 0)
return 14;
-#endif
return 0;
}
/* Try to access a reserved page. Behavior should be identical with accessing unallocated pages. */
SEC("syscall")
__success __retval(0)
+__skip_without_arena
int access_reserved(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile char __arena *page;
char __arena *base;
const size_t len = 4;
@@ -118,7 +117,6 @@ int access_reserved(void *ctx)
if (*page)
return 2 + 2 * i + 1;
}
-#endif
return 0;
}
@@ -127,7 +125,6 @@ SEC("syscall")
__success __retval(0)
int request_partially_reserved(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
volatile char __arena *page;
char __arena *base;
int ret;
@@ -142,7 +139,6 @@ int request_partially_reserved(void *ctx)
page = bpf_arena_alloc_pages(&arena, base, 5, NUMA_NO_NODE, 0);
if ((u64)page != 0ULL)
return 2;
-#endif
return 0;
}
@@ -150,7 +146,6 @@ SEC("syscall")
__success __retval(0)
int free_reserved(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *addr;
char __arena *page;
int ret;
@@ -177,7 +172,6 @@ int free_reserved(void *ctx)
page = bpf_arena_alloc_pages(&arena, addr + __PAGE_SIZE, 2, NUMA_NO_NODE, 0);
if (!page)
return 3;
-#endif
return 0;
}
@@ -292,7 +286,6 @@ SEC("socket")
__success __retval(0)
int big_alloc3(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *pages;
u64 i;
int err = 0;
@@ -314,8 +307,6 @@ int big_alloc3(void *ctx)
bpf_arena_free_pages(&arena, pages, LARGE_PAGE_CNT);
return err;
-#endif
- return 0;
}
/* SYSCALL programs are always sleepable. */
@@ -323,7 +314,6 @@ SEC("syscall")
__success __retval(0)
int big_alloc4(void *ctx)
{
-#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
char __arena *pages;
u64 i;
int err = 0;
@@ -345,8 +335,16 @@ int big_alloc4(void *ctx)
bpf_arena_free_pages(&arena, pages, LARGE_PAGE_CNT);
return err;
-#endif
+}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
return 0;
}
+
#endif
char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/progs/verifier_callx.c b/tools/testing/selftests/bpf/progs/verifier_callx.c
index 7e59188d9fca96..ca1aef34ab7287 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 b2ee0c8e042bbc..642071fa749831 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
@@ -992,6 +990,7 @@ int callx_c_packed_struct(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_ldsx.c b/tools/testing/selftests/bpf/progs/verifier_ldsx.c
index 49e8cd4bb4f996..35b20d0796db2b 100644
--- a/tools/testing/selftests/bpf/progs/verifier_ldsx.c
+++ b/tools/testing/selftests/bpf/progs/verifier_ldsx.c
@@ -450,6 +450,15 @@ void kfunc_root(void)
{
bpf_arena_alloc_pages(0, 0, 0, 0, 0);
}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
+ return 0;
+}
#endif /* __BPF_FEATURE_ADDR_SPACE_CAST */
diff --git a/tools/testing/selftests/bpf/progs/verifier_zext.c b/tools/testing/selftests/bpf/progs/verifier_zext.c
index 572017fe28fbe1..dbfeeea4cf9f78 100644
--- a/tools/testing/selftests/bpf/progs/verifier_zext.c
+++ b/tools/testing/selftests/bpf/progs/verifier_zext.c
@@ -381,6 +381,15 @@ __naked void zext_arena_cmpxchg32(void)
BPF_ATOMIC_OP(BPF_W, BPF_CMPXCHG, BPF_REG_1, BPF_REG_2, 0))
: __clobber_all);
}
+#else
+
+SEC("socket")
+__skip_without_arena
+__success
+int arena_unsupported(void)
+{
+ return 0;
+}
#endif
|
| 3/2 | 2026/11/03 17:09 | llm | patch-evaluator |
1mModel:gemini-3.8-flash Args: null Results: null Tokens: input: 17233 output: 82 thoughts: 1769 Thoughts: **Analysis of the Patch Series for Syzkaller Fuzzing** Okay, let's break this down. My goal is to determine if this patch series is "WorthFuzzing" for Syzkaller. First, I need to understand the scope of the changes. The diff indicates modifications across various files. I see the changes are all within `tools/testing/selftests/bpf/`. That's a key observation. Now, I'm referencing the evaluation criteria, specifically Section 2, the *negative criteria* for "WorthFuzzing". It clearly states that if *all* modified code falls into specific categories, then WorthFuzzing is false. One of those categories is: "User-space directories, self-tests, samples, or scripts... that do not affect the compiled kernel image (vmlinux) or kernel modules". Looking at the list of files again, it's crystal clear: every single file modified is inside `tools/testing/selftests/bpf/`. These are BPF selftests. There's absolutely nothing here that touches core kernel code or modules. I could have run `git diff` or grepped to double check, but the provided list is comprehensive. The prompt confirms this is the complete diff of the changes. Therefore, applying the criteria, the answer is immediately obvious. Since all changes are confined to this userspace selftest directory, and *do not* impact the kernel image or modules, "WorthFuzzing" must be false. Consequently, both `FocusSymbols` and `EnableConfigs` should be empty ( `[]` ). The reasoning is straightforward: All changes are within `tools/testing/selftests/bpf/` and are isolated to selftests, thus falling under the negative criteria. I'm ready to call the `set-results` tool now. |
| 4/2 | 2026/11/03 17:11 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch modifies only BPF selftests and test build files under tools/testing/selftests/bpf/. These changes do not affect the compiled kernel image (vmlinux) or kernel modules, and are therefore not fuzzed.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch modifies only BPF selftests and test build files under tools/testing/selftests/bpf/. These changes do not affect the compiled kernel image (vmlinux) or kernel modules, and are therefore not fuzzed.",
"WorthFuzzing": false
} |
| 5/1 | 2026/11/03 17:11 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|