xref: /linux/tools/testing/selftests/bpf/progs/verifier_ldsx.c (revision 788f63c4dc1780c84deb5fe820f6446c28364a0d)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/bpf.h>
4 #include <bpf/bpf_helpers.h>
5 #include "bpf_misc.h"
6 
7 #if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
8 	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64) || defined(__TARGET_ARCH_arm)) && \
9 	__clang_major__ >= 18
10 
11 SEC("socket")
12 __description("LDSX, S8")
13 __success __success_unpriv __retval(-2)
14 __naked void ldsx_s8(void)
15 {
16 	asm volatile ("					\
17 	r1 = 0x3fe;					\
18 	*(u64 *)(r10 - 8) = r1;				\
19 	r0 = *(s8 *)(r10 - 8);				\
20 	exit;						\
21 "	::: __clobber_all);
22 }
23 
24 SEC("socket")
25 __description("LDSX, S16")
26 __success __success_unpriv __retval(-2)
27 __naked void ldsx_s16(void)
28 {
29 	asm volatile ("					\
30 	r1 = 0x3fffe;					\
31 	*(u64 *)(r10 - 8) = r1;				\
32 	r0 = *(s16 *)(r10 - 8);				\
33 	exit;						\
34 "	::: __clobber_all);
35 }
36 
37 SEC("socket")
38 __description("LDSX, S32")
39 __success __success_unpriv __retval(-1)
40 __naked void ldsx_s32(void)
41 {
42 	asm volatile ("					\
43 	r1 = 0xfffffffe;				\
44 	*(u64 *)(r10 - 8) = r1;				\
45 	r0 = *(s32 *)(r10 - 8);				\
46 	r0 >>= 1;					\
47 	exit;						\
48 "	::: __clobber_all);
49 }
50 
51 SEC("socket")
52 __description("LDSX, S8 range checking, privileged")
53 __log_level(2) __success __retval(1)
54 __msg("R1_w=scalar(smin=-128,smax=127)")
55 __naked void ldsx_s8_range_priv(void)
56 {
57 	asm volatile ("					\
58 	call %[bpf_get_prandom_u32];			\
59 	*(u64 *)(r10 - 8) = r0;				\
60 	r1 = *(s8 *)(r10 - 8);				\
61 	/* r1 with s8 range */				\
62 	if r1 s> 0x7f goto l0_%=;			\
63 	if r1 s< -0x80 goto l0_%=;			\
64 	r0 = 1;						\
65 l1_%=:							\
66 	exit;						\
67 l0_%=:							\
68 	r0 = 2;						\
69 	goto l1_%=;					\
70 "	:
71 	: __imm(bpf_get_prandom_u32)
72 	: __clobber_all);
73 }
74 
75 SEC("socket")
76 __description("LDSX, S16 range checking")
77 __success __success_unpriv __retval(1)
78 __naked void ldsx_s16_range(void)
79 {
80 	asm volatile ("					\
81 	call %[bpf_get_prandom_u32];			\
82 	*(u64 *)(r10 - 8) = r0;				\
83 	r1 = *(s16 *)(r10 - 8);				\
84 	/* r1 with s16 range */				\
85 	if r1 s> 0x7fff goto l0_%=;			\
86 	if r1 s< -0x8000 goto l0_%=;			\
87 	r0 = 1;						\
88 l1_%=:							\
89 	exit;						\
90 l0_%=:							\
91 	r0 = 2;						\
92 	goto l1_%=;					\
93 "	:
94 	: __imm(bpf_get_prandom_u32)
95 	: __clobber_all);
96 }
97 
98 SEC("socket")
99 __description("LDSX, S32 range checking")
100 __success __success_unpriv __retval(1)
101 __naked void ldsx_s32_range(void)
102 {
103 	asm volatile ("					\
104 	call %[bpf_get_prandom_u32];			\
105 	*(u64 *)(r10 - 8) = r0;				\
106 	r1 = *(s32 *)(r10 - 8);				\
107 	/* r1 with s16 range */				\
108 	if r1 s> 0x7fffFFFF goto l0_%=;			\
109 	if r1 s< -0x80000000 goto l0_%=;		\
110 	r0 = 1;						\
111 l1_%=:							\
112 	exit;						\
113 l0_%=:							\
114 	r0 = 2;						\
115 	goto l1_%=;					\
116 "	:
117 	: __imm(bpf_get_prandom_u32)
118 	: __clobber_all);
119 }
120 
121 #else
122 
123 SEC("socket")
124 __description("cpuv4 is not supported by compiler or jit, use a dummy test")
125 __success
126 int dummy_test(void)
127 {
128 	return 0;
129 }
130 
131 #endif
132 
133 char _license[] SEC("license") = "GPL";
134