1
2
3
4
5
6
7
8
9
10
11
12
13#include <asm/asm.h>
14#include <asm/regdef.h>
15#include "bpf_jit.h"
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#define skb a0
40#define offset a1
41#define SKF_LL_OFF (-0x200000)
42
43
44 .set noreorder
45
46#define is_offset_negative(TYPE) \
47 \
48 slti t0, offset, 0; \
49 bgtz t0, bpf_slow_path_
50
51
52#define is_offset_in_header(SIZE, TYPE) \
53 \
54 addiu $r_s0, $r_skb_hl, -SIZE; \
55 slt t0, $r_s0, offset; \
56 bgtz t0, bpf_slow_path_
57
58LEAF(sk_load_word)
59 is_offset_negative(word)
60FEXPORT(sk_load_word_positive)
61 is_offset_in_header(4, word)
62
63 PTR_ADDU t1, $r_skb_data, offset
64 .set reorder
65 lw $r_A, 0(t1)
66 .set noreorder
67#ifdef CONFIG_CPU_LITTLE_ENDIAN
68
69 wsbh t0, $r_A
70 rotr $r_A, t0, 16
71# else
72 sll t0, $r_A, 24
73 srl t1, $r_A, 24
74 srl t2, $r_A, 8
75 or t0, t0, t1
76 andi t2, t2, 0xff00
77 andi t1, $r_A, 0xff00
78 or t0, t0, t2
79 sll t1, t1, 8
80 or $r_A, t0, t1
81# endif
82#endif
83 jr $r_ra
84 move $r_ret, zero
85 END(sk_load_word)
86
87LEAF(sk_load_half)
88 is_offset_negative(half)
89FEXPORT(sk_load_half_positive)
90 is_offset_in_header(2, half)
91
92 PTR_ADDU t1, $r_skb_data, offset
93 .set reorder
94 lh $r_A, 0(t1)
95 .set noreorder
96#ifdef CONFIG_CPU_LITTLE_ENDIAN
97
98 wsbh t0, $r_A
99 seh $r_A, t0
100# else
101 sll t0, $r_A, 24
102 andi t1, $r_A, 0xff00
103 sra t0, t0, 16
104 srl t1, t1, 8
105 or $r_A, t0, t1
106# endif
107#endif
108 jr $r_ra
109 move $r_ret, zero
110 END(sk_load_half)
111
112LEAF(sk_load_byte)
113 is_offset_negative(byte)
114FEXPORT(sk_load_byte_positive)
115 is_offset_in_header(1, byte)
116
117 PTR_ADDU t1, $r_skb_data, offset
118 lb $r_A, 0(t1)
119 jr $r_ra
120 move $r_ret, zero
121 END(sk_load_byte)
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142#define bpf_slow_path_common(SIZE) \
143 \
144 LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \
145 sltu $r_s0, offset, $r_s1; \
146 beqz $r_s0, fault; \
147 \
148 LONG_ADDIU a3, zero, SIZE; \
149 PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
150 PTR_LA t0, skb_copy_bits; \
151 PTR_S $r_ra, (5 * SZREG)($r_sp); \
152 \
153 move a2, $r_sp; \
154 jalr t0; \
155 \
156 INT_S zero, (4 * SZREG)($r_sp); \
157
158
159
160
161 \
162 \
163 PTR_L $r_ra, (5 * SZREG)($r_sp); \
164 INT_L $r_s0, (4 * SZREG)($r_sp); \
165 bltz v0, fault; \
166 PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
167 move $r_ret, zero; \
168
169NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp)
170 bpf_slow_path_common(4)
171#ifdef CONFIG_CPU_LITTLE_ENDIAN
172
173 wsbh t0, $r_s0
174 jr $r_ra
175 rotr $r_A, t0, 16
176# else
177 sll t0, $r_s0, 24
178 srl t1, $r_s0, 24
179 srl t2, $r_s0, 8
180 or t0, t0, t1
181 andi t2, t2, 0xff00
182 andi t1, $r_s0, 0xff00
183 or t0, t0, t2
184 sll t1, t1, 8
185 jr $r_ra
186 or $r_A, t0, t1
187# endif
188#else
189 jr $r_ra
190 move $r_A, $r_s0
191#endif
192
193 END(bpf_slow_path_word)
194
195NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp)
196 bpf_slow_path_common(2)
197#ifdef CONFIG_CPU_LITTLE_ENDIAN
198
199 jr $r_ra
200 wsbh $r_A, $r_s0
201# else
202 sll t0, $r_s0, 8
203 andi t1, $r_s0, 0xff00
204 andi t0, t0, 0xff00
205 srl t1, t1, 8
206 jr $r_ra
207 or $r_A, t0, t1
208# endif
209#else
210 jr $r_ra
211 move $r_A, $r_s0
212#endif
213
214 END(bpf_slow_path_half)
215
216NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp)
217 bpf_slow_path_common(1)
218 jr $r_ra
219 move $r_A, $r_s0
220
221 END(bpf_slow_path_byte)
222
223
224
225
226 .macro bpf_is_end_of_data
227 li t0, SKF_LL_OFF
228
229 slt t1, offset, t0
230 bgtz t1, fault
231
232 .endm
233
234
235
236
237
238
239
240
241
242#define bpf_negative_common(SIZE) \
243 PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \
244 PTR_LA t0, bpf_internal_load_pointer_neg_helper; \
245 PTR_S $r_ra, (5 * SZREG)($r_sp); \
246 jalr t0; \
247 li a2, SIZE; \
248 PTR_L $r_ra, (5 * SZREG)($r_sp); \
249 \
250 beqz v0, fault; \
251 PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \
252 \
253 move $r_s0, v0; \
254 \
255 move $r_ret, zero; \
256
257bpf_slow_path_word_neg:
258 bpf_is_end_of_data
259NESTED(sk_load_word_negative, (6 * SZREG), $r_sp)
260 bpf_negative_common(4)
261 jr $r_ra
262 lw $r_A, 0($r_s0)
263 END(sk_load_word_negative)
264
265bpf_slow_path_half_neg:
266 bpf_is_end_of_data
267NESTED(sk_load_half_negative, (6 * SZREG), $r_sp)
268 bpf_negative_common(2)
269 jr $r_ra
270 lhu $r_A, 0($r_s0)
271 END(sk_load_half_negative)
272
273bpf_slow_path_byte_neg:
274 bpf_is_end_of_data
275NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp)
276 bpf_negative_common(1)
277 jr $r_ra
278 lbu $r_A, 0($r_s0)
279 END(sk_load_byte_negative)
280
281fault:
282 jr $r_ra
283 addiu $r_ret, zero, 1
284