18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#include <asm/ptrace.h> 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "bpf_jit_32.h" 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#define SAVE_SZ 96 78c2ecf20Sopenharmony_ci#define SCRATCH_OFF 72 88c2ecf20Sopenharmony_ci#define BE_PTR(label) be label 98c2ecf20Sopenharmony_ci#define SIGN_EXTEND(reg) 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci .text 148c2ecf20Sopenharmony_ci .globl bpf_jit_load_word 158c2ecf20Sopenharmony_cibpf_jit_load_word: 168c2ecf20Sopenharmony_ci cmp r_OFF, 0 178c2ecf20Sopenharmony_ci bl bpf_slow_path_word_neg 188c2ecf20Sopenharmony_ci nop 198c2ecf20Sopenharmony_ci .globl bpf_jit_load_word_positive_offset 208c2ecf20Sopenharmony_cibpf_jit_load_word_positive_offset: 218c2ecf20Sopenharmony_ci sub r_HEADLEN, r_OFF, r_TMP 228c2ecf20Sopenharmony_ci cmp r_TMP, 3 238c2ecf20Sopenharmony_ci ble bpf_slow_path_word 248c2ecf20Sopenharmony_ci add r_SKB_DATA, r_OFF, r_TMP 258c2ecf20Sopenharmony_ci andcc r_TMP, 3, %g0 268c2ecf20Sopenharmony_ci bne load_word_unaligned 278c2ecf20Sopenharmony_ci nop 288c2ecf20Sopenharmony_ci retl 298c2ecf20Sopenharmony_ci ld [r_TMP], r_A 308c2ecf20Sopenharmony_ciload_word_unaligned: 318c2ecf20Sopenharmony_ci ldub [r_TMP + 0x0], r_OFF 328c2ecf20Sopenharmony_ci ldub [r_TMP + 0x1], r_TMP2 338c2ecf20Sopenharmony_ci sll r_OFF, 8, r_OFF 348c2ecf20Sopenharmony_ci or r_OFF, r_TMP2, r_OFF 358c2ecf20Sopenharmony_ci ldub [r_TMP + 0x2], r_TMP2 368c2ecf20Sopenharmony_ci sll r_OFF, 8, r_OFF 378c2ecf20Sopenharmony_ci or r_OFF, r_TMP2, r_OFF 388c2ecf20Sopenharmony_ci ldub [r_TMP + 0x3], r_TMP2 398c2ecf20Sopenharmony_ci sll r_OFF, 8, r_OFF 408c2ecf20Sopenharmony_ci retl 418c2ecf20Sopenharmony_ci or r_OFF, r_TMP2, r_A 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci .globl bpf_jit_load_half 448c2ecf20Sopenharmony_cibpf_jit_load_half: 458c2ecf20Sopenharmony_ci cmp r_OFF, 0 468c2ecf20Sopenharmony_ci bl bpf_slow_path_half_neg 478c2ecf20Sopenharmony_ci nop 488c2ecf20Sopenharmony_ci .globl bpf_jit_load_half_positive_offset 498c2ecf20Sopenharmony_cibpf_jit_load_half_positive_offset: 508c2ecf20Sopenharmony_ci sub r_HEADLEN, r_OFF, r_TMP 518c2ecf20Sopenharmony_ci cmp r_TMP, 1 528c2ecf20Sopenharmony_ci ble bpf_slow_path_half 538c2ecf20Sopenharmony_ci add r_SKB_DATA, r_OFF, r_TMP 548c2ecf20Sopenharmony_ci andcc r_TMP, 1, %g0 558c2ecf20Sopenharmony_ci bne load_half_unaligned 568c2ecf20Sopenharmony_ci nop 578c2ecf20Sopenharmony_ci retl 588c2ecf20Sopenharmony_ci lduh [r_TMP], r_A 598c2ecf20Sopenharmony_ciload_half_unaligned: 608c2ecf20Sopenharmony_ci ldub [r_TMP + 0x0], r_OFF 618c2ecf20Sopenharmony_ci ldub [r_TMP + 0x1], r_TMP2 628c2ecf20Sopenharmony_ci sll r_OFF, 8, r_OFF 638c2ecf20Sopenharmony_ci retl 648c2ecf20Sopenharmony_ci or r_OFF, r_TMP2, r_A 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci .globl bpf_jit_load_byte 678c2ecf20Sopenharmony_cibpf_jit_load_byte: 688c2ecf20Sopenharmony_ci cmp r_OFF, 0 698c2ecf20Sopenharmony_ci bl bpf_slow_path_byte_neg 708c2ecf20Sopenharmony_ci nop 718c2ecf20Sopenharmony_ci .globl bpf_jit_load_byte_positive_offset 728c2ecf20Sopenharmony_cibpf_jit_load_byte_positive_offset: 738c2ecf20Sopenharmony_ci cmp r_OFF, r_HEADLEN 748c2ecf20Sopenharmony_ci bge bpf_slow_path_byte 758c2ecf20Sopenharmony_ci nop 768c2ecf20Sopenharmony_ci retl 778c2ecf20Sopenharmony_ci ldub [r_SKB_DATA + r_OFF], r_A 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci .globl bpf_jit_load_byte_msh 808c2ecf20Sopenharmony_cibpf_jit_load_byte_msh: 818c2ecf20Sopenharmony_ci cmp r_OFF, 0 828c2ecf20Sopenharmony_ci bl bpf_slow_path_byte_msh_neg 838c2ecf20Sopenharmony_ci nop 848c2ecf20Sopenharmony_ci .globl bpf_jit_load_byte_msh_positive_offset 858c2ecf20Sopenharmony_cibpf_jit_load_byte_msh_positive_offset: 868c2ecf20Sopenharmony_ci cmp r_OFF, r_HEADLEN 878c2ecf20Sopenharmony_ci bge bpf_slow_path_byte_msh 888c2ecf20Sopenharmony_ci nop 898c2ecf20Sopenharmony_ci ldub [r_SKB_DATA + r_OFF], r_OFF 908c2ecf20Sopenharmony_ci and r_OFF, 0xf, r_OFF 918c2ecf20Sopenharmony_ci retl 928c2ecf20Sopenharmony_ci sll r_OFF, 2, r_X 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci#define bpf_slow_path_common(LEN) \ 958c2ecf20Sopenharmony_ci save %sp, -SAVE_SZ, %sp; \ 968c2ecf20Sopenharmony_ci mov %i0, %o0; \ 978c2ecf20Sopenharmony_ci mov r_OFF, %o1; \ 988c2ecf20Sopenharmony_ci add %fp, SCRATCH_OFF, %o2; \ 998c2ecf20Sopenharmony_ci call skb_copy_bits; \ 1008c2ecf20Sopenharmony_ci mov (LEN), %o3; \ 1018c2ecf20Sopenharmony_ci cmp %o0, 0; \ 1028c2ecf20Sopenharmony_ci restore; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cibpf_slow_path_word: 1058c2ecf20Sopenharmony_ci bpf_slow_path_common(4) 1068c2ecf20Sopenharmony_ci bl bpf_error 1078c2ecf20Sopenharmony_ci ld [%sp + SCRATCH_OFF], r_A 1088c2ecf20Sopenharmony_ci retl 1098c2ecf20Sopenharmony_ci nop 1108c2ecf20Sopenharmony_cibpf_slow_path_half: 1118c2ecf20Sopenharmony_ci bpf_slow_path_common(2) 1128c2ecf20Sopenharmony_ci bl bpf_error 1138c2ecf20Sopenharmony_ci lduh [%sp + SCRATCH_OFF], r_A 1148c2ecf20Sopenharmony_ci retl 1158c2ecf20Sopenharmony_ci nop 1168c2ecf20Sopenharmony_cibpf_slow_path_byte: 1178c2ecf20Sopenharmony_ci bpf_slow_path_common(1) 1188c2ecf20Sopenharmony_ci bl bpf_error 1198c2ecf20Sopenharmony_ci ldub [%sp + SCRATCH_OFF], r_A 1208c2ecf20Sopenharmony_ci retl 1218c2ecf20Sopenharmony_ci nop 1228c2ecf20Sopenharmony_cibpf_slow_path_byte_msh: 1238c2ecf20Sopenharmony_ci bpf_slow_path_common(1) 1248c2ecf20Sopenharmony_ci bl bpf_error 1258c2ecf20Sopenharmony_ci ldub [%sp + SCRATCH_OFF], r_A 1268c2ecf20Sopenharmony_ci and r_OFF, 0xf, r_OFF 1278c2ecf20Sopenharmony_ci retl 1288c2ecf20Sopenharmony_ci sll r_OFF, 2, r_X 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#define bpf_negative_common(LEN) \ 1318c2ecf20Sopenharmony_ci save %sp, -SAVE_SZ, %sp; \ 1328c2ecf20Sopenharmony_ci mov %i0, %o0; \ 1338c2ecf20Sopenharmony_ci mov r_OFF, %o1; \ 1348c2ecf20Sopenharmony_ci SIGN_EXTEND(%o1); \ 1358c2ecf20Sopenharmony_ci call bpf_internal_load_pointer_neg_helper; \ 1368c2ecf20Sopenharmony_ci mov (LEN), %o2; \ 1378c2ecf20Sopenharmony_ci mov %o0, r_TMP; \ 1388c2ecf20Sopenharmony_ci cmp %o0, 0; \ 1398c2ecf20Sopenharmony_ci BE_PTR(bpf_error); \ 1408c2ecf20Sopenharmony_ci restore; 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cibpf_slow_path_word_neg: 1438c2ecf20Sopenharmony_ci sethi %hi(SKF_MAX_NEG_OFF), r_TMP 1448c2ecf20Sopenharmony_ci cmp r_OFF, r_TMP 1458c2ecf20Sopenharmony_ci bl bpf_error 1468c2ecf20Sopenharmony_ci nop 1478c2ecf20Sopenharmony_ci .globl bpf_jit_load_word_negative_offset 1488c2ecf20Sopenharmony_cibpf_jit_load_word_negative_offset: 1498c2ecf20Sopenharmony_ci bpf_negative_common(4) 1508c2ecf20Sopenharmony_ci andcc r_TMP, 3, %g0 1518c2ecf20Sopenharmony_ci bne load_word_unaligned 1528c2ecf20Sopenharmony_ci nop 1538c2ecf20Sopenharmony_ci retl 1548c2ecf20Sopenharmony_ci ld [r_TMP], r_A 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cibpf_slow_path_half_neg: 1578c2ecf20Sopenharmony_ci sethi %hi(SKF_MAX_NEG_OFF), r_TMP 1588c2ecf20Sopenharmony_ci cmp r_OFF, r_TMP 1598c2ecf20Sopenharmony_ci bl bpf_error 1608c2ecf20Sopenharmony_ci nop 1618c2ecf20Sopenharmony_ci .globl bpf_jit_load_half_negative_offset 1628c2ecf20Sopenharmony_cibpf_jit_load_half_negative_offset: 1638c2ecf20Sopenharmony_ci bpf_negative_common(2) 1648c2ecf20Sopenharmony_ci andcc r_TMP, 1, %g0 1658c2ecf20Sopenharmony_ci bne load_half_unaligned 1668c2ecf20Sopenharmony_ci nop 1678c2ecf20Sopenharmony_ci retl 1688c2ecf20Sopenharmony_ci lduh [r_TMP], r_A 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cibpf_slow_path_byte_neg: 1718c2ecf20Sopenharmony_ci sethi %hi(SKF_MAX_NEG_OFF), r_TMP 1728c2ecf20Sopenharmony_ci cmp r_OFF, r_TMP 1738c2ecf20Sopenharmony_ci bl bpf_error 1748c2ecf20Sopenharmony_ci nop 1758c2ecf20Sopenharmony_ci .globl bpf_jit_load_byte_negative_offset 1768c2ecf20Sopenharmony_cibpf_jit_load_byte_negative_offset: 1778c2ecf20Sopenharmony_ci bpf_negative_common(1) 1788c2ecf20Sopenharmony_ci retl 1798c2ecf20Sopenharmony_ci ldub [r_TMP], r_A 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cibpf_slow_path_byte_msh_neg: 1828c2ecf20Sopenharmony_ci sethi %hi(SKF_MAX_NEG_OFF), r_TMP 1838c2ecf20Sopenharmony_ci cmp r_OFF, r_TMP 1848c2ecf20Sopenharmony_ci bl bpf_error 1858c2ecf20Sopenharmony_ci nop 1868c2ecf20Sopenharmony_ci .globl bpf_jit_load_byte_msh_negative_offset 1878c2ecf20Sopenharmony_cibpf_jit_load_byte_msh_negative_offset: 1888c2ecf20Sopenharmony_ci bpf_negative_common(1) 1898c2ecf20Sopenharmony_ci ldub [r_TMP], r_OFF 1908c2ecf20Sopenharmony_ci and r_OFF, 0xf, r_OFF 1918c2ecf20Sopenharmony_ci retl 1928c2ecf20Sopenharmony_ci sll r_OFF, 2, r_X 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_cibpf_error: 1958c2ecf20Sopenharmony_ci /* Make the JIT program return zero. The JIT epilogue 1968c2ecf20Sopenharmony_ci * stores away the original %o7 into r_saved_O7. The 1978c2ecf20Sopenharmony_ci * normal leaf function return is to use "retl" which 1988c2ecf20Sopenharmony_ci * would evalute to "jmpl %o7 + 8, %g0" but we want to 1998c2ecf20Sopenharmony_ci * use the saved value thus the sequence you see here. 2008c2ecf20Sopenharmony_ci */ 2018c2ecf20Sopenharmony_ci jmpl r_saved_O7 + 8, %g0 2028c2ecf20Sopenharmony_ci clr %o0 203