xref: /openbmc/linux/tools/testing/selftests/bpf/progs/verifier_movsx.c (revision a9ca9f9ceff382b58b488248f0c0da9e157f5d06)
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_x86) && __clang_major__ >= 18
8 
9 SEC("socket")
10 __description("MOV32SX, S8")
11 __success __success_unpriv __retval(0x23)
12 __naked void mov32sx_s8(void)
13 {
14 	asm volatile ("					\
15 	w0 = 0xff23;					\
16 	w0 = (s8)w0;					\
17 	exit;						\
18 "	::: __clobber_all);
19 }
20 
21 SEC("socket")
22 __description("MOV32SX, S16")
23 __success __success_unpriv __retval(0xFFFFff23)
24 __naked void mov32sx_s16(void)
25 {
26 	asm volatile ("					\
27 	w0 = 0xff23;					\
28 	w0 = (s16)w0;					\
29 	exit;						\
30 "	::: __clobber_all);
31 }
32 
33 SEC("socket")
34 __description("MOV64SX, S8")
35 __success __success_unpriv __retval(-2)
36 __naked void mov64sx_s8(void)
37 {
38 	asm volatile ("					\
39 	r0 = 0x1fe;					\
40 	r0 = (s8)r0;					\
41 	exit;						\
42 "	::: __clobber_all);
43 }
44 
45 SEC("socket")
46 __description("MOV64SX, S16")
47 __success __success_unpriv __retval(0xf23)
48 __naked void mov64sx_s16(void)
49 {
50 	asm volatile ("					\
51 	r0 = 0xf0f23;					\
52 	r0 = (s16)r0;					\
53 	exit;						\
54 "	::: __clobber_all);
55 }
56 
57 SEC("socket")
58 __description("MOV64SX, S32")
59 __success __success_unpriv __retval(-1)
60 __naked void mov64sx_s32(void)
61 {
62 	asm volatile ("					\
63 	r0 = 0xfffffffe;				\
64 	r0 = (s32)r0;					\
65 	r0 >>= 1;					\
66 	exit;						\
67 "	::: __clobber_all);
68 }
69 
70 SEC("socket")
71 __description("MOV32SX, S8, range_check")
72 __success __success_unpriv __retval(1)
73 __naked void mov32sx_s8_range(void)
74 {
75 	asm volatile ("					\
76 	call %[bpf_get_prandom_u32];			\
77 	w1 = (s8)w0;					\
78 	/* w1 with s8 range */				\
79 	if w1 s> 0x7f goto l0_%=;			\
80 	if w1 s< -0x80 goto l0_%=;			\
81 	r0 = 1;						\
82 l1_%=:							\
83 	exit;						\
84 l0_%=:							\
85 	r0 = 2;						\
86 	goto l1_%=;					\
87 "	:
88 	: __imm(bpf_get_prandom_u32)
89 	: __clobber_all);
90 }
91 
92 SEC("socket")
93 __description("MOV32SX, S16, range_check")
94 __success __success_unpriv __retval(1)
95 __naked void mov32sx_s16_range(void)
96 {
97 	asm volatile ("					\
98 	call %[bpf_get_prandom_u32];			\
99 	w1 = (s16)w0;					\
100 	/* w1 with s16 range */				\
101 	if w1 s> 0x7fff goto l0_%=;			\
102 	if w1 s< -0x80ff goto l0_%=;			\
103 	r0 = 1;						\
104 l1_%=:							\
105 	exit;						\
106 l0_%=:							\
107 	r0 = 2;						\
108 	goto l1_%=;					\
109 "	:
110 	: __imm(bpf_get_prandom_u32)
111 	: __clobber_all);
112 }
113 
114 SEC("socket")
115 __description("MOV32SX, S16, range_check 2")
116 __success __success_unpriv __retval(1)
117 __naked void mov32sx_s16_range_2(void)
118 {
119 	asm volatile ("					\
120 	r1 = 65535;					\
121 	w2 = (s16)w1;					\
122 	r2 >>= 1;					\
123 	if r2 != 0x7fffFFFF goto l0_%=;			\
124 	r0 = 1;						\
125 l1_%=:							\
126 	exit;						\
127 l0_%=:							\
128 	r0 = 0;						\
129 	goto l1_%=;					\
130 "	:
131 	: __imm(bpf_get_prandom_u32)
132 	: __clobber_all);
133 }
134 
135 SEC("socket")
136 __description("MOV64SX, S8, range_check")
137 __success __success_unpriv __retval(1)
138 __naked void mov64sx_s8_range(void)
139 {
140 	asm volatile ("					\
141 	call %[bpf_get_prandom_u32];			\
142 	r1 = (s8)r0;					\
143 	/* r1 with s8 range */				\
144 	if r1 s> 0x7f goto l0_%=;			\
145 	if r1 s< -0x80 goto l0_%=;			\
146 	r0 = 1;						\
147 l1_%=:							\
148 	exit;						\
149 l0_%=:							\
150 	r0 = 2;						\
151 	goto l1_%=;					\
152 "	:
153 	: __imm(bpf_get_prandom_u32)
154 	: __clobber_all);
155 }
156 
157 SEC("socket")
158 __description("MOV64SX, S16, range_check")
159 __success __success_unpriv __retval(1)
160 __naked void mov64sx_s16_range(void)
161 {
162 	asm volatile ("					\
163 	call %[bpf_get_prandom_u32];			\
164 	r1 = (s16)r0;					\
165 	/* r1 with s16 range */				\
166 	if r1 s> 0x7fff goto l0_%=;			\
167 	if r1 s< -0x8000 goto l0_%=;			\
168 	r0 = 1;						\
169 l1_%=:							\
170 	exit;						\
171 l0_%=:							\
172 	r0 = 2;						\
173 	goto l1_%=;					\
174 "	:
175 	: __imm(bpf_get_prandom_u32)
176 	: __clobber_all);
177 }
178 
179 SEC("socket")
180 __description("MOV64SX, S32, range_check")
181 __success __success_unpriv __retval(1)
182 __naked void mov64sx_s32_range(void)
183 {
184 	asm volatile ("					\
185 	call %[bpf_get_prandom_u32];			\
186 	r1 = (s32)r0;					\
187 	/* r1 with s32 range */				\
188 	if r1 s> 0x7fffffff goto l0_%=;			\
189 	if r1 s< -0x80000000 goto l0_%=;		\
190 	r0 = 1;						\
191 l1_%=:							\
192 	exit;						\
193 l0_%=:							\
194 	r0 = 2;						\
195 	goto l1_%=;					\
196 "	:
197 	: __imm(bpf_get_prandom_u32)
198 	: __clobber_all);
199 }
200 
201 #else
202 
203 SEC("socket")
204 __description("cpuv4 is not supported by compiler or jit, use a dummy test")
205 __success
206 int dummy_test(void)
207 {
208 	return 0;
209 }
210 
211 #endif
212 
213 char _license[] SEC("license") = "GPL";
214