Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #include <asm/ptrace.h>
0003 
0004 #include "bpf_jit_32.h"
0005 
0006 #define SAVE_SZ     96
0007 #define SCRATCH_OFF 72
0008 #define BE_PTR(label)   be label
0009 #define SIGN_EXTEND(reg)
0010 
0011 #define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */
0012 
0013     .text
0014     .globl  bpf_jit_load_word
0015 bpf_jit_load_word:
0016     cmp r_OFF, 0
0017     bl  bpf_slow_path_word_neg
0018      nop
0019     .globl  bpf_jit_load_word_positive_offset
0020 bpf_jit_load_word_positive_offset:
0021     sub r_HEADLEN, r_OFF, r_TMP
0022     cmp r_TMP, 3
0023     ble bpf_slow_path_word
0024      add    r_SKB_DATA, r_OFF, r_TMP
0025     andcc   r_TMP, 3, %g0
0026     bne load_word_unaligned
0027      nop
0028     retl
0029      ld [r_TMP], r_A
0030 load_word_unaligned:
0031     ldub    [r_TMP + 0x0], r_OFF
0032     ldub    [r_TMP + 0x1], r_TMP2
0033     sll r_OFF, 8, r_OFF
0034     or  r_OFF, r_TMP2, r_OFF
0035     ldub    [r_TMP + 0x2], r_TMP2
0036     sll r_OFF, 8, r_OFF
0037     or  r_OFF, r_TMP2, r_OFF
0038     ldub    [r_TMP + 0x3], r_TMP2
0039     sll r_OFF, 8, r_OFF
0040     retl
0041      or r_OFF, r_TMP2, r_A
0042 
0043     .globl  bpf_jit_load_half
0044 bpf_jit_load_half:
0045     cmp r_OFF, 0
0046     bl  bpf_slow_path_half_neg
0047      nop
0048     .globl  bpf_jit_load_half_positive_offset
0049 bpf_jit_load_half_positive_offset:
0050     sub r_HEADLEN, r_OFF, r_TMP
0051     cmp r_TMP, 1
0052     ble bpf_slow_path_half
0053      add    r_SKB_DATA, r_OFF, r_TMP
0054     andcc   r_TMP, 1, %g0
0055     bne load_half_unaligned
0056      nop
0057     retl
0058      lduh   [r_TMP], r_A
0059 load_half_unaligned:
0060     ldub    [r_TMP + 0x0], r_OFF
0061     ldub    [r_TMP + 0x1], r_TMP2
0062     sll r_OFF, 8, r_OFF
0063     retl
0064      or r_OFF, r_TMP2, r_A
0065 
0066     .globl  bpf_jit_load_byte
0067 bpf_jit_load_byte:
0068     cmp r_OFF, 0
0069     bl  bpf_slow_path_byte_neg
0070      nop
0071     .globl  bpf_jit_load_byte_positive_offset
0072 bpf_jit_load_byte_positive_offset:
0073     cmp r_OFF, r_HEADLEN
0074     bge bpf_slow_path_byte
0075      nop
0076     retl
0077      ldub   [r_SKB_DATA + r_OFF], r_A
0078 
0079     .globl  bpf_jit_load_byte_msh
0080 bpf_jit_load_byte_msh:
0081     cmp r_OFF, 0
0082     bl  bpf_slow_path_byte_msh_neg
0083      nop
0084     .globl  bpf_jit_load_byte_msh_positive_offset
0085 bpf_jit_load_byte_msh_positive_offset:
0086     cmp r_OFF, r_HEADLEN
0087     bge bpf_slow_path_byte_msh
0088      nop
0089     ldub    [r_SKB_DATA + r_OFF], r_OFF
0090     and r_OFF, 0xf, r_OFF
0091     retl
0092      sll    r_OFF, 2, r_X
0093 
0094 #define bpf_slow_path_common(LEN)   \
0095     save    %sp, -SAVE_SZ, %sp; \
0096     mov %i0, %o0;       \
0097     mov r_OFF, %o1;     \
0098     add %fp, SCRATCH_OFF, %o2;  \
0099     call    skb_copy_bits;      \
0100      mov    (LEN), %o3;     \
0101     cmp %o0, 0;         \
0102     restore;
0103 
0104 bpf_slow_path_word:
0105     bpf_slow_path_common(4)
0106     bl  bpf_error
0107      ld [%sp + SCRATCH_OFF], r_A
0108     retl
0109      nop
0110 bpf_slow_path_half:
0111     bpf_slow_path_common(2)
0112     bl  bpf_error
0113      lduh   [%sp + SCRATCH_OFF], r_A
0114     retl
0115      nop
0116 bpf_slow_path_byte:
0117     bpf_slow_path_common(1)
0118     bl  bpf_error
0119      ldub   [%sp + SCRATCH_OFF], r_A
0120     retl
0121      nop
0122 bpf_slow_path_byte_msh:
0123     bpf_slow_path_common(1)
0124     bl  bpf_error
0125      ldub   [%sp + SCRATCH_OFF], r_A
0126     and r_OFF, 0xf, r_OFF
0127     retl
0128      sll    r_OFF, 2, r_X
0129 
0130 #define bpf_negative_common(LEN)            \
0131     save    %sp, -SAVE_SZ, %sp;         \
0132     mov %i0, %o0;               \
0133     mov r_OFF, %o1;             \
0134     SIGN_EXTEND(%o1);               \
0135     call    bpf_internal_load_pointer_neg_helper;   \
0136      mov    (LEN), %o2;             \
0137     mov %o0, r_TMP;             \
0138     cmp %o0, 0;                 \
0139     BE_PTR(bpf_error);              \
0140      restore;
0141 
0142 bpf_slow_path_word_neg:
0143     sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
0144     cmp r_OFF, r_TMP
0145     bl  bpf_error
0146      nop
0147     .globl  bpf_jit_load_word_negative_offset
0148 bpf_jit_load_word_negative_offset:
0149     bpf_negative_common(4)
0150     andcc   r_TMP, 3, %g0
0151     bne load_word_unaligned
0152      nop
0153     retl
0154      ld [r_TMP], r_A
0155 
0156 bpf_slow_path_half_neg:
0157     sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
0158     cmp r_OFF, r_TMP
0159     bl  bpf_error
0160      nop
0161     .globl  bpf_jit_load_half_negative_offset
0162 bpf_jit_load_half_negative_offset:
0163     bpf_negative_common(2)
0164     andcc   r_TMP, 1, %g0
0165     bne load_half_unaligned
0166      nop
0167     retl
0168      lduh   [r_TMP], r_A
0169 
0170 bpf_slow_path_byte_neg:
0171     sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
0172     cmp r_OFF, r_TMP
0173     bl  bpf_error
0174      nop
0175     .globl  bpf_jit_load_byte_negative_offset
0176 bpf_jit_load_byte_negative_offset:
0177     bpf_negative_common(1)
0178     retl
0179      ldub   [r_TMP], r_A
0180 
0181 bpf_slow_path_byte_msh_neg:
0182     sethi   %hi(SKF_MAX_NEG_OFF), r_TMP
0183     cmp r_OFF, r_TMP
0184     bl  bpf_error
0185      nop
0186     .globl  bpf_jit_load_byte_msh_negative_offset
0187 bpf_jit_load_byte_msh_negative_offset:
0188     bpf_negative_common(1)
0189     ldub    [r_TMP], r_OFF
0190     and r_OFF, 0xf, r_OFF
0191     retl
0192      sll    r_OFF, 2, r_X
0193 
0194 bpf_error:
0195     /* Make the JIT program return zero.  The JIT epilogue
0196      * stores away the original %o7 into r_saved_O7.  The
0197      * normal leaf function return is to use "retl" which
0198      * would evalute to "jmpl %o7 + 8, %g0" but we want to
0199      * use the saved value thus the sequence you see here.
0200      */
0201     jmpl    r_saved_O7 + 8, %g0
0202      clr    %o0