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