1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
3
4 /*
5 * Verify the JIT-emitted rebase sequences for __arena and __arena__nullable
6 * kfunc arguments. The capture kfuncs take the argument without
7 * dereferencing it, so these tests pin only the emitted code.
8 */
9 #define BPF_NO_KFUNC_PROTOTYPES
10 #include <vmlinux.h>
11 #include <bpf/bpf_helpers.h>
12 #include "bpf_misc.h"
13 #include "bpf_experimental.h"
14 #include <bpf_arena_common.h>
15 #include "../test_kmods/bpf_testmod_kfunc.h"
16
17 struct {
18 __uint(type, BPF_MAP_TYPE_ARENA);
19 __uint(map_flags, BPF_F_MMAPABLE);
20 __uint(max_entries, 1);
21 } arena SEC(".maps");
22
23 /* volatile to force the scalar reloads below */
24 volatile u64 stash;
25
26 #if defined(__BPF_FEATURE_ADDR_SPACE_CAST)
27
28 SEC("syscall")
29 __arch_x86_64
30 __jited("...")
31 __jited(" movl %edi, %edi")
32 __jited(" addq %r12, %rdi")
33 __jited("...")
34 __jited(" callq {{.*}}")
35 __arch_arm64
36 __jited("...")
37 __jited(" add x0, x28, w0, uxtw")
38 __jited(" {{(bl|mov) .*}}")
39 __success
arena_arg_jit_rebase(void * ctx)40 int arena_arg_jit_rebase(void *ctx)
41 {
42 stash = (u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
43 bpf_kfunc_arena_cap_test((u64 *)stash);
44 return 0;
45 }
46
47 SEC("syscall")
48 __arch_x86_64
49 __jited("...")
50 __jited(" movl %edi, %edi")
51 __jited(" testl %edi, %edi")
52 __jited(" je L0")
53 __jited(" addq %r12, %rdi")
54 __jited("L0: callq {{.*}}")
55 __arch_arm64
56 __jited("...")
57 __jited(" mov w0, w0")
58 __jited(" cbz w0, L0")
59 __jited(" add x0, x28, w0, uxtw")
60 __jited("L0: {{.*}}")
61 __success
arena_arg_jit_nullable(void * ctx)62 int arena_arg_jit_nullable(void *ctx)
63 {
64 stash = (u64)bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
65 bpf_kfunc_arena_cap_nullable_test((u64 *)stash);
66 return 0;
67 }
68
69 SEC("syscall")
70 __arch_x86_64
71 __jited("...")
72 __jited(" movl %edi, %edi")
73 __jited(" addq %r12, %rdi")
74 __jited(" movl %esi, %esi")
75 __jited(" addq %r12, %rsi")
76 __jited(" movl %edx, %edx")
77 __jited(" addq %r12, %rdx")
78 __jited(" movl %ecx, %ecx")
79 __jited(" addq %r12, %rcx")
80 __jited(" movl %r8d, %r8d")
81 __jited(" testl %r8d, %r8d")
82 __jited(" je L0")
83 __jited(" addq %r12, %r8")
84 __jited("L0: callq {{.*}}")
85 __arch_arm64
86 __jited("...")
87 __jited(" add x0, x28, w0, uxtw")
88 __jited(" add x1, x28, w1, uxtw")
89 __jited(" add x2, x28, w2, uxtw")
90 __jited(" add x3, x28, w3, uxtw")
91 __jited(" mov w4, w4")
92 __jited(" cbz w4, L0")
93 __jited(" add x4, x28, w4, uxtw")
94 __jited("L0: {{.*}}")
95 __success
arena_arg_jit_args5(void * ctx)96 int arena_arg_jit_args5(void *ctx)
97 {
98 u64 __arena *val;
99
100 val = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
101 if (!val)
102 return 1;
103
104 val[0] = 1;
105 val[1] = 2;
106 val[2] = 4;
107 val[3] = 8;
108 val[4] = 16;
109
110 bpf_kfunc_arena_args5_test((u64 *)&val[0], (u64 *)&val[1],
111 (u64 *)&val[2], (u64 *)&val[3],
112 (u64 *)&val[4]);
113 return 0;
114 }
115
116 #endif /* __BPF_FEATURE_ADDR_SPACE_CAST */
117
118 char _license[] SEC("license") = "GPL";
119