162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Converted from tools/testing/selftests/bpf/verifier/xadd.c */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/bpf.h> 562306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 662306a36Sopenharmony_ci#include "bpf_misc.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_cistruct { 962306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_HASH); 1062306a36Sopenharmony_ci __uint(max_entries, 1); 1162306a36Sopenharmony_ci __type(key, long long); 1262306a36Sopenharmony_ci __type(value, long long); 1362306a36Sopenharmony_ci} map_hash_8b SEC(".maps"); 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciSEC("tc") 1662306a36Sopenharmony_ci__description("xadd/w check unaligned stack") 1762306a36Sopenharmony_ci__failure __msg("misaligned stack access off") 1862306a36Sopenharmony_ci__naked void xadd_w_check_unaligned_stack(void) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci asm volatile (" \ 2162306a36Sopenharmony_ci r0 = 1; \ 2262306a36Sopenharmony_ci *(u64*)(r10 - 8) = r0; \ 2362306a36Sopenharmony_ci lock *(u32 *)(r10 - 7) += w0; \ 2462306a36Sopenharmony_ci r0 = *(u64*)(r10 - 8); \ 2562306a36Sopenharmony_ci exit; \ 2662306a36Sopenharmony_ci" ::: __clobber_all); 2762306a36Sopenharmony_ci} 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciSEC("tc") 3062306a36Sopenharmony_ci__description("xadd/w check unaligned map") 3162306a36Sopenharmony_ci__failure __msg("misaligned value access off") 3262306a36Sopenharmony_ci__naked void xadd_w_check_unaligned_map(void) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci asm volatile (" \ 3562306a36Sopenharmony_ci r1 = 0; \ 3662306a36Sopenharmony_ci *(u64*)(r10 - 8) = r1; \ 3762306a36Sopenharmony_ci r2 = r10; \ 3862306a36Sopenharmony_ci r2 += -8; \ 3962306a36Sopenharmony_ci r1 = %[map_hash_8b] ll; \ 4062306a36Sopenharmony_ci call %[bpf_map_lookup_elem]; \ 4162306a36Sopenharmony_ci if r0 != 0 goto l0_%=; \ 4262306a36Sopenharmony_ci exit; \ 4362306a36Sopenharmony_cil0_%=: r1 = 1; \ 4462306a36Sopenharmony_ci lock *(u32 *)(r0 + 3) += w1; \ 4562306a36Sopenharmony_ci r0 = *(u32*)(r0 + 3); \ 4662306a36Sopenharmony_ci exit; \ 4762306a36Sopenharmony_ci" : 4862306a36Sopenharmony_ci : __imm(bpf_map_lookup_elem), 4962306a36Sopenharmony_ci __imm_addr(map_hash_8b) 5062306a36Sopenharmony_ci : __clobber_all); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ciSEC("xdp") 5462306a36Sopenharmony_ci__description("xadd/w check unaligned pkt") 5562306a36Sopenharmony_ci__failure __msg("BPF_ATOMIC stores into R2 pkt is not allowed") 5662306a36Sopenharmony_ci__flag(BPF_F_ANY_ALIGNMENT) 5762306a36Sopenharmony_ci__naked void xadd_w_check_unaligned_pkt(void) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci asm volatile (" \ 6062306a36Sopenharmony_ci r2 = *(u32*)(r1 + %[xdp_md_data]); \ 6162306a36Sopenharmony_ci r3 = *(u32*)(r1 + %[xdp_md_data_end]); \ 6262306a36Sopenharmony_ci r1 = r2; \ 6362306a36Sopenharmony_ci r1 += 8; \ 6462306a36Sopenharmony_ci if r1 < r3 goto l0_%=; \ 6562306a36Sopenharmony_ci r0 = 99; \ 6662306a36Sopenharmony_ci goto l1_%=; \ 6762306a36Sopenharmony_cil0_%=: r0 = 1; \ 6862306a36Sopenharmony_ci r1 = 0; \ 6962306a36Sopenharmony_ci *(u32*)(r2 + 0) = r1; \ 7062306a36Sopenharmony_ci r1 = 0; \ 7162306a36Sopenharmony_ci *(u32*)(r2 + 3) = r1; \ 7262306a36Sopenharmony_ci lock *(u32 *)(r2 + 1) += w0; \ 7362306a36Sopenharmony_ci lock *(u32 *)(r2 + 2) += w0; \ 7462306a36Sopenharmony_ci r0 = *(u32*)(r2 + 1); \ 7562306a36Sopenharmony_cil1_%=: exit; \ 7662306a36Sopenharmony_ci" : 7762306a36Sopenharmony_ci : __imm_const(xdp_md_data, offsetof(struct xdp_md, data)), 7862306a36Sopenharmony_ci __imm_const(xdp_md_data_end, offsetof(struct xdp_md, data_end)) 7962306a36Sopenharmony_ci : __clobber_all); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ciSEC("tc") 8362306a36Sopenharmony_ci__description("xadd/w check whether src/dst got mangled, 1") 8462306a36Sopenharmony_ci__success __retval(3) 8562306a36Sopenharmony_ci__naked void src_dst_got_mangled_1(void) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci asm volatile (" \ 8862306a36Sopenharmony_ci r0 = 1; \ 8962306a36Sopenharmony_ci r6 = r0; \ 9062306a36Sopenharmony_ci r7 = r10; \ 9162306a36Sopenharmony_ci *(u64*)(r10 - 8) = r0; \ 9262306a36Sopenharmony_ci lock *(u64 *)(r10 - 8) += r0; \ 9362306a36Sopenharmony_ci lock *(u64 *)(r10 - 8) += r0; \ 9462306a36Sopenharmony_ci if r6 != r0 goto l0_%=; \ 9562306a36Sopenharmony_ci if r7 != r10 goto l0_%=; \ 9662306a36Sopenharmony_ci r0 = *(u64*)(r10 - 8); \ 9762306a36Sopenharmony_ci exit; \ 9862306a36Sopenharmony_cil0_%=: r0 = 42; \ 9962306a36Sopenharmony_ci exit; \ 10062306a36Sopenharmony_ci" ::: __clobber_all); 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ciSEC("tc") 10462306a36Sopenharmony_ci__description("xadd/w check whether src/dst got mangled, 2") 10562306a36Sopenharmony_ci__success __retval(3) 10662306a36Sopenharmony_ci__naked void src_dst_got_mangled_2(void) 10762306a36Sopenharmony_ci{ 10862306a36Sopenharmony_ci asm volatile (" \ 10962306a36Sopenharmony_ci r0 = 1; \ 11062306a36Sopenharmony_ci r6 = r0; \ 11162306a36Sopenharmony_ci r7 = r10; \ 11262306a36Sopenharmony_ci *(u32*)(r10 - 8) = r0; \ 11362306a36Sopenharmony_ci lock *(u32 *)(r10 - 8) += w0; \ 11462306a36Sopenharmony_ci lock *(u32 *)(r10 - 8) += w0; \ 11562306a36Sopenharmony_ci if r6 != r0 goto l0_%=; \ 11662306a36Sopenharmony_ci if r7 != r10 goto l0_%=; \ 11762306a36Sopenharmony_ci r0 = *(u32*)(r10 - 8); \ 11862306a36Sopenharmony_ci exit; \ 11962306a36Sopenharmony_cil0_%=: r0 = 42; \ 12062306a36Sopenharmony_ci exit; \ 12162306a36Sopenharmony_ci" ::: __clobber_all); 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 125