1f02ec3ffSYonghong Song // SPDX-License-Identifier: GPL-2.0
2f02ec3ffSYonghong Song
3f02ec3ffSYonghong Song #include <linux/bpf.h>
4f02ec3ffSYonghong Song #include <bpf/bpf_helpers.h>
5f02ec3ffSYonghong Song #include "bpf_misc.h"
6f02ec3ffSYonghong Song
7*0209fd51SPu Lehui #if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \
8*0209fd51SPu Lehui (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && __clang_major__ >= 18
9f02ec3ffSYonghong Song
10f02ec3ffSYonghong Song SEC("socket")
11f02ec3ffSYonghong Song __description("MOV32SX, S8")
12f02ec3ffSYonghong Song __success __success_unpriv __retval(0x23)
mov32sx_s8(void)13f02ec3ffSYonghong Song __naked void mov32sx_s8(void)
14f02ec3ffSYonghong Song {
15f02ec3ffSYonghong Song asm volatile (" \
16f02ec3ffSYonghong Song w0 = 0xff23; \
17f02ec3ffSYonghong Song w0 = (s8)w0; \
18f02ec3ffSYonghong Song exit; \
19f02ec3ffSYonghong Song " ::: __clobber_all);
20f02ec3ffSYonghong Song }
21f02ec3ffSYonghong Song
22f02ec3ffSYonghong Song SEC("socket")
23f02ec3ffSYonghong Song __description("MOV32SX, S16")
24f02ec3ffSYonghong Song __success __success_unpriv __retval(0xFFFFff23)
mov32sx_s16(void)25f02ec3ffSYonghong Song __naked void mov32sx_s16(void)
26f02ec3ffSYonghong Song {
27f02ec3ffSYonghong Song asm volatile (" \
28f02ec3ffSYonghong Song w0 = 0xff23; \
29f02ec3ffSYonghong Song w0 = (s16)w0; \
30f02ec3ffSYonghong Song exit; \
31f02ec3ffSYonghong Song " ::: __clobber_all);
32f02ec3ffSYonghong Song }
33f02ec3ffSYonghong Song
34f02ec3ffSYonghong Song SEC("socket")
35f02ec3ffSYonghong Song __description("MOV64SX, S8")
36f02ec3ffSYonghong Song __success __success_unpriv __retval(-2)
mov64sx_s8(void)37f02ec3ffSYonghong Song __naked void mov64sx_s8(void)
38f02ec3ffSYonghong Song {
39f02ec3ffSYonghong Song asm volatile (" \
40f02ec3ffSYonghong Song r0 = 0x1fe; \
41f02ec3ffSYonghong Song r0 = (s8)r0; \
42f02ec3ffSYonghong Song exit; \
43f02ec3ffSYonghong Song " ::: __clobber_all);
44f02ec3ffSYonghong Song }
45f02ec3ffSYonghong Song
46f02ec3ffSYonghong Song SEC("socket")
47f02ec3ffSYonghong Song __description("MOV64SX, S16")
48f02ec3ffSYonghong Song __success __success_unpriv __retval(0xf23)
mov64sx_s16(void)49f02ec3ffSYonghong Song __naked void mov64sx_s16(void)
50f02ec3ffSYonghong Song {
51f02ec3ffSYonghong Song asm volatile (" \
52f02ec3ffSYonghong Song r0 = 0xf0f23; \
53f02ec3ffSYonghong Song r0 = (s16)r0; \
54f02ec3ffSYonghong Song exit; \
55f02ec3ffSYonghong Song " ::: __clobber_all);
56f02ec3ffSYonghong Song }
57f02ec3ffSYonghong Song
58f02ec3ffSYonghong Song SEC("socket")
59f02ec3ffSYonghong Song __description("MOV64SX, S32")
60f02ec3ffSYonghong Song __success __success_unpriv __retval(-1)
mov64sx_s32(void)61f02ec3ffSYonghong Song __naked void mov64sx_s32(void)
62f02ec3ffSYonghong Song {
63f02ec3ffSYonghong Song asm volatile (" \
64f02ec3ffSYonghong Song r0 = 0xfffffffe; \
65f02ec3ffSYonghong Song r0 = (s32)r0; \
66f02ec3ffSYonghong Song r0 >>= 1; \
67f02ec3ffSYonghong Song exit; \
68f02ec3ffSYonghong Song " ::: __clobber_all);
69f02ec3ffSYonghong Song }
70f02ec3ffSYonghong Song
71f02ec3ffSYonghong Song SEC("socket")
72f02ec3ffSYonghong Song __description("MOV32SX, S8, range_check")
73f02ec3ffSYonghong Song __success __success_unpriv __retval(1)
mov32sx_s8_range(void)74f02ec3ffSYonghong Song __naked void mov32sx_s8_range(void)
75f02ec3ffSYonghong Song {
76f02ec3ffSYonghong Song asm volatile (" \
77f02ec3ffSYonghong Song call %[bpf_get_prandom_u32]; \
78f02ec3ffSYonghong Song w1 = (s8)w0; \
79f02ec3ffSYonghong Song /* w1 with s8 range */ \
80f02ec3ffSYonghong Song if w1 s> 0x7f goto l0_%=; \
81f02ec3ffSYonghong Song if w1 s< -0x80 goto l0_%=; \
82f02ec3ffSYonghong Song r0 = 1; \
83f02ec3ffSYonghong Song l1_%=: \
84f02ec3ffSYonghong Song exit; \
85f02ec3ffSYonghong Song l0_%=: \
86f02ec3ffSYonghong Song r0 = 2; \
87f02ec3ffSYonghong Song goto l1_%=; \
88f02ec3ffSYonghong Song " :
89f02ec3ffSYonghong Song : __imm(bpf_get_prandom_u32)
90f02ec3ffSYonghong Song : __clobber_all);
91f02ec3ffSYonghong Song }
92f02ec3ffSYonghong Song
93f02ec3ffSYonghong Song SEC("socket")
94f02ec3ffSYonghong Song __description("MOV32SX, S16, range_check")
95f02ec3ffSYonghong Song __success __success_unpriv __retval(1)
mov32sx_s16_range(void)96f02ec3ffSYonghong Song __naked void mov32sx_s16_range(void)
97f02ec3ffSYonghong Song {
98f02ec3ffSYonghong Song asm volatile (" \
99f02ec3ffSYonghong Song call %[bpf_get_prandom_u32]; \
100f02ec3ffSYonghong Song w1 = (s16)w0; \
101f02ec3ffSYonghong Song /* w1 with s16 range */ \
102f02ec3ffSYonghong Song if w1 s> 0x7fff goto l0_%=; \
103f02ec3ffSYonghong Song if w1 s< -0x80ff goto l0_%=; \
104f02ec3ffSYonghong Song r0 = 1; \
105f02ec3ffSYonghong Song l1_%=: \
106f02ec3ffSYonghong Song exit; \
107f02ec3ffSYonghong Song l0_%=: \
108f02ec3ffSYonghong Song r0 = 2; \
109f02ec3ffSYonghong Song goto l1_%=; \
110f02ec3ffSYonghong Song " :
111f02ec3ffSYonghong Song : __imm(bpf_get_prandom_u32)
112f02ec3ffSYonghong Song : __clobber_all);
113f02ec3ffSYonghong Song }
114f02ec3ffSYonghong Song
115f02ec3ffSYonghong Song SEC("socket")
116f02ec3ffSYonghong Song __description("MOV32SX, S16, range_check 2")
117f02ec3ffSYonghong Song __success __success_unpriv __retval(1)
mov32sx_s16_range_2(void)118f02ec3ffSYonghong Song __naked void mov32sx_s16_range_2(void)
119f02ec3ffSYonghong Song {
120f02ec3ffSYonghong Song asm volatile (" \
121f02ec3ffSYonghong Song r1 = 65535; \
122f02ec3ffSYonghong Song w2 = (s16)w1; \
123f02ec3ffSYonghong Song r2 >>= 1; \
124f02ec3ffSYonghong Song if r2 != 0x7fffFFFF goto l0_%=; \
125f02ec3ffSYonghong Song r0 = 1; \
126f02ec3ffSYonghong Song l1_%=: \
127f02ec3ffSYonghong Song exit; \
128f02ec3ffSYonghong Song l0_%=: \
129f02ec3ffSYonghong Song r0 = 0; \
130f02ec3ffSYonghong Song goto l1_%=; \
131f02ec3ffSYonghong Song " :
132f02ec3ffSYonghong Song : __imm(bpf_get_prandom_u32)
133f02ec3ffSYonghong Song : __clobber_all);
134f02ec3ffSYonghong Song }
135f02ec3ffSYonghong Song
136f02ec3ffSYonghong Song SEC("socket")
137f02ec3ffSYonghong Song __description("MOV64SX, S8, range_check")
138f02ec3ffSYonghong Song __success __success_unpriv __retval(1)
mov64sx_s8_range(void)139f02ec3ffSYonghong Song __naked void mov64sx_s8_range(void)
140f02ec3ffSYonghong Song {
141f02ec3ffSYonghong Song asm volatile (" \
142f02ec3ffSYonghong Song call %[bpf_get_prandom_u32]; \
143f02ec3ffSYonghong Song r1 = (s8)r0; \
144f02ec3ffSYonghong Song /* r1 with s8 range */ \
145f02ec3ffSYonghong Song if r1 s> 0x7f goto l0_%=; \
146f02ec3ffSYonghong Song if r1 s< -0x80 goto l0_%=; \
147f02ec3ffSYonghong Song r0 = 1; \
148f02ec3ffSYonghong Song l1_%=: \
149f02ec3ffSYonghong Song exit; \
150f02ec3ffSYonghong Song l0_%=: \
151f02ec3ffSYonghong Song r0 = 2; \
152f02ec3ffSYonghong Song goto l1_%=; \
153f02ec3ffSYonghong Song " :
154f02ec3ffSYonghong Song : __imm(bpf_get_prandom_u32)
155f02ec3ffSYonghong Song : __clobber_all);
156f02ec3ffSYonghong Song }
157f02ec3ffSYonghong Song
158f02ec3ffSYonghong Song SEC("socket")
159f02ec3ffSYonghong Song __description("MOV64SX, S16, range_check")
160f02ec3ffSYonghong Song __success __success_unpriv __retval(1)
mov64sx_s16_range(void)161f02ec3ffSYonghong Song __naked void mov64sx_s16_range(void)
162f02ec3ffSYonghong Song {
163f02ec3ffSYonghong Song asm volatile (" \
164f02ec3ffSYonghong Song call %[bpf_get_prandom_u32]; \
165f02ec3ffSYonghong Song r1 = (s16)r0; \
166f02ec3ffSYonghong Song /* r1 with s16 range */ \
167f02ec3ffSYonghong Song if r1 s> 0x7fff goto l0_%=; \
168f02ec3ffSYonghong Song if r1 s< -0x8000 goto l0_%=; \
169f02ec3ffSYonghong Song r0 = 1; \
170f02ec3ffSYonghong Song l1_%=: \
171f02ec3ffSYonghong Song exit; \
172f02ec3ffSYonghong Song l0_%=: \
173f02ec3ffSYonghong Song r0 = 2; \
174f02ec3ffSYonghong Song goto l1_%=; \
175f02ec3ffSYonghong Song " :
176f02ec3ffSYonghong Song : __imm(bpf_get_prandom_u32)
177f02ec3ffSYonghong Song : __clobber_all);
178f02ec3ffSYonghong Song }
179f02ec3ffSYonghong Song
180f02ec3ffSYonghong Song SEC("socket")
181f02ec3ffSYonghong Song __description("MOV64SX, S32, range_check")
182f02ec3ffSYonghong Song __success __success_unpriv __retval(1)
mov64sx_s32_range(void)183f02ec3ffSYonghong Song __naked void mov64sx_s32_range(void)
184f02ec3ffSYonghong Song {
185f02ec3ffSYonghong Song asm volatile (" \
186f02ec3ffSYonghong Song call %[bpf_get_prandom_u32]; \
187f02ec3ffSYonghong Song r1 = (s32)r0; \
188f02ec3ffSYonghong Song /* r1 with s32 range */ \
189f02ec3ffSYonghong Song if r1 s> 0x7fffffff goto l0_%=; \
190f02ec3ffSYonghong Song if r1 s< -0x80000000 goto l0_%=; \
191f02ec3ffSYonghong Song r0 = 1; \
192f02ec3ffSYonghong Song l1_%=: \
193f02ec3ffSYonghong Song exit; \
194f02ec3ffSYonghong Song l0_%=: \
195f02ec3ffSYonghong Song r0 = 2; \
196f02ec3ffSYonghong Song goto l1_%=; \
197f02ec3ffSYonghong Song " :
198f02ec3ffSYonghong Song : __imm(bpf_get_prandom_u32)
199f02ec3ffSYonghong Song : __clobber_all);
200f02ec3ffSYonghong Song }
201f02ec3ffSYonghong Song
202a5c0a42bSYonghong Song SEC("socket")
203a5c0a42bSYonghong Song __description("MOV64SX, S16, R10 Sign Extension")
204a5c0a42bSYonghong Song __failure __msg("R1 type=scalar expected=fp, pkt, pkt_meta, map_key, map_value, mem, ringbuf_mem, buf, trusted_ptr_")
205a5c0a42bSYonghong Song __failure_unpriv __msg_unpriv("R10 sign-extension part of pointer")
mov64sx_s16_r10(void)206a5c0a42bSYonghong Song __naked void mov64sx_s16_r10(void)
207a5c0a42bSYonghong Song {
208a5c0a42bSYonghong Song asm volatile (" \
209a5c0a42bSYonghong Song r1 = 553656332; \
210a5c0a42bSYonghong Song *(u32 *)(r10 - 8) = r1; \
211a5c0a42bSYonghong Song r1 = (s16)r10; \
212a5c0a42bSYonghong Song r1 += -8; \
213a5c0a42bSYonghong Song r2 = 3; \
214a5c0a42bSYonghong Song if r2 <= r1 goto l0_%=; \
215a5c0a42bSYonghong Song l0_%=: \
216a5c0a42bSYonghong Song call %[bpf_trace_printk]; \
217a5c0a42bSYonghong Song r0 = 0; \
218a5c0a42bSYonghong Song exit; \
219a5c0a42bSYonghong Song " :
220a5c0a42bSYonghong Song : __imm(bpf_trace_printk)
221a5c0a42bSYonghong Song : __clobber_all);
222a5c0a42bSYonghong Song }
223a5c0a42bSYonghong Song
224f02ec3ffSYonghong Song #else
225f02ec3ffSYonghong Song
226f02ec3ffSYonghong Song SEC("socket")
227f02ec3ffSYonghong Song __description("cpuv4 is not supported by compiler or jit, use a dummy test")
228f02ec3ffSYonghong Song __success
dummy_test(void)229f02ec3ffSYonghong Song int dummy_test(void)
230f02ec3ffSYonghong Song {
231f02ec3ffSYonghong Song return 0;
232f02ec3ffSYonghong Song }
233f02ec3ffSYonghong Song
234f02ec3ffSYonghong Song #endif
235f02ec3ffSYonghong Song
236f02ec3ffSYonghong Song char _license[] SEC("license") = "GPL";
237