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) || defined(__TARGET_ARCH_arm)) && \ 9 __clang_major__ >= 18 10 11 SEC("socket") 12 __description("LDSX, S8") 13 __success __success_unpriv __retval(-2) 14 __naked void ldsx_s8(void) 15 { 16 asm volatile (" \ 17 r1 = 0x3fe; \ 18 *(u64 *)(r10 - 8) = r1; \ 19 r0 = *(s8 *)(r10 - 8); \ 20 exit; \ 21 " ::: __clobber_all); 22 } 23 24 SEC("socket") 25 __description("LDSX, S16") 26 __success __success_unpriv __retval(-2) 27 __naked void ldsx_s16(void) 28 { 29 asm volatile (" \ 30 r1 = 0x3fffe; \ 31 *(u64 *)(r10 - 8) = r1; \ 32 r0 = *(s16 *)(r10 - 8); \ 33 exit; \ 34 " ::: __clobber_all); 35 } 36 37 SEC("socket") 38 __description("LDSX, S32") 39 __success __success_unpriv __retval(-1) 40 __naked void ldsx_s32(void) 41 { 42 asm volatile (" \ 43 r1 = 0xfffffffe; \ 44 *(u64 *)(r10 - 8) = r1; \ 45 r0 = *(s32 *)(r10 - 8); \ 46 r0 >>= 1; \ 47 exit; \ 48 " ::: __clobber_all); 49 } 50 51 SEC("socket") 52 __description("LDSX, S8 range checking, privileged") 53 __log_level(2) __success __retval(1) 54 __msg("R1_w=scalar(smin=-128,smax=127)") 55 __naked void ldsx_s8_range_priv(void) 56 { 57 asm volatile (" \ 58 call %[bpf_get_prandom_u32]; \ 59 *(u64 *)(r10 - 8) = r0; \ 60 r1 = *(s8 *)(r10 - 8); \ 61 /* r1 with s8 range */ \ 62 if r1 s> 0x7f goto l0_%=; \ 63 if r1 s< -0x80 goto l0_%=; \ 64 r0 = 1; \ 65 l1_%=: \ 66 exit; \ 67 l0_%=: \ 68 r0 = 2; \ 69 goto l1_%=; \ 70 " : 71 : __imm(bpf_get_prandom_u32) 72 : __clobber_all); 73 } 74 75 SEC("socket") 76 __description("LDSX, S16 range checking") 77 __success __success_unpriv __retval(1) 78 __naked void ldsx_s16_range(void) 79 { 80 asm volatile (" \ 81 call %[bpf_get_prandom_u32]; \ 82 *(u64 *)(r10 - 8) = r0; \ 83 r1 = *(s16 *)(r10 - 8); \ 84 /* r1 with s16 range */ \ 85 if r1 s> 0x7fff goto l0_%=; \ 86 if r1 s< -0x8000 goto l0_%=; \ 87 r0 = 1; \ 88 l1_%=: \ 89 exit; \ 90 l0_%=: \ 91 r0 = 2; \ 92 goto l1_%=; \ 93 " : 94 : __imm(bpf_get_prandom_u32) 95 : __clobber_all); 96 } 97 98 SEC("socket") 99 __description("LDSX, S32 range checking") 100 __success __success_unpriv __retval(1) 101 __naked void ldsx_s32_range(void) 102 { 103 asm volatile (" \ 104 call %[bpf_get_prandom_u32]; \ 105 *(u64 *)(r10 - 8) = r0; \ 106 r1 = *(s32 *)(r10 - 8); \ 107 /* r1 with s16 range */ \ 108 if r1 s> 0x7fffFFFF goto l0_%=; \ 109 if r1 s< -0x80000000 goto l0_%=; \ 110 r0 = 1; \ 111 l1_%=: \ 112 exit; \ 113 l0_%=: \ 114 r0 = 2; \ 115 goto l1_%=; \ 116 " : 117 : __imm(bpf_get_prandom_u32) 118 : __clobber_all); 119 } 120 121 #else 122 123 SEC("socket") 124 __description("cpuv4 is not supported by compiler or jit, use a dummy test") 125 __success 126 int dummy_test(void) 127 { 128 return 0; 129 } 130 131 #endif 132 133 char _license[] SEC("license") = "GPL"; 134