162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <linux/bpf.h> 462306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 562306a36Sopenharmony_ci#include "bpf_misc.h" 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#if (defined(__TARGET_ARCH_arm64) || defined(__TARGET_ARCH_x86) || \ 862306a36Sopenharmony_ci (defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && __clang_major__ >= 18 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ciSEC("socket") 1162306a36Sopenharmony_ci__description("LDSX, S8") 1262306a36Sopenharmony_ci__success __success_unpriv __retval(-2) 1362306a36Sopenharmony_ci__naked void ldsx_s8(void) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci asm volatile (" \ 1662306a36Sopenharmony_ci r1 = 0x3fe; \ 1762306a36Sopenharmony_ci *(u64 *)(r10 - 8) = r1; \ 1862306a36Sopenharmony_ci r0 = *(s8 *)(r10 - 8); \ 1962306a36Sopenharmony_ci exit; \ 2062306a36Sopenharmony_ci" ::: __clobber_all); 2162306a36Sopenharmony_ci} 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciSEC("socket") 2462306a36Sopenharmony_ci__description("LDSX, S16") 2562306a36Sopenharmony_ci__success __success_unpriv __retval(-2) 2662306a36Sopenharmony_ci__naked void ldsx_s16(void) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci asm volatile (" \ 2962306a36Sopenharmony_ci r1 = 0x3fffe; \ 3062306a36Sopenharmony_ci *(u64 *)(r10 - 8) = r1; \ 3162306a36Sopenharmony_ci r0 = *(s16 *)(r10 - 8); \ 3262306a36Sopenharmony_ci exit; \ 3362306a36Sopenharmony_ci" ::: __clobber_all); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ciSEC("socket") 3762306a36Sopenharmony_ci__description("LDSX, S32") 3862306a36Sopenharmony_ci__success __success_unpriv __retval(-1) 3962306a36Sopenharmony_ci__naked void ldsx_s32(void) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci asm volatile (" \ 4262306a36Sopenharmony_ci r1 = 0xfffffffe; \ 4362306a36Sopenharmony_ci *(u64 *)(r10 - 8) = r1; \ 4462306a36Sopenharmony_ci r0 = *(s32 *)(r10 - 8); \ 4562306a36Sopenharmony_ci r0 >>= 1; \ 4662306a36Sopenharmony_ci exit; \ 4762306a36Sopenharmony_ci" ::: __clobber_all); 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciSEC("socket") 5162306a36Sopenharmony_ci__description("LDSX, S8 range checking, privileged") 5262306a36Sopenharmony_ci__log_level(2) __success __retval(1) 5362306a36Sopenharmony_ci__msg("R1_w=scalar(smin=-128,smax=127)") 5462306a36Sopenharmony_ci__naked void ldsx_s8_range_priv(void) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci asm volatile (" \ 5762306a36Sopenharmony_ci call %[bpf_get_prandom_u32]; \ 5862306a36Sopenharmony_ci *(u64 *)(r10 - 8) = r0; \ 5962306a36Sopenharmony_ci r1 = *(s8 *)(r10 - 8); \ 6062306a36Sopenharmony_ci /* r1 with s8 range */ \ 6162306a36Sopenharmony_ci if r1 s> 0x7f goto l0_%=; \ 6262306a36Sopenharmony_ci if r1 s< -0x80 goto l0_%=; \ 6362306a36Sopenharmony_ci r0 = 1; \ 6462306a36Sopenharmony_cil1_%=: \ 6562306a36Sopenharmony_ci exit; \ 6662306a36Sopenharmony_cil0_%=: \ 6762306a36Sopenharmony_ci r0 = 2; \ 6862306a36Sopenharmony_ci goto l1_%=; \ 6962306a36Sopenharmony_ci" : 7062306a36Sopenharmony_ci : __imm(bpf_get_prandom_u32) 7162306a36Sopenharmony_ci : __clobber_all); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ciSEC("socket") 7562306a36Sopenharmony_ci__description("LDSX, S16 range checking") 7662306a36Sopenharmony_ci__success __success_unpriv __retval(1) 7762306a36Sopenharmony_ci__naked void ldsx_s16_range(void) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci asm volatile (" \ 8062306a36Sopenharmony_ci call %[bpf_get_prandom_u32]; \ 8162306a36Sopenharmony_ci *(u64 *)(r10 - 8) = r0; \ 8262306a36Sopenharmony_ci r1 = *(s16 *)(r10 - 8); \ 8362306a36Sopenharmony_ci /* r1 with s16 range */ \ 8462306a36Sopenharmony_ci if r1 s> 0x7fff goto l0_%=; \ 8562306a36Sopenharmony_ci if r1 s< -0x8000 goto l0_%=; \ 8662306a36Sopenharmony_ci r0 = 1; \ 8762306a36Sopenharmony_cil1_%=: \ 8862306a36Sopenharmony_ci exit; \ 8962306a36Sopenharmony_cil0_%=: \ 9062306a36Sopenharmony_ci r0 = 2; \ 9162306a36Sopenharmony_ci goto l1_%=; \ 9262306a36Sopenharmony_ci" : 9362306a36Sopenharmony_ci : __imm(bpf_get_prandom_u32) 9462306a36Sopenharmony_ci : __clobber_all); 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciSEC("socket") 9862306a36Sopenharmony_ci__description("LDSX, S32 range checking") 9962306a36Sopenharmony_ci__success __success_unpriv __retval(1) 10062306a36Sopenharmony_ci__naked void ldsx_s32_range(void) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci asm volatile (" \ 10362306a36Sopenharmony_ci call %[bpf_get_prandom_u32]; \ 10462306a36Sopenharmony_ci *(u64 *)(r10 - 8) = r0; \ 10562306a36Sopenharmony_ci r1 = *(s32 *)(r10 - 8); \ 10662306a36Sopenharmony_ci /* r1 with s16 range */ \ 10762306a36Sopenharmony_ci if r1 s> 0x7fffFFFF goto l0_%=; \ 10862306a36Sopenharmony_ci if r1 s< -0x80000000 goto l0_%=; \ 10962306a36Sopenharmony_ci r0 = 1; \ 11062306a36Sopenharmony_cil1_%=: \ 11162306a36Sopenharmony_ci exit; \ 11262306a36Sopenharmony_cil0_%=: \ 11362306a36Sopenharmony_ci r0 = 2; \ 11462306a36Sopenharmony_ci goto l1_%=; \ 11562306a36Sopenharmony_ci" : 11662306a36Sopenharmony_ci : __imm(bpf_get_prandom_u32) 11762306a36Sopenharmony_ci : __clobber_all); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci#else 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ciSEC("socket") 12362306a36Sopenharmony_ci__description("cpuv4 is not supported by compiler or jit, use a dummy test") 12462306a36Sopenharmony_ci__success 12562306a36Sopenharmony_ciint dummy_test(void) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci return 0; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#endif 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 133