summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-08-08 02:39:29 +0200
committerEduard Zingerman <eddyz87@gmail.com>2026-08-08 03:03:26 -0700
commit25818556edcf6cb3c2ef2007f7d137e06877f698 (patch)
tree21eb5fee73053433da601c3d247b5ea1099e75d2 /tools
parent0996e93691f1acbf6660fe51f2a90e0df6799769 (diff)
selftests/bpf: Add JIT-sequence tests for __arena kfunc arguments
Pin the exact rebase sequences the JITs emit for __arena and __arena__nullable kfunc arguments with __jited assertions on x86-64: the unconditional truncate-and-add, the nullable test-and-skip variant, and all five argument registers in one call, which also covers the REX-prefixed encoding of r8 on x86. The capture kfuncs take the argument without dereferencing, so only the emitted code is under test. The tests skip without LLVM disassembler support. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260808003938.3486067-10-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/bpf/prog_tests/verifier.c3
-rw-r--r--tools/testing/selftests/bpf/progs/arena_kfunc_jit.c98
2 files changed, 101 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index 608050c60309..5b265af3b1d5 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -3,6 +3,7 @@
#include <test_progs.h>
#include "arena_kfunc.skel.h"
+#include "arena_kfunc_jit.skel.h"
#include "cap_helpers.h"
#include "verifier_align.skel.h"
#include "verifier_and.skel.h"
@@ -165,6 +166,8 @@ static void run_tests_aux(const char *skel_name,
void test_arena_kfunc(void) { RUN_TESTS(arena_kfunc); }
+void test_arena_kfunc_jit(void) { RUN_TESTS(arena_kfunc_jit); }
+
void test_verifier_align(void) { RUN(verifier_align); }
void test_verifier_and(void) { RUN(verifier_and); }
void test_verifier_arena(void) { RUN(verifier_arena); }
diff --git a/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c b/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c
new file mode 100644
index 000000000000..c9b918662616
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/arena_kfunc_jit.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+
+/*
+ * Verify the JIT-emitted rebase sequences for __arena and __arena__nullable
+ * kfunc arguments. The capture kfuncs take the argument without
+ * dereferencing it, so these tests pin only the emitted code.
+ */
+#define BPF_NO_KFUNC_PROTOTYPES
+#include <vmlinux.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+#include "bpf_experimental.h"
+#include <bpf_arena_common.h>
+#include "../test_kmods/bpf_testmod_kfunc.h"
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARENA);
+ __uint(map_flags, BPF_F_MMAPABLE);
+ __uint(max_entries, 1);
+} arena SEC(".maps");
+
+/* volatile to force the scalar reloads below */
+volatile u64 stash;
+
+#if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
+
+SEC("syscall")
+__arch_x86_64
+__jited("...")
+__jited(" movl %edi, %edi")
+__jited(" addq %r12, %rdi")
+__jited("...")
+__jited(" callq {{.*}}")
+__success
+int arena_arg_jit_rebase(void *ctx)
+{
+ stash = (u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ bpf_kfunc_arena_cap_test((u64 *)stash);
+ return 0;
+}
+
+SEC("syscall")
+__arch_x86_64
+__jited("...")
+__jited(" movl %edi, %edi")
+__jited(" testl %edi, %edi")
+__jited(" je L0")
+__jited(" addq %r12, %rdi")
+__jited("L0: callq {{.*}}")
+__success
+int arena_arg_jit_nullable(void *ctx)
+{
+ stash = (u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ bpf_kfunc_arena_cap_nullable_test((u64 *)stash);
+ return 0;
+}
+
+SEC("syscall")
+__arch_x86_64
+__jited("...")
+__jited(" movl %edi, %edi")
+__jited(" addq %r12, %rdi")
+__jited(" movl %esi, %esi")
+__jited(" addq %r12, %rsi")
+__jited(" movl %edx, %edx")
+__jited(" addq %r12, %rdx")
+__jited(" movl %ecx, %ecx")
+__jited(" addq %r12, %rcx")
+__jited(" movl %r8d, %r8d")
+__jited(" testl %r8d, %r8d")
+__jited(" je L0")
+__jited(" addq %r12, %r8")
+__jited("L0: callq {{.*}}")
+__success
+int arena_arg_jit_args5(void *ctx)
+{
+ u64 __arena *val;
+
+ val = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
+ if (!val)
+ return 1;
+
+ val[0] = 1;
+ val[1] = 2;
+ val[2] = 4;
+ val[3] = 8;
+ val[4] = 16;
+
+ bpf_kfunc_arena_args5_test((u64 *)&val[0], (u64 *)&val[1],
+ (u64 *)&val[2], (u64 *)&val[3],
+ (u64 *)&val[4]);
+ return 0;
+}
+
+#endif /* __BPF_FEATURE_ADDR_SPACE_CAST */
+
+char _license[] SEC("license") = "GPL";