~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/verifier/bpf_loop_inline.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #define BTF_TYPES \
  2         .btf_strings = "\0int\0i\0ctx\0callback\0main\0", \
  3         .btf_types = { \
  4         /* 1: int   */ BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), \
  5         /* 2: int*  */ BTF_PTR_ENC(1), \
  6         /* 3: void* */ BTF_PTR_ENC(0), \
  7         /* 4: int __(void*) */ BTF_FUNC_PROTO_ENC(1, 1), \
  8                 BTF_FUNC_PROTO_ARG_ENC(7, 3), \
  9         /* 5: int __(int, int*) */ BTF_FUNC_PROTO_ENC(1, 2), \
 10                 BTF_FUNC_PROTO_ARG_ENC(5, 1), \
 11                 BTF_FUNC_PROTO_ARG_ENC(7, 2), \
 12         /* 6: main      */ BTF_FUNC_ENC(20, 4), \
 13         /* 7: callback  */ BTF_FUNC_ENC(11, 5), \
 14         BTF_END_RAW \
 15         }
 16 
 17 #define MAIN_TYPE       6
 18 #define CALLBACK_TYPE   7
 19 
 20 /* can't use BPF_CALL_REL, jit_subprogs adjusts IMM & OFF
 21  * fields for pseudo calls
 22  */
 23 #define PSEUDO_CALL_INSN() \
 24         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_CALL, \
 25                      INSN_OFF_MASK, INSN_IMM_MASK)
 26 
 27 /* can't use BPF_FUNC_loop constant,
 28  * do_mix_fixups adjusts the IMM field
 29  */
 30 #define HELPER_CALL_INSN() \
 31         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, INSN_OFF_MASK, INSN_IMM_MASK)
 32 
 33 {
 34         "inline simple bpf_loop call",
 35         .insns = {
 36         /* main */
 37         /* force verifier state branching to verify logic on first and
 38          * subsequent bpf_loop insn processing steps
 39          */
 40         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
 41         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 2),
 42         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
 43         BPF_JMP_IMM(BPF_JA, 0, 0, 1),
 44         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
 45 
 46         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),
 47         BPF_RAW_INSN(0, 0, 0, 0, 0),
 48         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
 49         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
 50         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
 51         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
 52         BPF_EXIT_INSN(),
 53         /* callback */
 54         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
 55         BPF_EXIT_INSN(),
 56         },
 57         .expected_insns = { PSEUDO_CALL_INSN() },
 58         .unexpected_insns = { HELPER_CALL_INSN() },
 59         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
 60         .flags = F_NEEDS_JIT_ENABLED,
 61         .result = ACCEPT,
 62         .runs = 0,
 63         .func_info = { { 0, MAIN_TYPE }, { 12, CALLBACK_TYPE } },
 64         .func_info_cnt = 2,
 65         BTF_TYPES
 66 },
 67 {
 68         "don't inline bpf_loop call, flags non-zero",
 69         .insns = {
 70         /* main */
 71         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
 72         BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_0),
 73         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
 74         BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
 75         BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 9),
 76         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
 77         BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 0),
 78         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
 79         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 7),
 80         BPF_RAW_INSN(0, 0, 0, 0, 0),
 81         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
 82         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
 83         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
 84         BPF_EXIT_INSN(),
 85         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 1),
 86         BPF_JMP_IMM(BPF_JA, 0, 0, -10),
 87         /* callback */
 88         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
 89         BPF_EXIT_INSN(),
 90         },
 91         .expected_insns = { HELPER_CALL_INSN() },
 92         .unexpected_insns = { PSEUDO_CALL_INSN() },
 93         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
 94         .flags = F_NEEDS_JIT_ENABLED,
 95         .result = ACCEPT,
 96         .runs = 0,
 97         .func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },
 98         .func_info_cnt = 2,
 99         BTF_TYPES
