xref: /linux/tools/testing/selftests/bpf/progs/verifier_subreg.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/subreg.c */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 /* This file contains sub-register zero extension checks for insns defining
9  * sub-registers, meaning:
10  *   - All insns under BPF_ALU class. Their BPF_ALU32 variants or narrow width
11  *     forms (BPF_END) could define sub-registers.
12  *   - Narrow direct loads, BPF_B/H/W | BPF_LDX.
13  *   - BPF_LD is not exposed to JIT back-ends, so no need for testing.
14  *
15  * "get_prandom_u32" is used to initialize low 32-bit of some registers to
16  * prevent potential optimizations done by verifier or JIT back-ends which could
17  * optimize register back into constant when range info shows one register is a
18  * constant.
19  */
20 
21 SEC("socket")
22 __description("add32 reg zero extend check")
23 __success __success_unpriv __retval(0)
24 __naked void add32_reg_zero_extend_check(void)
25 {
26 	asm volatile ("					\
27 	call %[bpf_get_prandom_u32];			\
28 	r1 = r0;					\
29 	r0 = 0x100000000 ll;				\
30 	w0 += w1;					\
31 	r0 >>= 32;					\
32 	exit;						\
33 "	:
34 	: __imm(bpf_get_prandom_u32)
35 	: __clobber_all);
36 }
37 
38 SEC("socket")
39 __description("add32 imm zero extend check")
40 __success __success_unpriv __retval(0)
41 __naked void add32_imm_zero_extend_check(void)
42 {
43 	asm volatile ("					\
44 	call %[bpf_get_prandom_u32];			\
45 	r1 = 0x1000000000 ll;				\
46 	r0 |= r1;					\
47 	/* An insn could have no effect on the low 32-bit, for example:\
48 	 *   a = a + 0					\
49 	 *   a = a | 0					\
50 	 *   a = a & -1					\
51 	 * But, they should still zero high 32-bit.	\
52 	 */						\
53 	w0 += 0;					\
54 	r0 >>= 32;					\
55 	r6 = r0;					\
56 	call %[bpf_get_prandom_u32];			\
57 	r1 = 0x1000000000 ll;				\
58 	r0 |= r1;					\
59 	w0 += -2;					\
60 	r0 >>= 32;					\
61 	r0 |= r6;					\
62 	exit;						\
63 "	:
64 	: __imm(bpf_get_prandom_u32)
65 	: __clobber_all);
66 }
67 
68 SEC("socket")
69 __description("sub32 reg zero extend check")
70 __success __success_unpriv __retval(0)
71 __naked void sub32_reg_zero_extend_check(void)
72 {
73 	asm volatile ("					\
74 	call %[bpf_get_prandom_u32];			\
75 	r1 = r0;					\
76 	r0 = 0x1ffffffff ll;				\
77 	w0 -= w1;					\
78 	r0 >>= 32;					\
79 	exit;						\
80 "	:
81 	: __imm(bpf_get_prandom_u32)
82 	: __clobber_all);
83 }
84 
85 SEC("socket")
86 __description("sub32 imm zero extend check")
87 __success __success_unpriv __retval(0)
88 __naked void sub32_imm_zero_extend_check(void)
89 {
90 	asm volatile ("					\
91 	call %[bpf_get_prandom_u32];			\
92 	r1 = 0x1000000000 ll;				\
93 	r0 |= r1;					\
94 	w0 -= 0;					\
95 	r0 >>= 32;					\
96 	r6 = r0;					\
97 	call %[bpf_get_prandom_u32];			\
98 	r1 = 0x1000000000 ll;				\
99 	r0 |= r1;					\
100 	w0 -= 1;					\
101 	r0 >>= 32;					\
102 	r0 |= r6;					\
103 	exit;						\
104 "	:
105 	: __imm(bpf_get_prandom_u32)
106 	: __clobber_all);
107 }
108 
109 SEC("socket")
110 __description("mul32 reg zero extend check")
111 __success __success_unpriv __retval(0)
112 __naked void mul32_reg_zero_extend_check(void)
113 {
114 	asm volatile ("					\
115 	call %[bpf_get_prandom_u32];			\
116 	r1 = r0;					\
117 	r0 = 0x100000001 ll;				\
118 	w0 *= w1;					\
119 	r0 >>= 32;					\
120 	exit;						\
121 "	:
122 	: __imm(bpf_get_prandom_u32)
123 	: __clobber_all);
124 }
125 
126 SEC("socket")
127 __description("mul32 imm zero extend check")
128 __success __success_unpriv __retval(0)
129 __naked void mul32_imm_zero_extend_check(void)
130 {
131 	asm volatile ("					\
132 	call %[bpf_get_prandom_u32];			\
133 	r1 = 0x1000000000 ll;				\
134 	r0 |= r1;					\
135 	w0 *= 1;					\
136 	r0 >>= 32;					\
137 	r6 = r0;					\
138 	call %[bpf_get_prandom_u32];			\
139 	r1 = 0x1000000000 ll;				\
140 	r0 |= r1;					\
141 	w0 *= -1;					\
142 	r0 >>= 32;					\
143 	r0 |= r6;					\
144 	exit;						\
145 "	:
146 	: __imm(bpf_get_prandom_u32)
147 	: __clobber_all);
148 }
149 
150 SEC("socket")
151 __description("div32 reg zero extend check")
152 __success __success_unpriv __retval(0)
153 __naked void div32_reg_zero_extend_check(void)
154 {
155 	asm volatile ("					\
156 	call %[bpf_get_prandom_u32];			\
157 	r1 = r0;					\
158 	r0 = -1;					\
159 	w0 /= w1;					\
160 	r0 >>= 32;					\
161 	exit;						\
162 "	:
163 	: __imm(bpf_get_prandom_u32)
164 	: __clobber_all);
165 }
166 
167 SEC("socket")
168 __description("div32 imm zero extend check")
169 __success __success_unpriv __retval(0)
170 __naked void div32_imm_zero_extend_check(void)
171 {
172 	asm volatile ("					\
173 	call %[bpf_get_prandom_u32];			\
174 	r1 = 0x1000000000 ll;				\
175 	r0 |= r1;					\
176 	w0 /= 1;					\
177 	r0 >>= 32;					\
178 	r6 = r0;					\
179 	call %[bpf_get_prandom_u32];			\
180 	r1 = 0x1000000000 ll;				\
181 	r0 |= r1;					\
182 	w0 /= 2;					\
183 	r0 >>= 32;					\
184 	r0 |= r6;					\
185 	exit;						\
186 "	:
187 	: __imm(bpf_get_prandom_u32)
188 	: __clobber_all);
189 }
190 
191 SEC("socket")
192 __description("or32 reg zero extend check")
193 __success __success_unpriv __retval(0)
194 __naked void or32_reg_zero_extend_check(void)
195 {
196 	asm volatile ("					\
197 	call %[bpf_get_prandom_u32];			\
198 	r1 = r0;					\
199 	r0 = 0x100000001 ll;				\
200 	w0 |= w1;					\
201 	r0 >>= 32;					\
202 	exit;						\
203 "	:
204 	: __imm(bpf_get_prandom_u32)
205 	: __clobber_all);
206 }
207 
208 SEC("socket")
209 __description("or32 imm zero extend check")
210 __success __success_unpriv __retval(0)
211 __naked void or32_imm_zero_extend_check(void)
212 {
213 	asm volatile ("					\
214 	call %[bpf_get_prandom_u32];			\
215 	r1 = 0x1000000000 ll;				\
216 	r0 |= r1;					\
217 	w0 |= 0;					\
218 	r0 >>= 32;					\
219 	r6 = r0;					\
220 	call %[bpf_get_prandom_u32];			\
221 	r1 = 0x1000000000 ll;				\
222 	r0 |= r1;					\
223 	w0 |= 1;					\
224 	r0 >>= 32;					\
225 	r0 |= r6;					\
226 	exit;						\
227 "	:
228 	: __imm(bpf_get_prandom_u32)
229 	: __clobber_all);
230 }
231 
232 SEC("socket")
233 __description("and32 reg zero extend check")
234 __success __success_unpriv __retval(0)
235 __naked void and32_reg_zero_extend_check(void)
236 {
237 	asm volatile ("					\
238 	call %[bpf_get_prandom_u32];			\
239 	r1 = 0x100000000 ll;				\
240 	r1 |= r0;					\
241 	r0 = 0x1ffffffff ll;				\
242 	w0 &= w1;					\
243 	r0 >>= 32;					\
244 	exit;						\
245 "	:
246 	: __imm(bpf_get_prandom_u32)
247 	: __clobber_all);
248 }
249 
250 SEC("socket")
251 __description("and32 imm zero extend check")
252 __success __success_unpriv __retval(0)
253 __naked void and32_imm_zero_extend_check(void)
254 {
255 	asm volatile ("					\
256 	call %[bpf_get_prandom_u32];			\
257 	r1 = 0x1000000000 ll;				\
258 	r0 |= r1;					\
259 	w0 &= -1;					\
260 	r0 >>= 32;					\
261 	r6 = r0;					\
262 	call %[bpf_get_prandom_u32];			\
263 	r1 = 0x1000000000 ll;				\
264 	r0 |= r1;					\
265 	w0 &= -2;					\
266 	r0 >>= 32;					\
267 	r0 |= r6;					\
268 	exit;						\
269 "	:
270 	: __imm(bpf_get_prandom_u32)
271 	: __clobber_all);
272 }
273 
274 SEC("socket")
275 __description("lsh32 reg zero extend check")
276 __success __success_unpriv __retval(0)
277 __naked void lsh32_reg_zero_extend_check(void)
278 {
279 	asm volatile ("					\
280 	call %[bpf_get_prandom_u32];			\
281 	r1 = 0x100000000 ll;				\
282 	r0 |= r1;					\
283 	r1 = 1;						\
284 	w0 <<= w1;					\
285 	r0 >>= 32;					\
286 	exit;						\
287 "	:
288 	: __imm(bpf_get_prandom_u32)
289 	: __clobber_all);
290 }
291 
292 SEC("socket")
293 __description("lsh32 imm zero extend check")
294 __success __success_unpriv __retval(0)
295 __naked void lsh32_imm_zero_extend_check(void)
296 {
297 	asm volatile ("					\
298 	call %[bpf_get_prandom_u32];			\
299 	r1 = 0x1000000000 ll;				\
300 	r0 |= r1;					\
301 	w0 <<= 0;					\
302 	r0 >>= 32;					\
303 	r6 = r0;					\
304 	call %[bpf_get_prandom_u32];			\
305 	r1 = 0x1000000000 ll;				\
306 	r0 |= r1;					\
307 	w0 <<= 1;					\
308 	r0 >>= 32;					\
309 	r0 |= r6;					\
310 	exit;						\
311 "	:
312 	: __imm(bpf_get_prandom_u32)
313 	: __clobber_all);
314 }
315 
316 SEC("socket")
317 __description("rsh32 reg zero extend check")
318 __success __success_unpriv __retval(0)
319 __naked void rsh32_reg_zero_extend_check(void)
320 {
321 	asm volatile ("					\
322 	call %[bpf_get_prandom_u32];			\
323 	r1 = 0x1000000000 ll;				\
324 	r0 |= r1;					\
325 	r1 = 1;						\
326 	w0 >>= w1;					\
327 	r0 >>= 32;					\
328 	exit;						\
329 "	:
330 	: __imm(bpf_get_prandom_u32)
331 	: __clobber_all);
332 }
333 
334 SEC("socket")
335 __description("rsh32 imm zero extend check")
336 __success __success_unpriv __retval(0)
337 __naked void rsh32_imm_zero_extend_check(void)
338 {
339 	asm volatile ("					\
340 	call %[bpf_get_prandom_u32];			\
341 	r1 = 0x1000000000 ll;				\
342 	r0 |= r1;					\
343 	w0 >>= 0;					\
344 	r0 >>= 32;					\
345 	r6 = r0;					\
346 	call %[bpf_get_prandom_u32];			\
347 	r1 = 0x1000000000 ll;				\
348 	r0 |= r1;					\
349 	w0 >>= 1;					\
350 	r0 >>= 32;					\
351 	r0 |= r6;					\
352 	exit;						\
353 "	:
354 	: __imm(bpf_get_prandom_u32)
355 	: __clobber_all);
356 }
357 
358 SEC("socket")
359 __description("neg32 reg zero extend check")
360 __success __success_unpriv __retval(0)
361 __naked void neg32_reg_zero_extend_check(void)
362 {
363 	asm volatile ("					\
364 	call %[bpf_get_prandom_u32];			\
365 	r1 = 0x1000000000 ll;				\
366 	r0 |= r1;					\
367 	w0 = -w0;					\
368 	r0 >>= 32;					\
369 	exit;						\
370 "	:
371 	: __imm(bpf_get_prandom_u32)
372 	: __clobber_all);
373 }
374 
375 SEC("socket")
376 __description("mod32 reg zero extend check")
377 __success __success_unpriv __retval(0)
378 __naked void mod32_reg_zero_extend_check(void)
379 {
380 	asm volatile ("					\
381 	call %[bpf_get_prandom_u32];			\
382 	r1 = r0;					\
383 	r0 = -1;					\
384 	w0 %%= w1;					\
385 	r0 >>= 32;					\
386 	exit;						\
387 "	:
388 	: __imm(bpf_get_prandom_u32)
389 	: __clobber_all);
390 }
391 
392 SEC("socket")
393 __description("mod32 imm zero extend check")
394 __success __success_unpriv __retval(0)
395 __naked void mod32_imm_zero_extend_check(void)
396 {
397 	asm volatile ("					\
398 	call %[bpf_get_prandom_u32];			\
399 	r1 = 0x1000000000 ll;				\
400 	r0 |= r1;					\
401 	w0 %%= 1;					\
402 	r0 >>= 32;					\
403 	r6 = r0;					\
404 	call %[bpf_get_prandom_u32];			\
405 	r1 = 0x1000000000 ll;				\
406 	r0 |= r1;					\
407 	w0 %%= 2;					\
408 	r0 >>= 32;					\
409 	r0 |= r6;					\
410 	exit;						\
411 "	:
412 	: __imm(bpf_get_prandom_u32)
413 	: __clobber_all);
414 }
415 
416 SEC("socket")
417 __description("xor32 reg zero extend check")
418 __success __success_unpriv __retval(0)
419 __naked void xor32_reg_zero_extend_check(void)
420 {
421 	asm volatile ("					\
422 	call %[bpf_get_prandom_u32];			\
423 	r1 = r0;					\
424 	r0 = 0x100000000 ll;				\
425 	w0 ^= w1;					\
426 	r0 >>= 32;					\
427 	exit;						\
428 "	:
429 	: __imm(bpf_get_prandom_u32)
430 	: __clobber_all);
431 }
432 
433 SEC("socket")
434 __description("xor32 imm zero extend check")
435 __success __success_unpriv __retval(0)
436 __naked void xor32_imm_zero_extend_check(void)
437 {
438 	asm volatile ("					\
439 	call %[bpf_get_prandom_u32];			\
440 	r1 = 0x1000000000 ll;				\
441 	r0 |= r1;					\
442 	w0 ^= 1;					\
443 	r0 >>= 32;					\
444 	exit;						\
445 "	:
446 	: __imm(bpf_get_prandom_u32)
447 	: __clobber_all);
448 }
449 
450 SEC("socket")
451 __description("mov32 reg zero extend check")
452 __success __success_unpriv __retval(0)
453 __naked void mov32_reg_zero_extend_check(void)
454 {
455 	asm volatile ("					\
456 	call %[bpf_get_prandom_u32];			\
457 	r1 = 0x100000000 ll;				\
458 	r1 |= r0;					\
459 	r0 = 0x100000000 ll;				\
460 	w0 = w1;					\
461 	r0 >>= 32;					\
462 	exit;						\
463 "	:
464 	: __imm(bpf_get_prandom_u32)
465 	: __clobber_all);
466 }
467 
468 SEC("socket")
469 __description("mov32 imm zero extend check")
470 __success __success_unpriv __retval(0)
471 __naked void mov32_imm_zero_extend_check(void)
472 {
473 	asm volatile ("					\
474 	call %[bpf_get_prandom_u32];			\
475 	r1 = 0x1000000000 ll;				\
476 	r0 |= r1;					\
477 	w0 = 0;						\
478 	r0 >>= 32;					\
479 	r6 = r0;					\
480 	call %[bpf_get_prandom_u32];			\
481 	r1 = 0x1000000000 ll;				\
482 	r0 |= r1;					\
483 	w0 = 1;						\
484 	r0 >>= 32;					\
485 	r0 |= r6;					\
486 	exit;						\
487 "	:
488 	: __imm(bpf_get_prandom_u32)
489 	: __clobber_all);
490 }
491 
492 SEC("socket")
493 __description("arsh32 reg zero extend check")
494 __success __success_unpriv __retval(0)
495 __naked void arsh32_reg_zero_extend_check(void)
496 {
497 	asm volatile ("					\
498 	call %[bpf_get_prandom_u32];			\
499 	r1 = 0x1000000000 ll;				\
500 	r0 |= r1;					\
501 	r1 = 1;						\
502 	w0 s>>= w1;					\
503 	r0 >>= 32;					\
504 	exit;						\
505 "	:
506 	: __imm(bpf_get_prandom_u32)
507 	: __clobber_all);
508 }
509 
510 SEC("socket")
511 __description("arsh32 imm zero extend check")
512 __success __success_unpriv __retval(0)
513 __naked void arsh32_imm_zero_extend_check(void)
514 {
515 	asm volatile ("					\
516 	call %[bpf_get_prandom_u32];			\
517 	r1 = 0x1000000000 ll;				\
518 	r0 |= r1;					\
519 	w0 s>>= 0;					\
520 	r0 >>= 32;					\
521 	r6 = r0;					\
522 	call %[bpf_get_prandom_u32];			\
523 	r1 = 0x1000000000 ll;				\
524 	r0 |= r1;					\
525 	w0 s>>= 1;					\
526 	r0 >>= 32;					\
527 	r0 |= r6;					\
528 	exit;						\
529 "	:
530 	: __imm(bpf_get_prandom_u32)
531 	: __clobber_all);
532 }
533 
534 SEC("socket")
535 __description("arsh32 imm sign positive extend check")
536 __success __retval(0)
537 __log_level(2)
538 __msg("2: (57) r6 &= 4095                    ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=4095,var_off=(0x0; 0xfff))")
539 __msg("3: (67) r6 <<= 32                     ; R6=scalar(smin=smin32=0,smax=umax=0xfff00000000,smax32=umax32=0,var_off=(0x0; 0xfff00000000))")
540 __msg("4: (c7) r6 s>>= 32                    ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=4095,var_off=(0x0; 0xfff))")
541 __naked void arsh32_imm_sign_extend_positive_check(void)
542 {
543 	asm volatile ("					\
544 	call %[bpf_get_prandom_u32];			\
545 	r6 = r0;					\
546 	r6 &= 4095;					\
547 	r6 <<= 32;					\
548 	r6 s>>= 32;					\
549 	r0 = 0;						\
550 	exit;						\
551 "	:
552 	: __imm(bpf_get_prandom_u32)
553 	: __clobber_all);
554 }
555 
556 SEC("socket")
557 __description("arsh32 imm sign negative extend check")
558 __success __retval(0)
559 __log_level(2)
560 __msg("3: (17) r6 -= 4095                    ; R6=scalar(smin=smin32=-4095,smax=smax32=0)")
561 __msg("4: (67) r6 <<= 32                     ; R6=scalar(smin=0xfffff00100000000,smax=smax32=umax32=0,umax=0xffffffff00000000,smin32=0,var_off=(0x0; 0xffffffff00000000))")
562 __msg("5: (c7) r6 s>>= 32                    ; R6=scalar(smin=smin32=-4095,smax=smax32=0)")
563 __naked void arsh32_imm_sign_extend_negative_check(void)
564 {
565 	asm volatile ("					\
566 	call %[bpf_get_prandom_u32];			\
567 	r6 = r0;					\
568 	r6 &= 4095;					\
569 	r6 -= 4095;					\
570 	r6 <<= 32;					\
571 	r6 s>>= 32;					\
572 	r0 = 0;						\
573 	exit;						\
574 "	:
575 	: __imm(bpf_get_prandom_u32)
576 	: __clobber_all);
577 }
578 
579 SEC("socket")
580 __description("arsh32 imm sign extend check")
581 __success __retval(0)
582 __log_level(2)
583 __msg("3: (17) r6 -= 2047                    ; R6=scalar(smin=smin32=-2047,smax=smax32=2048)")
584 __msg("4: (67) r6 <<= 32                     ; R6=scalar(smin=0xfffff80100000000,smax=0x80000000000,umax=0xffffffff00000000,smin32=0,smax32=umax32=0,var_off=(0x0; 0xffffffff00000000))")
585 __msg("5: (c7) r6 s>>= 32                    ; R6=scalar(smin=smin32=-2047,smax=smax32=2048)")
586 __naked void arsh32_imm_sign_extend_check(void)
587 {
588 	asm volatile ("					\
589 	call %[bpf_get_prandom_u32];			\
590 	r6 = r0;					\
591 	r6 &= 4095;					\
592 	r6 -= 2047;					\
593 	r6 <<= 32;					\
594 	r6 s>>= 32;					\
595 	r0 = 0;						\
596 	exit;						\
597 "	:
598 	: __imm(bpf_get_prandom_u32)
599 	: __clobber_all);
600 }
601 
602 SEC("socket")
603 __description("end16 (to_le) reg zero extend check")
604 __success __success_unpriv __retval(0)
605 __naked void le_reg_zero_extend_check_1(void)
606 {
607 	asm volatile ("					\
608 	call %[bpf_get_prandom_u32];			\
609 	r6 = r0;					\
610 	r6 <<= 32;					\
611 	call %[bpf_get_prandom_u32];			\
612 	r0 |= r6;					\
613 	r0 = le16 r0;					\
614 	r0 >>= 32;					\
615 	exit;						\
616 "	:
617 	: __imm(bpf_get_prandom_u32)
618 	: __clobber_all);
619 }
620 
621 SEC("socket")
622 __description("end32 (to_le) reg zero extend check")
623 __success __success_unpriv __retval(0)
624 __naked void le_reg_zero_extend_check_2(void)
625 {
626 	asm volatile ("					\
627 	call %[bpf_get_prandom_u32];			\
628 	r6 = r0;					\
629 	r6 <<= 32;					\
630 	call %[bpf_get_prandom_u32];			\
631 	r0 |= r6;					\
632 	r0 = le32 r0;					\
633 	r0 >>= 32;					\
634 	exit;						\
635 "	:
636 	: __imm(bpf_get_prandom_u32)
637 	: __clobber_all);
638 }
639 
640 SEC("socket")
641 __description("end16 (to_be) reg zero extend check")
642 __success __success_unpriv __retval(0)
643 __naked void be_reg_zero_extend_check_1(void)
644 {
645 	asm volatile ("					\
646 	call %[bpf_get_prandom_u32];			\
647 	r6 = r0;					\
648 	r6 <<= 32;					\
649 	call %[bpf_get_prandom_u32];			\
650 	r0 |= r6;					\
651 	r0 = be16 r0;					\
652 	r0 >>= 32;					\
653 	exit;						\
654 "	:
655 	: __imm(bpf_get_prandom_u32)
656 	: __clobber_all);
657 }
658 
659 SEC("socket")
660 __description("end32 (to_be) reg zero extend check")
661 __success __success_unpriv __retval(0)
662 __naked void be_reg_zero_extend_check_2(void)
663 {
664 	asm volatile ("					\
665 	call %[bpf_get_prandom_u32];			\
666 	r6 = r0;					\
667 	r6 <<= 32;					\
668 	call %[bpf_get_prandom_u32];			\
669 	r0 |= r6;					\
670 	r0 = be32 r0;					\
671 	r0 >>= 32;					\
672 	exit;						\
673 "	:
674 	: __imm(bpf_get_prandom_u32)
675 	: __clobber_all);
676 }
677 
678 SEC("socket")
679 __description("ldx_b zero extend check")
680 __success __success_unpriv __retval(0)
681 __naked void ldx_b_zero_extend_check(void)
682 {
683 	asm volatile ("					\
684 	r6 = r10;					\
685 	r6 += -4;					\
686 	r7 = 0xfaceb00c;				\
687 	*(u32*)(r6 + 0) = r7;				\
688 	call %[bpf_get_prandom_u32];			\
689 	r1 = 0x1000000000 ll;				\
690 	r0 |= r1;					\
691 	r0 = *(u8*)(r6 + 0);				\
692 	r0 >>= 32;					\
693 	exit;						\
694 "	:
695 	: __imm(bpf_get_prandom_u32)
696 	: __clobber_all);
697 }
698 
699 SEC("socket")
700 __description("ldx_h zero extend check")
701 __success __success_unpriv __retval(0)
702 __naked void ldx_h_zero_extend_check(void)
703 {
704 	asm volatile ("					\
705 	r6 = r10;					\
706 	r6 += -4;					\
707 	r7 = 0xfaceb00c;				\
708 	*(u32*)(r6 + 0) = r7;				\
709 	call %[bpf_get_prandom_u32];			\
710 	r1 = 0x1000000000 ll;				\
711 	r0 |= r1;					\
712 	r0 = *(u16*)(r6 + 0);				\
713 	r0 >>= 32;					\
714 	exit;						\
715 "	:
716 	: __imm(bpf_get_prandom_u32)
717 	: __clobber_all);
718 }
719 
720 SEC("socket")
721 __description("ldx_w zero extend check")
722 __success __success_unpriv __retval(0)
723 __naked void ldx_w_zero_extend_check(void)
724 {
725 	asm volatile ("					\
726 	r6 = r10;					\
727 	r6 += -4;					\
728 	r7 = 0xfaceb00c;				\
729 	*(u32*)(r6 + 0) = r7;				\
730 	call %[bpf_get_prandom_u32];			\
731 	r1 = 0x1000000000 ll;				\
732 	r0 |= r1;					\
733 	r0 = *(u32*)(r6 + 0);				\
734 	r0 >>= 32;					\
735 	exit;						\
736 "	:
737 	: __imm(bpf_get_prandom_u32)
738 	: __clobber_all);
739 }
740 
741 SEC("socket")
742 __success __success_unpriv __retval(0)
743 __naked void arsh_31_and(void)
744 {
745 	/* Below is what LLVM generates in cilium's bpf_wiregard.o */
746 	asm volatile ("					\
747 	call %[bpf_get_prandom_u32];			\
748 	w2 = w0;					\
749 	w2 s>>= 31;					\
750 	w2 &= -134; /* w2 becomes 0 or -134 */		\
751 	if w2 s> -1 goto +2;				\
752 	/* Branch always taken because w2 = -134 */	\
753 	if w2 != -136 goto +1;				\
754 	w0 /= 0;					\
755 	w0 = 0;						\
756 	exit;						\
757 "	:
758 	: __imm(bpf_get_prandom_u32)
759 	: __clobber_all);
760 }
761 
762 SEC("socket")
763 __success __success_unpriv __retval(0)
764 __naked void arsh_63_and(void)
765 {
766 	/* Copy of arsh_31 with s/w/r/ */
767 	asm volatile ("					\
768 	call %[bpf_get_prandom_u32];			\
769 	r2 = r0;					\
770 	r2 <<= 32;					\
771 	r2 s>>= 63;					\
772 	r2 &= -134;					\
773 	if r2 s> -1 goto +2;				\
774 	/* Branch always taken because w2 = -134 */	\
775 	if r2 != -136 goto +1;				\
776 	r0 /= 0;					\
777 	r0 = 0;						\
778 	exit;						\
779 "	:
780 	: __imm(bpf_get_prandom_u32)
781 	: __clobber_all);
782 }
783 
784 SEC("socket")
785 __success __success_unpriv __retval(0)
786 __naked void arsh_31_or(void)
787 {
788 	asm volatile ("					\
789 	call %[bpf_get_prandom_u32];			\
790 	w2 = w0;					\
791 	w2 s>>= 31;					\
792 	w2 |= 134; /* w2 becomes -1 or 134 */		\
793 	if w2 s> -1 goto +2;				\
794 	/* Branch always taken because w2 = -1 */	\
795 	if w2 == -1 goto +1;				\
796 	w0 /= 0;					\
797 	w0 = 0;						\
798 	exit;						\
799 "	:
800 	: __imm(bpf_get_prandom_u32)
801 	: __clobber_all);
802 }
803 
804 SEC("socket")
805 __success __success_unpriv __retval(0)
806 __naked void arsh_63_or(void)
807 {
808 	/* Copy of arsh_31 with s/w/r/ */
809 	asm volatile ("					\
810 	call %[bpf_get_prandom_u32];			\
811 	r2 = r0;					\
812 	r2 <<= 32;					\
813 	r2 s>>= 63;					\
814 	r2 |= 134; /* r2 becomes -1 or 134 */		\
815 	if r2 s> -1 goto +2;				\
816 	/* Branch always taken because w2 = -1 */	\
817 	if r2 == -1 goto +1;				\
818 	r0 /= 0;					\
819 	r0 = 0;						\
820 	exit;						\
821 "	:
822 	: __imm(bpf_get_prandom_u32)
823 	: __clobber_all);
824 }
825 
826 char _license[] SEC("license") = "GPL";
827