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