1147c8f44SYonghong Song // SPDX-License-Identifier: GPL-2.0
2147c8f44SYonghong Song 
3147c8f44SYonghong Song #include <linux/bpf.h>
4147c8f44SYonghong Song #include <bpf/bpf_helpers.h>
5147c8f44SYonghong Song #include "bpf_misc.h"
6147c8f44SYonghong 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
9147c8f44SYonghong Song 
10147c8f44SYonghong Song SEC("socket")
11147c8f44SYonghong Song __description("LDSX, S8")
12147c8f44SYonghong Song __success __success_unpriv __retval(-2)
ldsx_s8(void)13147c8f44SYonghong Song __naked void ldsx_s8(void)
14147c8f44SYonghong Song {
15147c8f44SYonghong Song 	asm volatile ("					\
16147c8f44SYonghong Song 	r1 = 0x3fe;					\
17147c8f44SYonghong Song 	*(u64 *)(r10 - 8) = r1;				\
18147c8f44SYonghong Song 	r0 = *(s8 *)(r10 - 8);				\
19147c8f44SYonghong Song 	exit;						\
20147c8f44SYonghong Song "	::: __clobber_all);
21147c8f44SYonghong Song }
22147c8f44SYonghong Song 
23147c8f44SYonghong Song SEC("socket")
24147c8f44SYonghong Song __description("LDSX, S16")
25147c8f44SYonghong Song __success __success_unpriv __retval(-2)
ldsx_s16(void)26147c8f44SYonghong Song __naked void ldsx_s16(void)
27147c8f44SYonghong Song {
28147c8f44SYonghong Song 	asm volatile ("					\
29147c8f44SYonghong Song 	r1 = 0x3fffe;					\
30147c8f44SYonghong Song 	*(u64 *)(r10 - 8) = r1;				\
31147c8f44SYonghong Song 	r0 = *(s16 *)(r10 - 8);				\
32147c8f44SYonghong Song 	exit;						\
33147c8f44SYonghong Song "	::: __clobber_all);
34147c8f44SYonghong Song }
35147c8f44SYonghong Song 
36147c8f44SYonghong Song SEC("socket")
37147c8f44SYonghong Song __description("LDSX, S32")
38147c8f44SYonghong Song __success __success_unpriv __retval(-1)
ldsx_s32(void)39147c8f44SYonghong Song __naked void ldsx_s32(void)
40147c8f44SYonghong Song {
41147c8f44SYonghong Song 	asm volatile ("					\
42147c8f44SYonghong Song 	r1 = 0xfffffffe;				\
43147c8f44SYonghong Song 	*(u64 *)(r10 - 8) = r1;				\
44147c8f44SYonghong Song 	r0 = *(s32 *)(r10 - 8);				\
45147c8f44SYonghong Song 	r0 >>= 1;					\
46147c8f44SYonghong Song 	exit;						\
47147c8f44SYonghong Song "	::: __clobber_all);
48147c8f44SYonghong Song }
49147c8f44SYonghong Song 
50147c8f44SYonghong Song SEC("socket")
51147c8f44SYonghong Song __description("LDSX, S8 range checking, privileged")
52147c8f44SYonghong Song __log_level(2) __success __retval(1)
53147c8f44SYonghong Song __msg("R1_w=scalar(smin=-128,smax=127)")
ldsx_s8_range_priv(void)54147c8f44SYonghong Song __naked void ldsx_s8_range_priv(void)
55147c8f44SYonghong Song {
56147c8f44SYonghong Song 	asm volatile ("					\
57147c8f44SYonghong Song 	call %[bpf_get_prandom_u32];			\
58147c8f44SYonghong Song 	*(u64 *)(r10 - 8) = r0;				\
59147c8f44SYonghong Song 	r1 = *(s8 *)(r10 - 8);				\
60147c8f44SYonghong Song 	/* r1 with s8 range */				\
61147c8f44SYonghong Song 	if r1 s> 0x7f goto l0_%=;			\
62147c8f44SYonghong Song 	if r1 s< -0x80 goto l0_%=;			\
63147c8f44SYonghong Song 	r0 = 1;						\
64147c8f44SYonghong Song l1_%=:							\
65147c8f44SYonghong Song 	exit;						\
66147c8f44SYonghong Song l0_%=:							\
67147c8f44SYonghong Song 	r0 = 2;						\
68147c8f44SYonghong Song 	goto l1_%=;					\
69147c8f44SYonghong Song "	:
70147c8f44SYonghong Song 	: __imm(bpf_get_prandom_u32)
71147c8f44SYonghong Song 	: __clobber_all);
72147c8f44SYonghong Song }
73147c8f44SYonghong Song 
74147c8f44SYonghong Song SEC("socket")
75147c8f44SYonghong Song __description("LDSX, S16 range checking")
76147c8f44SYonghong Song __success __success_unpriv __retval(1)
ldsx_s16_range(void)77147c8f44SYonghong Song __naked void ldsx_s16_range(void)
78147c8f44SYonghong Song {
79147c8f44SYonghong Song 	asm volatile ("					\
80147c8f44SYonghong Song 	call %[bpf_get_prandom_u32];			\
81147c8f44SYonghong Song 	*(u64 *)(r10 - 8) = r0;				\
82147c8f44SYonghong Song 	r1 = *(s16 *)(r10 - 8);				\
83147c8f44SYonghong Song 	/* r1 with s16 range */				\
84147c8f44SYonghong Song 	if r1 s> 0x7fff goto l0_%=;			\
85147c8f44SYonghong Song 	if r1 s< -0x8000 goto l0_%=;			\
86147c8f44SYonghong Song 	r0 = 1;						\
87147c8f44SYonghong Song l1_%=:							\
88147c8f44SYonghong Song 	exit;						\
89147c8f44SYonghong Song l0_%=:							\
90147c8f44SYonghong Song 	r0 = 2;						\
91147c8f44SYonghong Song 	goto l1_%=;					\
92147c8f44SYonghong Song "	:
93147c8f44SYonghong Song 	: __imm(bpf_get_prandom_u32)
94147c8f44SYonghong Song 	: __clobber_all);
95147c8f44SYonghong Song }
96147c8f44SYonghong Song 
97147c8f44SYonghong Song SEC("socket")
98147c8f44SYonghong Song __description("LDSX, S32 range checking")
99147c8f44SYonghong Song __success __success_unpriv __retval(1)
ldsx_s32_range(void)100147c8f44SYonghong Song __naked void ldsx_s32_range(void)
101147c8f44SYonghong Song {
102147c8f44SYonghong Song 	asm volatile ("					\
103147c8f44SYonghong Song 	call %[bpf_get_prandom_u32];			\
104147c8f44SYonghong Song 	*(u64 *)(r10 - 8) = r0;				\
105147c8f44SYonghong Song 	r1 = *(s32 *)(r10 - 8);				\
106147c8f44SYonghong Song 	/* r1 with s16 range */				\
107147c8f44SYonghong Song 	if r1 s> 0x7fffFFFF goto l0_%=;			\
108147c8f44SYonghong Song 	if r1 s< -0x80000000 goto l0_%=;		\
109147c8f44SYonghong Song 	r0 = 1;						\
110147c8f44SYonghong Song l1_%=:							\
111147c8f44SYonghong Song 	exit;						\
112147c8f44SYonghong Song l0_%=:							\
113147c8f44SYonghong Song 	r0 = 2;						\
114147c8f44SYonghong Song 	goto l1_%=;					\
115147c8f44SYonghong Song "	:
116147c8f44SYonghong Song 	: __imm(bpf_get_prandom_u32)
117147c8f44SYonghong Song 	: __clobber_all);
118147c8f44SYonghong Song }
119147c8f44SYonghong Song 
120147c8f44SYonghong Song #else
121147c8f44SYonghong Song 
122147c8f44SYonghong Song SEC("socket")
123147c8f44SYonghong Song __description("cpuv4 is not supported by compiler or jit, use a dummy test")
124147c8f44SYonghong Song __success
dummy_test(void)125147c8f44SYonghong Song int dummy_test(void)
126147c8f44SYonghong Song {
127147c8f44SYonghong Song 	return 0;
128147c8f44SYonghong Song }
129147c8f44SYonghong Song 
130147c8f44SYonghong Song #endif
131147c8f44SYonghong Song 
132147c8f44SYonghong Song char _license[] SEC("license") = "GPL";
133