Skip to content

Commit 14a627f

Browse files
Yonghong SongAlexei Starovoitov
authored andcommitted
selftests/bpf: Add some tests related to 'may_goto 0' insns
Add both asm-based and C-based tests which have 'may_goto 0' insns. For the following code in C-based test, int i, tmp[3]; for (i = 0; i < 3 && can_loop; i++) tmp[i] = 0; The clang compiler (clang 19 and 20) generates may_goto 2 may_goto 1 may_goto 0 r1 = 0 r2 = 0 r3 = 0 The above asm codes are due to llvm pass SROAPass. This ensures the successful verification since tmp[0-2] are initialized. Otherwise, the code without SROAPass like may_goto 5 r1 = 0 may_goto 3 r2 = 0 may_goto 1 r3 = 0 will have verification failure. Although from the source code C-based test should have verification failure, clang compiler optimization generates code with successful verification. If gcc generates different asm codes than clang, the following code can be used for gcc: int i, tmp[3]; for (i = 0; i < 3; i++) tmp[i] = 0; Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20250118192034.2124952-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 0c35ca2 commit 14a627f

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

tools/testing/selftests/bpf/prog_tests/verifier.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
#include "verifier_map_ptr_mixing.skel.h"
5353
#include "verifier_map_ret_val.skel.h"
5454
#include "verifier_masking.skel.h"
55+
#include "verifier_may_goto_1.skel.h"
56+
#include "verifier_may_goto_2.skel.h"
5557
#include "verifier_meta_access.skel.h"
5658
#include "verifier_movsx.skel.h"
5759
#include "verifier_mtu.skel.h"
@@ -182,6 +184,8 @@ void test_verifier_map_ptr(void) { RUN(verifier_map_ptr); }
182184
void test_verifier_map_ptr_mixing(void) { RUN(verifier_map_ptr_mixing); }
183185
void test_verifier_map_ret_val(void) { RUN(verifier_map_ret_val); }
184186
void test_verifier_masking(void) { RUN(verifier_masking); }
187+
void test_verifier_may_goto_1(void) { RUN(verifier_may_goto_1); }
188+
void test_verifier_may_goto_2(void) { RUN(verifier_may_goto_2); }
185189
void test_verifier_meta_access(void) { RUN(verifier_meta_access); }
186190
void test_verifier_movsx(void) { RUN(verifier_movsx); }
187191
void test_verifier_netfilter_ctx(void) { RUN(verifier_netfilter_ctx); }
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
3+
4+
#include <linux/bpf.h>
5+
#include <bpf/bpf_helpers.h>
6+
#include "../../../include/linux/filter.h"
7+
#include "bpf_misc.h"
8+
9+
SEC("raw_tp")
10+
__description("may_goto 0")
11+
__arch_x86_64
12+
__xlated("0: r0 = 1")
13+
__xlated("1: exit")
14+
__success
15+
__naked void may_goto_simple(void)
16+
{
17+
asm volatile (
18+
".8byte %[may_goto];"
19+
"r0 = 1;"
20+
".8byte %[may_goto];"
21+
"exit;"
22+
:
23+
: __imm_insn(may_goto, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 0 /* offset */, 0))
24+
: __clobber_all);
25+
}
26+
27+
SEC("raw_tp")
28+
__description("batch 2 of may_goto 0")
29+
__arch_x86_64
30+
__xlated("0: r0 = 1")
31+
__xlated("1: exit")
32+
__success
33+
__naked void may_goto_batch_0(void)
34+
{
35+
asm volatile (
36+
".8byte %[may_goto1];"
37+
".8byte %[may_goto1];"
38+
"r0 = 1;"
39+
".8byte %[may_goto1];"
40+
".8byte %[may_goto1];"
41+
"exit;"
42+
:
43+
: __imm_insn(may_goto1, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 0 /* offset */, 0))
44+
: __clobber_all);
45+
}
46+
47+
SEC("raw_tp")
48+
__description("may_goto batch with offsets 2/1/0")
49+
__arch_x86_64
50+
__xlated("0: r0 = 1")
51+
__xlated("1: exit")
52+
__success
53+
__naked void may_goto_batch_1(void)
54+
{
55+
asm volatile (
56+
".8byte %[may_goto1];"
57+
".8byte %[may_goto2];"
58+
".8byte %[may_goto3];"
59+
"r0 = 1;"
60+
".8byte %[may_goto1];"
61+
".8byte %[may_goto2];"
62+
".8byte %[may_goto3];"
63+
"exit;"
64+
:
65+
: __imm_insn(may_goto1, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 2 /* offset */, 0)),
66+
__imm_insn(may_goto2, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 1 /* offset */, 0)),
67+
__imm_insn(may_goto3, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 0 /* offset */, 0))
68+
: __clobber_all);
69+
}
70+
71+
SEC("raw_tp")
72+
__description("may_goto batch with offsets 2/0")
73+
__arch_x86_64
74+
__xlated("0: *(u64 *)(r10 -8) = 8388608")
75+
__xlated("1: r11 = *(u64 *)(r10 -8)")
76+
__xlated("2: if r11 == 0x0 goto pc+3")
77+
__xlated("3: r11 -= 1")
78+
__xlated("4: *(u64 *)(r10 -8) = r11")
79+
__xlated("5: r0 = 1")
80+
__xlated("6: r0 = 2")
81+
__xlated("7: exit")
82+
__success
83+
__naked void may_goto_batch_2(void)
84+
{
85+
asm volatile (
86+
".8byte %[may_goto1];"
87+
".8byte %[may_goto3];"
88+
"r0 = 1;"
89+
"r0 = 2;"
90+
"exit;"
91+
:
92+
: __imm_insn(may_goto1, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 2 /* offset */, 0)),
93+
__imm_insn(may_goto3, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 0 /* offset */, 0))
94+
: __clobber_all);
95+
}
96+
97+
char _license[] SEC("license") = "GPL";
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
3+
4+
#include "bpf_misc.h"
5+
#include "bpf_experimental.h"
6+
7+
int gvar;
8+
9+
SEC("raw_tp")
10+
__description("C code with may_goto 0")
11+
__success
12+
int may_goto_c_code(void)
13+
{
14+
int i, tmp[3];
15+
16+
for (i = 0; i < 3 && can_loop; i++)
17+
tmp[i] = 0;
18+
19+
for (i = 0; i < 3 && can_loop; i++)
20+
tmp[i] = gvar - i;
21+
22+
for (i = 0; i < 3 && can_loop; i++)
23+
gvar += tmp[i];
24+
25+
return 0;
26+
}
27+
28+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)