1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <asm/ptrace.h>
4 #include "bpf_jit_32.h"
8 #define BE_PTR(label) be label
9 #define SIGN_EXTEND(reg)
11 #define SKF_MAX_NEG_OFF (-0x200000) /* SKF_LL_OFF from filter.h */
14 .globl bpf_jit_load_word
17 bl bpf_slow_path_word_neg
19 .globl bpf_jit_load_word_positive_offset
20 bpf_jit_load_word_positive_offset:
21 sub r_HEADLEN, r_OFF, r_TMP
23 ble bpf_slow_path_word
24 add r_SKB_DATA, r_OFF, r_TMP
26 bne load_word_unaligned
31 ldub [r_TMP + 0x0], r_OFF
32 ldub [r_TMP + 0x1], r_TMP2
34 or r_OFF, r_TMP2, r_OFF
35 ldub [r_TMP + 0x2], r_TMP2
37 or r_OFF, r_TMP2, r_OFF
38 ldub [r_TMP + 0x3], r_TMP2
43 .globl bpf_jit_load_half
46 bl bpf_slow_path_half_neg
48 .globl bpf_jit_load_half_positive_offset
49 bpf_jit_load_half_positive_offset:
50 sub r_HEADLEN, r_OFF, r_TMP
52 ble bpf_slow_path_half
53 add r_SKB_DATA, r_OFF, r_TMP
55 bne load_half_unaligned
60 ldub [r_TMP + 0x0], r_OFF
61 ldub [r_TMP + 0x1], r_TMP2
66 .globl bpf_jit_load_byte
69 bl bpf_slow_path_byte_neg
71 .globl bpf_jit_load_byte_positive_offset
72 bpf_jit_load_byte_positive_offset:
74 bge bpf_slow_path_byte
77 ldub [r_SKB_DATA + r_OFF], r_A
79 .globl bpf_jit_load_byte_msh
80 bpf_jit_load_byte_msh:
82 bl bpf_slow_path_byte_msh_neg
84 .globl bpf_jit_load_byte_msh_positive_offset
85 bpf_jit_load_byte_msh_positive_offset:
87 bge bpf_slow_path_byte_msh
89 ldub [r_SKB_DATA + r_OFF], r_OFF
94 #define bpf_slow_path_common(LEN) \
95 save %sp, -SAVE_SZ, %sp; \
98 add %fp, SCRATCH_OFF, %o2; \
105 bpf_slow_path_common(4)
107 ld [%sp + SCRATCH_OFF], r_A
111 bpf_slow_path_common(2)
113 lduh [%sp + SCRATCH_OFF], r_A
117 bpf_slow_path_common(1)
119 ldub [%sp + SCRATCH_OFF], r_A
122 bpf_slow_path_byte_msh:
123 bpf_slow_path_common(1)
125 ldub [%sp + SCRATCH_OFF], r_A
126 and r_OFF, 0xf, r_OFF
130 #define bpf_negative_common(LEN) \
131 save %sp, -SAVE_SZ, %sp; \
135 call bpf_internal_load_pointer_neg_helper; \
142 bpf_slow_path_word_neg:
143 sethi %hi(SKF_MAX_NEG_OFF), r_TMP
147 .globl bpf_jit_load_word_negative_offset
148 bpf_jit_load_word_negative_offset:
149 bpf_negative_common(4)
151 bne load_word_unaligned
156 bpf_slow_path_half_neg:
157 sethi %hi(SKF_MAX_NEG_OFF), r_TMP
161 .globl bpf_jit_load_half_negative_offset
162 bpf_jit_load_half_negative_offset:
163 bpf_negative_common(2)
165 bne load_half_unaligned
170 bpf_slow_path_byte_neg:
171 sethi %hi(SKF_MAX_NEG_OFF), r_TMP
175 .globl bpf_jit_load_byte_negative_offset
176 bpf_jit_load_byte_negative_offset:
177 bpf_negative_common(1)
181 bpf_slow_path_byte_msh_neg:
182 sethi %hi(SKF_MAX_NEG_OFF), r_TMP
186 .globl bpf_jit_load_byte_msh_negative_offset
187 bpf_jit_load_byte_msh_negative_offset:
188 bpf_negative_common(1)
190 and r_OFF, 0xf, r_OFF
195 /* Make the JIT program return zero. The JIT epilogue
196 * stores away the original %o7 into r_saved_O7. The
197 * normal leaf function return is to use "retl" which
198 * would evalute to "jmpl %o7 + 8, %g0" but we want to
199 * use the saved value thus the sequence you see here.
201 jmpl r_saved_O7 + 8, %g0