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>
This commit is contained in:
Tejun Heo
2026-08-08 02:39:29 +02:00
committed by Eduard Zingerman
parent 0996e93691
commit 25818556ed
2 changed files with 101 additions and 0 deletions

View File

@@ -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); }

View File

@@ -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";