]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/progs/iters_looping.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / progs / iters_looping.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
3
4 #include <errno.h>
5 #include <string.h>
6 #include <linux/bpf.h>
7 #include <bpf/bpf_helpers.h>
8 #include "bpf_misc.h"
9
10 char _license[] SEC("license") = "GPL";
11
12 #define ITER_HELPERS                                            \
13           __imm(bpf_iter_num_new),                              \
14           __imm(bpf_iter_num_next),                             \
15           __imm(bpf_iter_num_destroy)
16
17 SEC("?raw_tp")
18 __success
19 int force_clang_to_emit_btf_for_externs(void *ctx)
20 {
21         /* we need this as a workaround to enforce compiler emitting BTF
22          * information for bpf_iter_num_{new,next,destroy}() kfuncs,
23          * as, apparently, it doesn't emit it for symbols only referenced from
24          * assembly (or cleanup attribute, for that matter, as well)
25          */
26         bpf_repeat(0);
27
28         return 0;
29 }
30
31 SEC("?raw_tp")
32 __success
33 int consume_first_item_only(void *ctx)
34 {
35         struct bpf_iter_num iter;
36
37         asm volatile (
38                 /* create iterator */
39                 "r1 = %[iter];"
40                 "r2 = 0;"
41                 "r3 = 1000;"
42                 "call %[bpf_iter_num_new];"
43
44                 /* consume first item */
45                 "r1 = %[iter];"
46                 "call %[bpf_iter_num_next];"
47
48                 "if r0 == 0 goto +1;"
49                 "r0 = *(u32 *)(r0 + 0);"
50
51                 /* destroy iterator */
52                 "r1 = %[iter];"
53                 "call %[bpf_iter_num_destroy];"
54                 :
55                 : __imm_ptr(iter), ITER_HELPERS
56                 : __clobber_common
57         );
58
59         return 0;
60 }
61
62 SEC("?raw_tp")
63 __failure __msg("R0 invalid mem access 'scalar'")
64 int missing_null_check_fail(void *ctx)
65 {
66         struct bpf_iter_num iter;
67
68         asm volatile (
69                 /* create iterator */
70                 "r1 = %[iter];"
71                 "r2 = 0;"
72                 "r3 = 1000;"
73                 "call %[bpf_iter_num_new];"
74
75                 /* consume first element */
76                 "r1 = %[iter];"
77                 "call %[bpf_iter_num_next];"
78
79                 /* FAIL: deref with no NULL check */
80                 "r1 = *(u32 *)(r0 + 0);"
81
82                 /* destroy iterator */
83                 "r1 = %[iter];"
84                 "call %[bpf_iter_num_destroy];"
85                 :
86                 : __imm_ptr(iter), ITER_HELPERS
87                 : __clobber_common
88         );
89
90         return 0;
91 }
92
93 SEC("?raw_tp")
94 __failure
95 __msg("invalid access to memory, mem_size=4 off=0 size=8")
96 __msg("R0 min value is outside of the allowed memory range")
97 int wrong_sized_read_fail(void *ctx)
98 {
99         struct bpf_iter_num iter;
100
101         asm volatile (
102                 /* create iterator */
103                 "r1 = %[iter];"
104                 "r2 = 0;"
105                 "r3 = 1000;"
106                 "call %[bpf_iter_num_new];"
107
108                 /* consume first element */
109                 "r1 = %[iter];"
110                 "call %[bpf_iter_num_next];"
111
112                 "if r0 == 0 goto +1;"
113                 /* FAIL: deref more than available 4 bytes */
114                 "r0 = *(u64 *)(r0 + 0);"
115
116                 /* destroy iterator */
117                 "r1 = %[iter];"
118                 "call %[bpf_iter_num_destroy];"
119                 :
120                 : __imm_ptr(iter), ITER_HELPERS
121                 : __clobber_common
122         );
123
124         return 0;
125 }
126
127 SEC("?raw_tp")
128 __success __log_level(2)
129 __flag(BPF_F_TEST_STATE_FREQ)
130 int simplest_loop(void *ctx)
131 {
132         struct bpf_iter_num iter;
133
134         asm volatile (
135                 "r6 = 0;" /* init sum */
136
137                 /* create iterator */
138                 "r1 = %[iter];"
139                 "r2 = 0;"
140                 "r3 = 10;"
141                 "call %[bpf_iter_num_new];"
142
143         "1:"
144                 /* consume next item */
145                 "r1 = %[iter];"
146                 "call %[bpf_iter_num_next];"
147
148                 "if r0 == 0 goto 2f;"
149                 "r0 = *(u32 *)(r0 + 0);"
150                 "r6 += r0;" /* accumulate sum */
151                 "goto 1b;"
152
153         "2:"
154                 /* destroy iterator */
155                 "r1 = %[iter];"
156                 "call %[bpf_iter_num_destroy];"
157                 :
158                 : __imm_ptr(iter), ITER_HELPERS
159                 : __clobber_common, "r6"
160         );
161
162         return 0;
163 }
This page took 0.035807 seconds and 4 git commands to generate.