100 },
101 {
102         "don't inline bpf_loop call, callback non-constant",
103         .insns = {
104         /* main */
105         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64),
106         BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 777, 4), /* pick a random callback */
107 
108         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
109         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 10),
110         BPF_RAW_INSN(0, 0, 0, 0, 0),
111         BPF_JMP_IMM(BPF_JA, 0, 0, 3),
112 
113         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
114         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),
115         BPF_RAW_INSN(0, 0, 0, 0, 0),
116 
117         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
118         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
119         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
120         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
121         BPF_EXIT_INSN(),
122         /* callback */
123         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
124         BPF_EXIT_INSN(),
125         /* callback #2 */
126         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
127         BPF_EXIT_INSN(),
128         },
129         .expected_insns = { HELPER_CALL_INSN() },
130         .unexpected_insns = { PSEUDO_CALL_INSN() },
131         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
132         .flags = F_NEEDS_JIT_ENABLED,
133         .result = ACCEPT,
134         .runs = 0,
135         .func_info = {
136                 { 0, MAIN_TYPE },
137                 { 14, CALLBACK_TYPE },
138                 { 16, CALLBACK_TYPE }
139         },
140         .func_info_cnt = 3,
141         BTF_TYPES
142 },
143 {
144         "bpf_loop_inline and a dead func",
145         .insns = {
146         /* main */
147 
148         /* A reference to callback #1 to make verifier count it as a func.
149          * This reference is overwritten below and callback #1 is dead.
150          */
151         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 9),
152         BPF_RAW_INSN(0, 0, 0, 0, 0),
153         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
154         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 8),
155         BPF_RAW_INSN(0, 0, 0, 0, 0),
156         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
157         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
158         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
159         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
160         BPF_EXIT_INSN(),
161         /* callback */
162         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
163         BPF_EXIT_INSN(),
164         /* callback #2 */
165         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
166         BPF_EXIT_INSN(),
167         },
168         .expected_insns = { PSEUDO_CALL_INSN() },
169         .unexpected_insns = { HELPER_CALL_INSN() },
170         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
171         .flags = F_NEEDS_JIT_ENABLED,
172         .result = ACCEPT,
173         .runs = 0,
174         .func_info = {
175                 { 0, MAIN_TYPE },
176                 { 10, CALLBACK_TYPE },
177                 { 12, CALLBACK_TYPE }
178         },
179         .func_info_cnt = 3,
180         BTF_TYPES
181 },
182 {
183         "bpf_loop_inline stack locations for loop vars",
184         .insns = {
185         /* main */
186         BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
187         /* bpf_loop call #1 */
188         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 1),
189         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 22),
190         BPF_RAW_INSN(0, 0, 0, 0, 0),
191         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
192         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
193         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
194         /* bpf_loop call #2 */
195         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
196         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 16),
197         BPF_RAW_INSN(0, 0, 0, 0, 0),
198         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
199         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
200         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
201         /* call func and exit */
202         BPF_CALL_REL(2),
203         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
204         BPF_EXIT_INSN(),
205         /* func */
206         BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),
207         BPF_ALU64_IMM(BPF_MOV, BPF_REG_1, 2),
208         BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_2, BPF_PSEUDO_FUNC, 0, 6),
209         BPF_RAW_INSN(0, 0, 0, 0, 0),
210         BPF_ALU64_IMM(BPF_MOV, BPF_REG_3, 0),
211         BPF_ALU64_IMM(BPF_MOV, BPF_REG_4, 0),
212         BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_loop),
213         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
214         BPF_EXIT_INSN(),
215         /* callback */
216         BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 1),
217         BPF_EXIT_INSN(),
218         },
219         .expected_insns = {
220         BPF_ST_MEM(BPF_W, BPF_REG_10, -12, 0x77),
221         SKIP_INSNS(),
222         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),
223         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),
224         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),
225         SKIP_INSNS(),
226         /* offsets are the same as in the first call */
227         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -40),
228         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -32),
229         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -24),
230         SKIP_INSNS(),
231         BPF_ST_MEM(BPF_DW, BPF_REG_10, -32, 0x55),
232         SKIP_INSNS(),
233         /* offsets differ from main because of different offset
234          * in BPF_ST_MEM instruction
235          */
236         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -56),
237         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_7, -48),
238         BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_8, -40),
239         },
240         .unexpected_insns = { HELPER_CALL_INSN() },
241         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
242         .flags = F_NEEDS_JIT_ENABLED,
243         .result = ACCEPT,
244         .func_info = {
245                 { 0, MAIN_TYPE },
246                 { 16, MAIN_TYPE },
247                 { 25, CALLBACK_TYPE },
248         },
249         .func_info_cnt = 3,
250         BTF_TYPES
251 },
252 {
253         "inline bpf_loop call in a big program",
254         .insns = {},
255         .fill_helper = bpf_fill_big_prog_with_loop_1,
256         .expected_insns = { PSEUDO_CALL_INSN() },
257         .unexpected_insns = { HELPER_CALL_INSN() },
258         .result = ACCEPT,
259         .prog_type = BPF_PROG_TYPE_TRACEPOINT,
260         .flags = F_NEEDS_JIT_ENABLED,
261         .func_info = { { 0, MAIN_TYPE }, { 16, CALLBACK_TYPE } },
262         .func_info_cnt = 2,
263         BTF_TYPES
264 },
265 
266 #undef HELPER_CALL_INSN
267 #undef PSEUDO_CALL_INSN
268 #undef CALLBACK_TYPE
269 #undef MAIN_TYPE
270 #undef BTF_TYPES
271 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php