.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * bpf_jit_comp64.c: eBPF JIT compiler |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * IBM Corporation |
---|
6 | 7 | * |
---|
7 | 8 | * Based on the powerpc classic BPF JIT compiler by Matt Evans |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or |
---|
10 | | - * modify it under the terms of the GNU General Public License |
---|
11 | | - * as published by the Free Software Foundation; version 2 |
---|
12 | | - * of the License. |
---|
13 | 9 | */ |
---|
14 | 10 | #include <linux/moduleloader.h> |
---|
15 | 11 | #include <asm/cacheflush.h> |
---|
.. | .. |
---|
100 | 96 | * invoked through a tail call. |
---|
101 | 97 | */ |
---|
102 | 98 | if (ctx->seen & SEEN_TAILCALL) { |
---|
103 | | - PPC_LI(b2p[TMP_REG_1], 0); |
---|
| 99 | + EMIT(PPC_RAW_LI(b2p[TMP_REG_1], 0)); |
---|
104 | 100 | /* this goes in the redzone */ |
---|
105 | 101 | PPC_BPF_STL(b2p[TMP_REG_1], 1, -(BPF_PPC_STACK_SAVE + 8)); |
---|
106 | 102 | } else { |
---|
107 | | - PPC_NOP(); |
---|
108 | | - PPC_NOP(); |
---|
| 103 | + EMIT(PPC_RAW_NOP()); |
---|
| 104 | + EMIT(PPC_RAW_NOP()); |
---|
109 | 105 | } |
---|
110 | 106 | |
---|
111 | 107 | #define BPF_TAILCALL_PROLOGUE_SIZE 8 |
---|
.. | .. |
---|
134 | 130 | |
---|
135 | 131 | /* Setup frame pointer to point to the bpf stack area */ |
---|
136 | 132 | if (bpf_is_seen_register(ctx, BPF_REG_FP)) |
---|
137 | | - PPC_ADDI(b2p[BPF_REG_FP], 1, |
---|
138 | | - STACK_FRAME_MIN_SIZE + ctx->stack_size); |
---|
| 133 | + EMIT(PPC_RAW_ADDI(b2p[BPF_REG_FP], 1, |
---|
| 134 | + STACK_FRAME_MIN_SIZE + ctx->stack_size)); |
---|
139 | 135 | } |
---|
140 | 136 | |
---|
141 | 137 | static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx) |
---|
.. | .. |
---|
149 | 145 | |
---|
150 | 146 | /* Tear down our stack frame */ |
---|
151 | 147 | if (bpf_has_stack_frame(ctx)) { |
---|
152 | | - PPC_ADDI(1, 1, BPF_PPC_STACKFRAME + ctx->stack_size); |
---|
| 148 | + EMIT(PPC_RAW_ADDI(1, 1, BPF_PPC_STACKFRAME + ctx->stack_size)); |
---|
153 | 149 | if (ctx->seen & SEEN_FUNC) { |
---|
154 | 150 | PPC_BPF_LL(0, 1, PPC_LR_STKOFF); |
---|
155 | | - PPC_MTLR(0); |
---|
| 151 | + EMIT(PPC_RAW_MTLR(0)); |
---|
156 | 152 | } |
---|
157 | 153 | } |
---|
158 | 154 | } |
---|
.. | .. |
---|
162 | 158 | bpf_jit_emit_common_epilogue(image, ctx); |
---|
163 | 159 | |
---|
164 | 160 | /* Move result to r3 */ |
---|
165 | | - PPC_MR(3, b2p[BPF_REG_0]); |
---|
| 161 | + EMIT(PPC_RAW_MR(3, b2p[BPF_REG_0])); |
---|
166 | 162 | |
---|
167 | | - PPC_BLR(); |
---|
| 163 | + EMIT(PPC_RAW_BLR()); |
---|
168 | 164 | } |
---|
169 | 165 | |
---|
170 | | -static void bpf_jit_emit_func_call(u32 *image, struct codegen_context *ctx, u64 func) |
---|
| 166 | +static void bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx, |
---|
| 167 | + u64 func) |
---|
| 168 | +{ |
---|
| 169 | +#ifdef PPC64_ELF_ABI_v1 |
---|
| 170 | + /* func points to the function descriptor */ |
---|
| 171 | + PPC_LI64(b2p[TMP_REG_2], func); |
---|
| 172 | + /* Load actual entry point from function descriptor */ |
---|
| 173 | + PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_2], 0); |
---|
| 174 | + /* ... and move it to LR */ |
---|
| 175 | + EMIT(PPC_RAW_MTLR(b2p[TMP_REG_1])); |
---|
| 176 | + /* |
---|
| 177 | + * Load TOC from function descriptor at offset 8. |
---|
| 178 | + * We can clobber r2 since we get called through a |
---|
| 179 | + * function pointer (so caller will save/restore r2) |
---|
| 180 | + * and since we don't use a TOC ourself. |
---|
| 181 | + */ |
---|
| 182 | + PPC_BPF_LL(2, b2p[TMP_REG_2], 8); |
---|
| 183 | +#else |
---|
| 184 | + /* We can clobber r12 */ |
---|
| 185 | + PPC_FUNC_ADDR(12, func); |
---|
| 186 | + EMIT(PPC_RAW_MTLR(12)); |
---|
| 187 | +#endif |
---|
| 188 | + EMIT(PPC_RAW_BLRL()); |
---|
| 189 | +} |
---|
| 190 | + |
---|
| 191 | +static void bpf_jit_emit_func_call_rel(u32 *image, struct codegen_context *ctx, |
---|
| 192 | + u64 func) |
---|
171 | 193 | { |
---|
172 | 194 | unsigned int i, ctx_idx = ctx->idx; |
---|
173 | 195 | |
---|
.. | .. |
---|
185 | 207 | * that PPC_LI64() can emit. |
---|
186 | 208 | */ |
---|
187 | 209 | for (i = ctx->idx - ctx_idx; i < 5; i++) |
---|
188 | | - PPC_NOP(); |
---|
| 210 | + EMIT(PPC_RAW_NOP()); |
---|
189 | 211 | |
---|
190 | 212 | #ifdef PPC64_ELF_ABI_v1 |
---|
191 | 213 | /* |
---|
.. | .. |
---|
199 | 221 | PPC_BPF_LL(12, 12, 0); |
---|
200 | 222 | #endif |
---|
201 | 223 | |
---|
202 | | - PPC_MTLR(12); |
---|
203 | | - PPC_BLRL(); |
---|
| 224 | + EMIT(PPC_RAW_MTLR(12)); |
---|
| 225 | + EMIT(PPC_RAW_BLRL()); |
---|
204 | 226 | } |
---|
205 | 227 | |
---|
206 | 228 | static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out) |
---|
.. | .. |
---|
218 | 240 | * if (index >= array->map.max_entries) |
---|
219 | 241 | * goto out; |
---|
220 | 242 | */ |
---|
221 | | - PPC_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries)); |
---|
222 | | - PPC_RLWINM(b2p_index, b2p_index, 0, 0, 31); |
---|
223 | | - PPC_CMPLW(b2p_index, b2p[TMP_REG_1]); |
---|
| 243 | + EMIT(PPC_RAW_LWZ(b2p[TMP_REG_1], b2p_bpf_array, offsetof(struct bpf_array, map.max_entries))); |
---|
| 244 | + EMIT(PPC_RAW_RLWINM(b2p_index, b2p_index, 0, 0, 31)); |
---|
| 245 | + EMIT(PPC_RAW_CMPLW(b2p_index, b2p[TMP_REG_1])); |
---|
224 | 246 | PPC_BCC(COND_GE, out); |
---|
225 | 247 | |
---|
226 | 248 | /* |
---|
.. | .. |
---|
228 | 250 | * goto out; |
---|
229 | 251 | */ |
---|
230 | 252 | PPC_BPF_LL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx)); |
---|
231 | | - PPC_CMPLWI(b2p[TMP_REG_1], MAX_TAIL_CALL_CNT); |
---|
| 253 | + EMIT(PPC_RAW_CMPLWI(b2p[TMP_REG_1], MAX_TAIL_CALL_CNT)); |
---|
232 | 254 | PPC_BCC(COND_GT, out); |
---|
233 | 255 | |
---|
234 | 256 | /* |
---|
235 | 257 | * tail_call_cnt++; |
---|
236 | 258 | */ |
---|
237 | | - PPC_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], 1); |
---|
| 259 | + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], 1)); |
---|
238 | 260 | PPC_BPF_STL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx)); |
---|
239 | 261 | |
---|
240 | 262 | /* prog = array->ptrs[index]; */ |
---|
241 | | - PPC_MULI(b2p[TMP_REG_1], b2p_index, 8); |
---|
242 | | - PPC_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array); |
---|
| 263 | + EMIT(PPC_RAW_MULI(b2p[TMP_REG_1], b2p_index, 8)); |
---|
| 264 | + EMIT(PPC_RAW_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array)); |
---|
243 | 265 | PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_array, ptrs)); |
---|
244 | 266 | |
---|
245 | 267 | /* |
---|
246 | 268 | * if (prog == NULL) |
---|
247 | 269 | * goto out; |
---|
248 | 270 | */ |
---|
249 | | - PPC_CMPLDI(b2p[TMP_REG_1], 0); |
---|
| 271 | + EMIT(PPC_RAW_CMPLDI(b2p[TMP_REG_1], 0)); |
---|
250 | 272 | PPC_BCC(COND_EQ, out); |
---|
251 | 273 | |
---|
252 | 274 | /* goto *(prog->bpf_func + prologue_size); */ |
---|
253 | 275 | PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_prog, bpf_func)); |
---|
254 | 276 | #ifdef PPC64_ELF_ABI_v1 |
---|
255 | 277 | /* skip past the function descriptor */ |
---|
256 | | - PPC_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], |
---|
257 | | - FUNCTION_DESCR_SIZE + BPF_TAILCALL_PROLOGUE_SIZE); |
---|
| 278 | + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], |
---|
| 279 | + FUNCTION_DESCR_SIZE + BPF_TAILCALL_PROLOGUE_SIZE)); |
---|
258 | 280 | #else |
---|
259 | | - PPC_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], BPF_TAILCALL_PROLOGUE_SIZE); |
---|
| 281 | + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], BPF_TAILCALL_PROLOGUE_SIZE)); |
---|
260 | 282 | #endif |
---|
261 | | - PPC_MTCTR(b2p[TMP_REG_1]); |
---|
| 283 | + EMIT(PPC_RAW_MTCTR(b2p[TMP_REG_1])); |
---|
262 | 284 | |
---|
263 | 285 | /* tear down stack, restore NVRs, ... */ |
---|
264 | 286 | bpf_jit_emit_common_epilogue(image, ctx); |
---|
265 | 287 | |
---|
266 | | - PPC_BCTR(); |
---|
| 288 | + EMIT(PPC_RAW_BCTR()); |
---|
267 | 289 | |
---|
268 | 290 | /* out: */ |
---|
269 | 291 | return 0; |
---|
.. | .. |
---|
310 | 332 | u32 src_reg = b2p[insn[i].src_reg]; |
---|
311 | 333 | s16 off = insn[i].off; |
---|
312 | 334 | s32 imm = insn[i].imm; |
---|
| 335 | + bool func_addr_fixed; |
---|
| 336 | + u64 func_addr; |
---|
313 | 337 | u64 imm64; |
---|
314 | | - u8 *func; |
---|
315 | 338 | u32 true_cond; |
---|
316 | 339 | u32 tmp_idx; |
---|
317 | 340 | |
---|
.. | .. |
---|
343 | 366 | */ |
---|
344 | 367 | case BPF_ALU | BPF_ADD | BPF_X: /* (u32) dst += (u32) src */ |
---|
345 | 368 | case BPF_ALU64 | BPF_ADD | BPF_X: /* dst += src */ |
---|
346 | | - PPC_ADD(dst_reg, dst_reg, src_reg); |
---|
| 369 | + EMIT(PPC_RAW_ADD(dst_reg, dst_reg, src_reg)); |
---|
347 | 370 | goto bpf_alu32_trunc; |
---|
348 | 371 | case BPF_ALU | BPF_SUB | BPF_X: /* (u32) dst -= (u32) src */ |
---|
349 | 372 | case BPF_ALU64 | BPF_SUB | BPF_X: /* dst -= src */ |
---|
350 | | - PPC_SUB(dst_reg, dst_reg, src_reg); |
---|
| 373 | + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, src_reg)); |
---|
351 | 374 | goto bpf_alu32_trunc; |
---|
352 | 375 | case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */ |
---|
353 | 376 | case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */ |
---|
354 | 377 | if (!imm) { |
---|
355 | 378 | goto bpf_alu32_trunc; |
---|
356 | 379 | } else if (imm >= -32768 && imm < 32768) { |
---|
357 | | - PPC_ADDI(dst_reg, dst_reg, IMM_L(imm)); |
---|
| 380 | + EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(imm))); |
---|
358 | 381 | } else { |
---|
359 | 382 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
360 | | - PPC_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 383 | + EMIT(PPC_RAW_ADD(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
361 | 384 | } |
---|
362 | 385 | goto bpf_alu32_trunc; |
---|
363 | 386 | case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ |
---|
.. | .. |
---|
365 | 388 | if (!imm) { |
---|
366 | 389 | goto bpf_alu32_trunc; |
---|
367 | 390 | } else if (imm > -32768 && imm <= 32768) { |
---|
368 | | - PPC_ADDI(dst_reg, dst_reg, IMM_L(-imm)); |
---|
| 391 | + EMIT(PPC_RAW_ADDI(dst_reg, dst_reg, IMM_L(-imm))); |
---|
369 | 392 | } else { |
---|
370 | 393 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
371 | | - PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 394 | + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
372 | 395 | } |
---|
373 | 396 | goto bpf_alu32_trunc; |
---|
374 | 397 | case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */ |
---|
375 | 398 | case BPF_ALU64 | BPF_MUL | BPF_X: /* dst *= src */ |
---|
376 | 399 | if (BPF_CLASS(code) == BPF_ALU) |
---|
377 | | - PPC_MULW(dst_reg, dst_reg, src_reg); |
---|
| 400 | + EMIT(PPC_RAW_MULW(dst_reg, dst_reg, src_reg)); |
---|
378 | 401 | else |
---|
379 | | - PPC_MULD(dst_reg, dst_reg, src_reg); |
---|
| 402 | + EMIT(PPC_RAW_MULD(dst_reg, dst_reg, src_reg)); |
---|
380 | 403 | goto bpf_alu32_trunc; |
---|
381 | 404 | case BPF_ALU | BPF_MUL | BPF_K: /* (u32) dst *= (u32) imm */ |
---|
382 | 405 | case BPF_ALU64 | BPF_MUL | BPF_K: /* dst *= imm */ |
---|
383 | 406 | if (imm >= -32768 && imm < 32768) |
---|
384 | | - PPC_MULI(dst_reg, dst_reg, IMM_L(imm)); |
---|
| 407 | + EMIT(PPC_RAW_MULI(dst_reg, dst_reg, IMM_L(imm))); |
---|
385 | 408 | else { |
---|
386 | 409 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
387 | 410 | if (BPF_CLASS(code) == BPF_ALU) |
---|
388 | | - PPC_MULW(dst_reg, dst_reg, |
---|
389 | | - b2p[TMP_REG_1]); |
---|
| 411 | + EMIT(PPC_RAW_MULW(dst_reg, dst_reg, |
---|
| 412 | + b2p[TMP_REG_1])); |
---|
390 | 413 | else |
---|
391 | | - PPC_MULD(dst_reg, dst_reg, |
---|
392 | | - b2p[TMP_REG_1]); |
---|
| 414 | + EMIT(PPC_RAW_MULD(dst_reg, dst_reg, |
---|
| 415 | + b2p[TMP_REG_1])); |
---|
393 | 416 | } |
---|
394 | 417 | goto bpf_alu32_trunc; |
---|
395 | 418 | case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */ |
---|
396 | 419 | case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */ |
---|
397 | 420 | if (BPF_OP(code) == BPF_MOD) { |
---|
398 | | - PPC_DIVWU(b2p[TMP_REG_1], dst_reg, src_reg); |
---|
399 | | - PPC_MULW(b2p[TMP_REG_1], src_reg, |
---|
400 | | - b2p[TMP_REG_1]); |
---|
401 | | - PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 421 | + EMIT(PPC_RAW_DIVWU(b2p[TMP_REG_1], dst_reg, src_reg)); |
---|
| 422 | + EMIT(PPC_RAW_MULW(b2p[TMP_REG_1], src_reg, |
---|
| 423 | + b2p[TMP_REG_1])); |
---|
| 424 | + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
402 | 425 | } else |
---|
403 | | - PPC_DIVWU(dst_reg, dst_reg, src_reg); |
---|
| 426 | + EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, src_reg)); |
---|
404 | 427 | goto bpf_alu32_trunc; |
---|
405 | 428 | case BPF_ALU64 | BPF_DIV | BPF_X: /* dst /= src */ |
---|
406 | 429 | case BPF_ALU64 | BPF_MOD | BPF_X: /* dst %= src */ |
---|
407 | 430 | if (BPF_OP(code) == BPF_MOD) { |
---|
408 | | - PPC_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg); |
---|
409 | | - PPC_MULD(b2p[TMP_REG_1], src_reg, |
---|
410 | | - b2p[TMP_REG_1]); |
---|
411 | | - PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 431 | + EMIT(PPC_RAW_DIVDU(b2p[TMP_REG_1], dst_reg, src_reg)); |
---|
| 432 | + EMIT(PPC_RAW_MULD(b2p[TMP_REG_1], src_reg, |
---|
| 433 | + b2p[TMP_REG_1])); |
---|
| 434 | + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
412 | 435 | } else |
---|
413 | | - PPC_DIVDU(dst_reg, dst_reg, src_reg); |
---|
| 436 | + EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, src_reg)); |
---|
414 | 437 | break; |
---|
415 | 438 | case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */ |
---|
416 | 439 | case BPF_ALU | BPF_DIV | BPF_K: /* (u32) dst /= (u32) imm */ |
---|
.. | .. |
---|
422 | 445 | if (BPF_OP(code) == BPF_DIV) { |
---|
423 | 446 | goto bpf_alu32_trunc; |
---|
424 | 447 | } else { |
---|
425 | | - PPC_LI(dst_reg, 0); |
---|
| 448 | + EMIT(PPC_RAW_LI(dst_reg, 0)); |
---|
426 | 449 | break; |
---|
427 | 450 | } |
---|
428 | 451 | } |
---|
.. | .. |
---|
431 | 454 | switch (BPF_CLASS(code)) { |
---|
432 | 455 | case BPF_ALU: |
---|
433 | 456 | if (BPF_OP(code) == BPF_MOD) { |
---|
434 | | - PPC_DIVWU(b2p[TMP_REG_2], dst_reg, |
---|
435 | | - b2p[TMP_REG_1]); |
---|
436 | | - PPC_MULW(b2p[TMP_REG_1], |
---|
| 457 | + EMIT(PPC_RAW_DIVWU(b2p[TMP_REG_2], |
---|
| 458 | + dst_reg, |
---|
| 459 | + b2p[TMP_REG_1])); |
---|
| 460 | + EMIT(PPC_RAW_MULW(b2p[TMP_REG_1], |
---|
437 | 461 | b2p[TMP_REG_1], |
---|
438 | | - b2p[TMP_REG_2]); |
---|
439 | | - PPC_SUB(dst_reg, dst_reg, |
---|
440 | | - b2p[TMP_REG_1]); |
---|
| 462 | + b2p[TMP_REG_2])); |
---|
| 463 | + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, |
---|
| 464 | + b2p[TMP_REG_1])); |
---|
441 | 465 | } else |
---|
442 | | - PPC_DIVWU(dst_reg, dst_reg, |
---|
443 | | - b2p[TMP_REG_1]); |
---|
| 466 | + EMIT(PPC_RAW_DIVWU(dst_reg, dst_reg, |
---|
| 467 | + b2p[TMP_REG_1])); |
---|
444 | 468 | break; |
---|
445 | 469 | case BPF_ALU64: |
---|
446 | 470 | if (BPF_OP(code) == BPF_MOD) { |
---|
447 | | - PPC_DIVDU(b2p[TMP_REG_2], dst_reg, |
---|
448 | | - b2p[TMP_REG_1]); |
---|
449 | | - PPC_MULD(b2p[TMP_REG_1], |
---|
| 471 | + EMIT(PPC_RAW_DIVDU(b2p[TMP_REG_2], |
---|
| 472 | + dst_reg, |
---|
| 473 | + b2p[TMP_REG_1])); |
---|
| 474 | + EMIT(PPC_RAW_MULD(b2p[TMP_REG_1], |
---|
450 | 475 | b2p[TMP_REG_1], |
---|
451 | | - b2p[TMP_REG_2]); |
---|
452 | | - PPC_SUB(dst_reg, dst_reg, |
---|
453 | | - b2p[TMP_REG_1]); |
---|
| 476 | + b2p[TMP_REG_2])); |
---|
| 477 | + EMIT(PPC_RAW_SUB(dst_reg, dst_reg, |
---|
| 478 | + b2p[TMP_REG_1])); |
---|
454 | 479 | } else |
---|
455 | | - PPC_DIVDU(dst_reg, dst_reg, |
---|
456 | | - b2p[TMP_REG_1]); |
---|
| 480 | + EMIT(PPC_RAW_DIVDU(dst_reg, dst_reg, |
---|
| 481 | + b2p[TMP_REG_1])); |
---|
457 | 482 | break; |
---|
458 | 483 | } |
---|
459 | 484 | goto bpf_alu32_trunc; |
---|
460 | 485 | case BPF_ALU | BPF_NEG: /* (u32) dst = -dst */ |
---|
461 | 486 | case BPF_ALU64 | BPF_NEG: /* dst = -dst */ |
---|
462 | | - PPC_NEG(dst_reg, dst_reg); |
---|
| 487 | + EMIT(PPC_RAW_NEG(dst_reg, dst_reg)); |
---|
463 | 488 | goto bpf_alu32_trunc; |
---|
464 | 489 | |
---|
465 | 490 | /* |
---|
.. | .. |
---|
467 | 492 | */ |
---|
468 | 493 | case BPF_ALU | BPF_AND | BPF_X: /* (u32) dst = dst & src */ |
---|
469 | 494 | case BPF_ALU64 | BPF_AND | BPF_X: /* dst = dst & src */ |
---|
470 | | - PPC_AND(dst_reg, dst_reg, src_reg); |
---|
| 495 | + EMIT(PPC_RAW_AND(dst_reg, dst_reg, src_reg)); |
---|
471 | 496 | goto bpf_alu32_trunc; |
---|
472 | 497 | case BPF_ALU | BPF_AND | BPF_K: /* (u32) dst = dst & imm */ |
---|
473 | 498 | case BPF_ALU64 | BPF_AND | BPF_K: /* dst = dst & imm */ |
---|
474 | 499 | if (!IMM_H(imm)) |
---|
475 | | - PPC_ANDI(dst_reg, dst_reg, IMM_L(imm)); |
---|
| 500 | + EMIT(PPC_RAW_ANDI(dst_reg, dst_reg, IMM_L(imm))); |
---|
476 | 501 | else { |
---|
477 | 502 | /* Sign-extended */ |
---|
478 | 503 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
479 | | - PPC_AND(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 504 | + EMIT(PPC_RAW_AND(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
480 | 505 | } |
---|
481 | 506 | goto bpf_alu32_trunc; |
---|
482 | 507 | case BPF_ALU | BPF_OR | BPF_X: /* dst = (u32) dst | (u32) src */ |
---|
483 | 508 | case BPF_ALU64 | BPF_OR | BPF_X: /* dst = dst | src */ |
---|
484 | | - PPC_OR(dst_reg, dst_reg, src_reg); |
---|
| 509 | + EMIT(PPC_RAW_OR(dst_reg, dst_reg, src_reg)); |
---|
485 | 510 | goto bpf_alu32_trunc; |
---|
486 | 511 | case BPF_ALU | BPF_OR | BPF_K:/* dst = (u32) dst | (u32) imm */ |
---|
487 | 512 | case BPF_ALU64 | BPF_OR | BPF_K:/* dst = dst | imm */ |
---|
488 | 513 | if (imm < 0 && BPF_CLASS(code) == BPF_ALU64) { |
---|
489 | 514 | /* Sign-extended */ |
---|
490 | 515 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
491 | | - PPC_OR(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 516 | + EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
492 | 517 | } else { |
---|
493 | 518 | if (IMM_L(imm)) |
---|
494 | | - PPC_ORI(dst_reg, dst_reg, IMM_L(imm)); |
---|
| 519 | + EMIT(PPC_RAW_ORI(dst_reg, dst_reg, IMM_L(imm))); |
---|
495 | 520 | if (IMM_H(imm)) |
---|
496 | | - PPC_ORIS(dst_reg, dst_reg, IMM_H(imm)); |
---|
| 521 | + EMIT(PPC_RAW_ORIS(dst_reg, dst_reg, IMM_H(imm))); |
---|
497 | 522 | } |
---|
498 | 523 | goto bpf_alu32_trunc; |
---|
499 | 524 | case BPF_ALU | BPF_XOR | BPF_X: /* (u32) dst ^= src */ |
---|
500 | 525 | case BPF_ALU64 | BPF_XOR | BPF_X: /* dst ^= src */ |
---|
501 | | - PPC_XOR(dst_reg, dst_reg, src_reg); |
---|
| 526 | + EMIT(PPC_RAW_XOR(dst_reg, dst_reg, src_reg)); |
---|
502 | 527 | goto bpf_alu32_trunc; |
---|
503 | 528 | case BPF_ALU | BPF_XOR | BPF_K: /* (u32) dst ^= (u32) imm */ |
---|
504 | 529 | case BPF_ALU64 | BPF_XOR | BPF_K: /* dst ^= imm */ |
---|
505 | 530 | if (imm < 0 && BPF_CLASS(code) == BPF_ALU64) { |
---|
506 | 531 | /* Sign-extended */ |
---|
507 | 532 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
508 | | - PPC_XOR(dst_reg, dst_reg, b2p[TMP_REG_1]); |
---|
| 533 | + EMIT(PPC_RAW_XOR(dst_reg, dst_reg, b2p[TMP_REG_1])); |
---|
509 | 534 | } else { |
---|
510 | 535 | if (IMM_L(imm)) |
---|
511 | | - PPC_XORI(dst_reg, dst_reg, IMM_L(imm)); |
---|
| 536 | + EMIT(PPC_RAW_XORI(dst_reg, dst_reg, IMM_L(imm))); |
---|
512 | 537 | if (IMM_H(imm)) |
---|
513 | | - PPC_XORIS(dst_reg, dst_reg, IMM_H(imm)); |
---|
| 538 | + EMIT(PPC_RAW_XORIS(dst_reg, dst_reg, IMM_H(imm))); |
---|
514 | 539 | } |
---|
515 | 540 | goto bpf_alu32_trunc; |
---|
516 | 541 | case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */ |
---|
517 | 542 | /* slw clears top 32 bits */ |
---|
518 | | - PPC_SLW(dst_reg, dst_reg, src_reg); |
---|
| 543 | + EMIT(PPC_RAW_SLW(dst_reg, dst_reg, src_reg)); |
---|
| 544 | + /* skip zero extension move, but set address map. */ |
---|
| 545 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 546 | + addrs[++i] = ctx->idx * 4; |
---|
519 | 547 | break; |
---|
520 | 548 | case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */ |
---|
521 | | - PPC_SLD(dst_reg, dst_reg, src_reg); |
---|
| 549 | + EMIT(PPC_RAW_SLD(dst_reg, dst_reg, src_reg)); |
---|
522 | 550 | break; |
---|
523 | 551 | case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */ |
---|
524 | 552 | /* with imm 0, we still need to clear top 32 bits */ |
---|
525 | | - PPC_SLWI(dst_reg, dst_reg, imm); |
---|
| 553 | + EMIT(PPC_RAW_SLWI(dst_reg, dst_reg, imm)); |
---|
| 554 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 555 | + addrs[++i] = ctx->idx * 4; |
---|
526 | 556 | break; |
---|
527 | 557 | case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */ |
---|
528 | 558 | if (imm != 0) |
---|
529 | | - PPC_SLDI(dst_reg, dst_reg, imm); |
---|
| 559 | + EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, imm)); |
---|
530 | 560 | break; |
---|
531 | 561 | case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */ |
---|
532 | | - PPC_SRW(dst_reg, dst_reg, src_reg); |
---|
| 562 | + EMIT(PPC_RAW_SRW(dst_reg, dst_reg, src_reg)); |
---|
| 563 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 564 | + addrs[++i] = ctx->idx * 4; |
---|
533 | 565 | break; |
---|
534 | 566 | case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */ |
---|
535 | | - PPC_SRD(dst_reg, dst_reg, src_reg); |
---|
| 567 | + EMIT(PPC_RAW_SRD(dst_reg, dst_reg, src_reg)); |
---|
536 | 568 | break; |
---|
537 | 569 | case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */ |
---|
538 | | - PPC_SRWI(dst_reg, dst_reg, imm); |
---|
| 570 | + EMIT(PPC_RAW_SRWI(dst_reg, dst_reg, imm)); |
---|
| 571 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 572 | + addrs[++i] = ctx->idx * 4; |
---|
539 | 573 | break; |
---|
540 | 574 | case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */ |
---|
541 | 575 | if (imm != 0) |
---|
542 | | - PPC_SRDI(dst_reg, dst_reg, imm); |
---|
| 576 | + EMIT(PPC_RAW_SRDI(dst_reg, dst_reg, imm)); |
---|
543 | 577 | break; |
---|
| 578 | + case BPF_ALU | BPF_ARSH | BPF_X: /* (s32) dst >>= src */ |
---|
| 579 | + EMIT(PPC_RAW_SRAW(dst_reg, dst_reg, src_reg)); |
---|
| 580 | + goto bpf_alu32_trunc; |
---|
544 | 581 | case BPF_ALU64 | BPF_ARSH | BPF_X: /* (s64) dst >>= src */ |
---|
545 | | - PPC_SRAD(dst_reg, dst_reg, src_reg); |
---|
| 582 | + EMIT(PPC_RAW_SRAD(dst_reg, dst_reg, src_reg)); |
---|
546 | 583 | break; |
---|
| 584 | + case BPF_ALU | BPF_ARSH | BPF_K: /* (s32) dst >>= imm */ |
---|
| 585 | + EMIT(PPC_RAW_SRAWI(dst_reg, dst_reg, imm)); |
---|
| 586 | + goto bpf_alu32_trunc; |
---|
547 | 587 | case BPF_ALU64 | BPF_ARSH | BPF_K: /* (s64) dst >>= imm */ |
---|
548 | 588 | if (imm != 0) |
---|
549 | | - PPC_SRADI(dst_reg, dst_reg, imm); |
---|
| 589 | + EMIT(PPC_RAW_SRADI(dst_reg, dst_reg, imm)); |
---|
550 | 590 | break; |
---|
551 | 591 | |
---|
552 | 592 | /* |
---|
.. | .. |
---|
554 | 594 | */ |
---|
555 | 595 | case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */ |
---|
556 | 596 | case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */ |
---|
557 | | - PPC_MR(dst_reg, src_reg); |
---|
| 597 | + if (imm == 1) { |
---|
| 598 | + /* special mov32 for zext */ |
---|
| 599 | + EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31)); |
---|
| 600 | + break; |
---|
| 601 | + } |
---|
| 602 | + EMIT(PPC_RAW_MR(dst_reg, src_reg)); |
---|
558 | 603 | goto bpf_alu32_trunc; |
---|
559 | 604 | case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */ |
---|
560 | 605 | case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = (s64) imm */ |
---|
561 | 606 | PPC_LI32(dst_reg, imm); |
---|
562 | 607 | if (imm < 0) |
---|
563 | 608 | goto bpf_alu32_trunc; |
---|
| 609 | + else if (insn_is_zext(&insn[i + 1])) |
---|
| 610 | + addrs[++i] = ctx->idx * 4; |
---|
564 | 611 | break; |
---|
565 | 612 | |
---|
566 | 613 | bpf_alu32_trunc: |
---|
567 | 614 | /* Truncate to 32-bits */ |
---|
568 | | - if (BPF_CLASS(code) == BPF_ALU) |
---|
569 | | - PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31); |
---|
| 615 | + if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext) |
---|
| 616 | + EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31)); |
---|
570 | 617 | break; |
---|
571 | 618 | |
---|
572 | 619 | /* |
---|
.. | .. |
---|
584 | 631 | switch (imm) { |
---|
585 | 632 | case 16: |
---|
586 | 633 | /* Rotate 8 bits left & mask with 0x0000ff00 */ |
---|
587 | | - PPC_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 16, 23); |
---|
| 634 | + EMIT(PPC_RAW_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 16, 23)); |
---|
588 | 635 | /* Rotate 8 bits right & insert LSB to reg */ |
---|
589 | | - PPC_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 24, 31); |
---|
| 636 | + EMIT(PPC_RAW_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 24, 31)); |
---|
590 | 637 | /* Move result back to dst_reg */ |
---|
591 | | - PPC_MR(dst_reg, b2p[TMP_REG_1]); |
---|
| 638 | + EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1])); |
---|
592 | 639 | break; |
---|
593 | 640 | case 32: |
---|
594 | 641 | /* |
---|
.. | .. |
---|
596 | 643 | * 2 bytes are already in their final position |
---|
597 | 644 | * -- byte 2 and 4 (of bytes 1, 2, 3 and 4) |
---|
598 | 645 | */ |
---|
599 | | - PPC_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 0, 31); |
---|
| 646 | + EMIT(PPC_RAW_RLWINM(b2p[TMP_REG_1], dst_reg, 8, 0, 31)); |
---|
600 | 647 | /* Rotate 24 bits and insert byte 1 */ |
---|
601 | | - PPC_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 0, 7); |
---|
| 648 | + EMIT(PPC_RAW_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 0, 7)); |
---|
602 | 649 | /* Rotate 24 bits and insert byte 3 */ |
---|
603 | | - PPC_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 16, 23); |
---|
604 | | - PPC_MR(dst_reg, b2p[TMP_REG_1]); |
---|
| 650 | + EMIT(PPC_RAW_RLWIMI(b2p[TMP_REG_1], dst_reg, 24, 16, 23)); |
---|
| 651 | + EMIT(PPC_RAW_MR(dst_reg, b2p[TMP_REG_1])); |
---|
605 | 652 | break; |
---|
606 | 653 | case 64: |
---|
607 | | - /* |
---|
608 | | - * Way easier and faster(?) to store the value |
---|
609 | | - * into stack and then use ldbrx |
---|
610 | | - * |
---|
611 | | - * ctx->seen will be reliable in pass2, but |
---|
612 | | - * the instructions generated will remain the |
---|
613 | | - * same across all passes |
---|
614 | | - */ |
---|
| 654 | + /* Store the value to stack and then use byte-reverse loads */ |
---|
615 | 655 | PPC_BPF_STL(dst_reg, 1, bpf_jit_stack_local(ctx)); |
---|
616 | | - PPC_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx)); |
---|
617 | | - PPC_LDBRX(dst_reg, 0, b2p[TMP_REG_1]); |
---|
| 656 | + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], 1, bpf_jit_stack_local(ctx))); |
---|
| 657 | + if (cpu_has_feature(CPU_FTR_ARCH_206)) { |
---|
| 658 | + EMIT(PPC_RAW_LDBRX(dst_reg, 0, b2p[TMP_REG_1])); |
---|
| 659 | + } else { |
---|
| 660 | + EMIT(PPC_RAW_LWBRX(dst_reg, 0, b2p[TMP_REG_1])); |
---|
| 661 | + if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) |
---|
| 662 | + EMIT(PPC_RAW_SLDI(dst_reg, dst_reg, 32)); |
---|
| 663 | + EMIT(PPC_RAW_LI(b2p[TMP_REG_2], 4)); |
---|
| 664 | + EMIT(PPC_RAW_LWBRX(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p[TMP_REG_1])); |
---|
| 665 | + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) |
---|
| 666 | + EMIT(PPC_RAW_SLDI(b2p[TMP_REG_2], b2p[TMP_REG_2], 32)); |
---|
| 667 | + EMIT(PPC_RAW_OR(dst_reg, dst_reg, b2p[TMP_REG_2])); |
---|
| 668 | + } |
---|
618 | 669 | break; |
---|
619 | 670 | } |
---|
620 | 671 | break; |
---|
.. | .. |
---|
623 | 674 | switch (imm) { |
---|
624 | 675 | case 16: |
---|
625 | 676 | /* zero-extend 16 bits into 64 bits */ |
---|
626 | | - PPC_RLDICL(dst_reg, dst_reg, 0, 48); |
---|
| 677 | + EMIT(PPC_RAW_RLDICL(dst_reg, dst_reg, 0, 48)); |
---|
| 678 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 679 | + addrs[++i] = ctx->idx * 4; |
---|
627 | 680 | break; |
---|
628 | 681 | case 32: |
---|
629 | | - /* zero-extend 32 bits into 64 bits */ |
---|
630 | | - PPC_RLDICL(dst_reg, dst_reg, 0, 32); |
---|
| 682 | + if (!fp->aux->verifier_zext) |
---|
| 683 | + /* zero-extend 32 bits into 64 bits */ |
---|
| 684 | + EMIT(PPC_RAW_RLDICL(dst_reg, dst_reg, 0, 32)); |
---|
631 | 685 | break; |
---|
632 | 686 | case 64: |
---|
633 | 687 | /* nop */ |
---|
.. | .. |
---|
641 | 695 | case BPF_ST | BPF_NOSPEC: |
---|
642 | 696 | if (!security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) || |
---|
643 | 697 | (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) && |
---|
644 | | - (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) || !cpu_has_feature(CPU_FTR_HVMODE)))) |
---|
| 698 | + (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) || !cpu_has_feature(CPU_FTR_HVMODE)))) |
---|
645 | 699 | break; |
---|
646 | 700 | |
---|
647 | 701 | switch (stf_barrier) { |
---|
.. | .. |
---|
650 | 704 | break; |
---|
651 | 705 | case STF_BARRIER_SYNC_ORI: |
---|
652 | 706 | EMIT(PPC_INST_SYNC); |
---|
653 | | - PPC_LD(b2p[TMP_REG_1], 13, 0); |
---|
654 | | - PPC_ORI(31, 31, 0); |
---|
| 707 | + EMIT(PPC_RAW_LD(b2p[TMP_REG_1], 13, 0)); |
---|
| 708 | + EMIT(PPC_RAW_ORI(31, 31, 0)); |
---|
655 | 709 | break; |
---|
656 | 710 | case STF_BARRIER_FALLBACK: |
---|
657 | 711 | EMIT(PPC_INST_MFLR | ___PPC_RT(b2p[TMP_REG_1])); |
---|
658 | 712 | PPC_LI64(12, dereference_kernel_function_descriptor(bpf_stf_barrier)); |
---|
659 | | - PPC_MTCTR(12); |
---|
| 713 | + EMIT(PPC_RAW_MTCTR(12)); |
---|
660 | 714 | EMIT(PPC_INST_BCTR | 0x1); |
---|
661 | | - PPC_MTLR(b2p[TMP_REG_1]); |
---|
| 715 | + EMIT(PPC_RAW_MTLR(b2p[TMP_REG_1])); |
---|
662 | 716 | break; |
---|
663 | 717 | case STF_BARRIER_NONE: |
---|
664 | 718 | break; |
---|
.. | .. |
---|
671 | 725 | case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src */ |
---|
672 | 726 | case BPF_ST | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = imm */ |
---|
673 | 727 | if (BPF_CLASS(code) == BPF_ST) { |
---|
674 | | - PPC_LI(b2p[TMP_REG_1], imm); |
---|
| 728 | + EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm)); |
---|
675 | 729 | src_reg = b2p[TMP_REG_1]; |
---|
676 | 730 | } |
---|
677 | | - PPC_STB(src_reg, dst_reg, off); |
---|
| 731 | + EMIT(PPC_RAW_STB(src_reg, dst_reg, off)); |
---|
678 | 732 | break; |
---|
679 | 733 | case BPF_STX | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = src */ |
---|
680 | 734 | case BPF_ST | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = imm */ |
---|
681 | 735 | if (BPF_CLASS(code) == BPF_ST) { |
---|
682 | | - PPC_LI(b2p[TMP_REG_1], imm); |
---|
| 736 | + EMIT(PPC_RAW_LI(b2p[TMP_REG_1], imm)); |
---|
683 | 737 | src_reg = b2p[TMP_REG_1]; |
---|
684 | 738 | } |
---|
685 | | - PPC_STH(src_reg, dst_reg, off); |
---|
| 739 | + EMIT(PPC_RAW_STH(src_reg, dst_reg, off)); |
---|
686 | 740 | break; |
---|
687 | 741 | case BPF_STX | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = src */ |
---|
688 | 742 | case BPF_ST | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = imm */ |
---|
.. | .. |
---|
690 | 744 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
691 | 745 | src_reg = b2p[TMP_REG_1]; |
---|
692 | 746 | } |
---|
693 | | - PPC_STW(src_reg, dst_reg, off); |
---|
| 747 | + EMIT(PPC_RAW_STW(src_reg, dst_reg, off)); |
---|
694 | 748 | break; |
---|
695 | 749 | case BPF_STX | BPF_MEM | BPF_DW: /* (u64 *)(dst + off) = src */ |
---|
696 | 750 | case BPF_ST | BPF_MEM | BPF_DW: /* *(u64 *)(dst + off) = imm */ |
---|
.. | .. |
---|
707 | 761 | /* *(u32 *)(dst + off) += src */ |
---|
708 | 762 | case BPF_STX | BPF_XADD | BPF_W: |
---|
709 | 763 | /* Get EA into TMP_REG_1 */ |
---|
710 | | - PPC_ADDI(b2p[TMP_REG_1], dst_reg, off); |
---|
| 764 | + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], dst_reg, off)); |
---|
711 | 765 | tmp_idx = ctx->idx * 4; |
---|
712 | 766 | /* load value from memory into TMP_REG_2 */ |
---|
713 | | - PPC_BPF_LWARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0); |
---|
| 767 | + EMIT(PPC_RAW_LWARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0)); |
---|
714 | 768 | /* add value from src_reg into this */ |
---|
715 | | - PPC_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg); |
---|
| 769 | + EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg)); |
---|
716 | 770 | /* store result back */ |
---|
717 | | - PPC_BPF_STWCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]); |
---|
| 771 | + EMIT(PPC_RAW_STWCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1])); |
---|
718 | 772 | /* we're done if this succeeded */ |
---|
719 | 773 | PPC_BCC_SHORT(COND_NE, tmp_idx); |
---|
720 | 774 | break; |
---|
721 | 775 | /* *(u64 *)(dst + off) += src */ |
---|
722 | 776 | case BPF_STX | BPF_XADD | BPF_DW: |
---|
723 | | - PPC_ADDI(b2p[TMP_REG_1], dst_reg, off); |
---|
| 777 | + EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], dst_reg, off)); |
---|
724 | 778 | tmp_idx = ctx->idx * 4; |
---|
725 | | - PPC_BPF_LDARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0); |
---|
726 | | - PPC_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg); |
---|
727 | | - PPC_BPF_STDCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1]); |
---|
| 779 | + EMIT(PPC_RAW_LDARX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1], 0)); |
---|
| 780 | + EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], src_reg)); |
---|
| 781 | + EMIT(PPC_RAW_STDCX(b2p[TMP_REG_2], 0, b2p[TMP_REG_1])); |
---|
728 | 782 | PPC_BCC_SHORT(COND_NE, tmp_idx); |
---|
729 | 783 | break; |
---|
730 | 784 | |
---|
.. | .. |
---|
733 | 787 | */ |
---|
734 | 788 | /* dst = *(u8 *)(ul) (src + off) */ |
---|
735 | 789 | case BPF_LDX | BPF_MEM | BPF_B: |
---|
736 | | - PPC_LBZ(dst_reg, src_reg, off); |
---|
| 790 | + EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off)); |
---|
| 791 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 792 | + addrs[++i] = ctx->idx * 4; |
---|
737 | 793 | break; |
---|
738 | 794 | /* dst = *(u16 *)(ul) (src + off) */ |
---|
739 | 795 | case BPF_LDX | BPF_MEM | BPF_H: |
---|
740 | | - PPC_LHZ(dst_reg, src_reg, off); |
---|
| 796 | + EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off)); |
---|
| 797 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 798 | + addrs[++i] = ctx->idx * 4; |
---|
741 | 799 | break; |
---|
742 | 800 | /* dst = *(u32 *)(ul) (src + off) */ |
---|
743 | 801 | case BPF_LDX | BPF_MEM | BPF_W: |
---|
744 | | - PPC_LWZ(dst_reg, src_reg, off); |
---|
| 802 | + EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off)); |
---|
| 803 | + if (insn_is_zext(&insn[i + 1])) |
---|
| 804 | + addrs[++i] = ctx->idx * 4; |
---|
745 | 805 | break; |
---|
746 | 806 | /* dst = *(u64 *)(ul) (src + off) */ |
---|
747 | 807 | case BPF_LDX | BPF_MEM | BPF_DW: |
---|
.. | .. |
---|
780 | 840 | case BPF_JMP | BPF_CALL: |
---|
781 | 841 | ctx->seen |= SEEN_FUNC; |
---|
782 | 842 | |
---|
783 | | - /* bpf function call */ |
---|
784 | | - if (insn[i].src_reg == BPF_PSEUDO_CALL) |
---|
785 | | - if (!extra_pass) |
---|
786 | | - func = NULL; |
---|
787 | | - else if (fp->aux->func && off < fp->aux->func_cnt) |
---|
788 | | - /* use the subprog id from the off |
---|
789 | | - * field to lookup the callee address |
---|
790 | | - */ |
---|
791 | | - func = (u8 *) fp->aux->func[off]->bpf_func; |
---|
792 | | - else |
---|
793 | | - return -EINVAL; |
---|
794 | | - /* kernel helper call */ |
---|
| 843 | + ret = bpf_jit_get_func_addr(fp, &insn[i], extra_pass, |
---|
| 844 | + &func_addr, &func_addr_fixed); |
---|
| 845 | + if (ret < 0) |
---|
| 846 | + return ret; |
---|
| 847 | + |
---|
| 848 | + if (func_addr_fixed) |
---|
| 849 | + bpf_jit_emit_func_call_hlp(image, ctx, func_addr); |
---|
795 | 850 | else |
---|
796 | | - func = (u8 *) __bpf_call_base + imm; |
---|
797 | | - |
---|
798 | | - bpf_jit_emit_func_call(image, ctx, (u64)func); |
---|
799 | | - |
---|
| 851 | + bpf_jit_emit_func_call_rel(image, ctx, func_addr); |
---|
800 | 852 | /* move return value from r3 to BPF_REG_0 */ |
---|
801 | | - PPC_MR(b2p[BPF_REG_0], 3); |
---|
| 853 | + EMIT(PPC_RAW_MR(b2p[BPF_REG_0], 3)); |
---|
802 | 854 | break; |
---|
803 | 855 | |
---|
804 | 856 | /* |
---|
.. | .. |
---|
812 | 864 | case BPF_JMP | BPF_JGT | BPF_X: |
---|
813 | 865 | case BPF_JMP | BPF_JSGT | BPF_K: |
---|
814 | 866 | case BPF_JMP | BPF_JSGT | BPF_X: |
---|
| 867 | + case BPF_JMP32 | BPF_JGT | BPF_K: |
---|
| 868 | + case BPF_JMP32 | BPF_JGT | BPF_X: |
---|
| 869 | + case BPF_JMP32 | BPF_JSGT | BPF_K: |
---|
| 870 | + case BPF_JMP32 | BPF_JSGT | BPF_X: |
---|
815 | 871 | true_cond = COND_GT; |
---|
816 | 872 | goto cond_branch; |
---|
817 | 873 | case BPF_JMP | BPF_JLT | BPF_K: |
---|
818 | 874 | case BPF_JMP | BPF_JLT | BPF_X: |
---|
819 | 875 | case BPF_JMP | BPF_JSLT | BPF_K: |
---|
820 | 876 | case BPF_JMP | BPF_JSLT | BPF_X: |
---|
| 877 | + case BPF_JMP32 | BPF_JLT | BPF_K: |
---|
| 878 | + case BPF_JMP32 | BPF_JLT | BPF_X: |
---|
| 879 | + case BPF_JMP32 | BPF_JSLT | BPF_K: |
---|
| 880 | + case BPF_JMP32 | BPF_JSLT | BPF_X: |
---|
821 | 881 | true_cond = COND_LT; |
---|
822 | 882 | goto cond_branch; |
---|
823 | 883 | case BPF_JMP | BPF_JGE | BPF_K: |
---|
824 | 884 | case BPF_JMP | BPF_JGE | BPF_X: |
---|
825 | 885 | case BPF_JMP | BPF_JSGE | BPF_K: |
---|
826 | 886 | case BPF_JMP | BPF_JSGE | BPF_X: |
---|
| 887 | + case BPF_JMP32 | BPF_JGE | BPF_K: |
---|
| 888 | + case BPF_JMP32 | BPF_JGE | BPF_X: |
---|
| 889 | + case BPF_JMP32 | BPF_JSGE | BPF_K: |
---|
| 890 | + case BPF_JMP32 | BPF_JSGE | BPF_X: |
---|
827 | 891 | true_cond = COND_GE; |
---|
828 | 892 | goto cond_branch; |
---|
829 | 893 | case BPF_JMP | BPF_JLE | BPF_K: |
---|
830 | 894 | case BPF_JMP | BPF_JLE | BPF_X: |
---|
831 | 895 | case BPF_JMP | BPF_JSLE | BPF_K: |
---|
832 | 896 | case BPF_JMP | BPF_JSLE | BPF_X: |
---|
| 897 | + case BPF_JMP32 | BPF_JLE | BPF_K: |
---|
| 898 | + case BPF_JMP32 | BPF_JLE | BPF_X: |
---|
| 899 | + case BPF_JMP32 | BPF_JSLE | BPF_K: |
---|
| 900 | + case BPF_JMP32 | BPF_JSLE | BPF_X: |
---|
833 | 901 | true_cond = COND_LE; |
---|
834 | 902 | goto cond_branch; |
---|
835 | 903 | case BPF_JMP | BPF_JEQ | BPF_K: |
---|
836 | 904 | case BPF_JMP | BPF_JEQ | BPF_X: |
---|
| 905 | + case BPF_JMP32 | BPF_JEQ | BPF_K: |
---|
| 906 | + case BPF_JMP32 | BPF_JEQ | BPF_X: |
---|
837 | 907 | true_cond = COND_EQ; |
---|
838 | 908 | goto cond_branch; |
---|
839 | 909 | case BPF_JMP | BPF_JNE | BPF_K: |
---|
840 | 910 | case BPF_JMP | BPF_JNE | BPF_X: |
---|
| 911 | + case BPF_JMP32 | BPF_JNE | BPF_K: |
---|
| 912 | + case BPF_JMP32 | BPF_JNE | BPF_X: |
---|
841 | 913 | true_cond = COND_NE; |
---|
842 | 914 | goto cond_branch; |
---|
843 | 915 | case BPF_JMP | BPF_JSET | BPF_K: |
---|
844 | 916 | case BPF_JMP | BPF_JSET | BPF_X: |
---|
| 917 | + case BPF_JMP32 | BPF_JSET | BPF_K: |
---|
| 918 | + case BPF_JMP32 | BPF_JSET | BPF_X: |
---|
845 | 919 | true_cond = COND_NE; |
---|
846 | 920 | /* Fall through */ |
---|
847 | 921 | |
---|
.. | .. |
---|
853 | 927 | case BPF_JMP | BPF_JLE | BPF_X: |
---|
854 | 928 | case BPF_JMP | BPF_JEQ | BPF_X: |
---|
855 | 929 | case BPF_JMP | BPF_JNE | BPF_X: |
---|
| 930 | + case BPF_JMP32 | BPF_JGT | BPF_X: |
---|
| 931 | + case BPF_JMP32 | BPF_JLT | BPF_X: |
---|
| 932 | + case BPF_JMP32 | BPF_JGE | BPF_X: |
---|
| 933 | + case BPF_JMP32 | BPF_JLE | BPF_X: |
---|
| 934 | + case BPF_JMP32 | BPF_JEQ | BPF_X: |
---|
| 935 | + case BPF_JMP32 | BPF_JNE | BPF_X: |
---|
856 | 936 | /* unsigned comparison */ |
---|
857 | | - PPC_CMPLD(dst_reg, src_reg); |
---|
| 937 | + if (BPF_CLASS(code) == BPF_JMP32) |
---|
| 938 | + EMIT(PPC_RAW_CMPLW(dst_reg, src_reg)); |
---|
| 939 | + else |
---|
| 940 | + EMIT(PPC_RAW_CMPLD(dst_reg, src_reg)); |
---|
858 | 941 | break; |
---|
859 | 942 | case BPF_JMP | BPF_JSGT | BPF_X: |
---|
860 | 943 | case BPF_JMP | BPF_JSLT | BPF_X: |
---|
861 | 944 | case BPF_JMP | BPF_JSGE | BPF_X: |
---|
862 | 945 | case BPF_JMP | BPF_JSLE | BPF_X: |
---|
| 946 | + case BPF_JMP32 | BPF_JSGT | BPF_X: |
---|
| 947 | + case BPF_JMP32 | BPF_JSLT | BPF_X: |
---|
| 948 | + case BPF_JMP32 | BPF_JSGE | BPF_X: |
---|
| 949 | + case BPF_JMP32 | BPF_JSLE | BPF_X: |
---|
863 | 950 | /* signed comparison */ |
---|
864 | | - PPC_CMPD(dst_reg, src_reg); |
---|
| 951 | + if (BPF_CLASS(code) == BPF_JMP32) |
---|
| 952 | + EMIT(PPC_RAW_CMPW(dst_reg, src_reg)); |
---|
| 953 | + else |
---|
| 954 | + EMIT(PPC_RAW_CMPD(dst_reg, src_reg)); |
---|
865 | 955 | break; |
---|
866 | 956 | case BPF_JMP | BPF_JSET | BPF_X: |
---|
867 | | - PPC_AND_DOT(b2p[TMP_REG_1], dst_reg, src_reg); |
---|
| 957 | + case BPF_JMP32 | BPF_JSET | BPF_X: |
---|
| 958 | + if (BPF_CLASS(code) == BPF_JMP) { |
---|
| 959 | + EMIT(PPC_RAW_AND_DOT(b2p[TMP_REG_1], dst_reg, |
---|
| 960 | + src_reg)); |
---|
| 961 | + } else { |
---|
| 962 | + int tmp_reg = b2p[TMP_REG_1]; |
---|
| 963 | + |
---|
| 964 | + EMIT(PPC_RAW_AND(tmp_reg, dst_reg, src_reg)); |
---|
| 965 | + EMIT(PPC_RAW_RLWINM_DOT(tmp_reg, tmp_reg, 0, 0, |
---|
| 966 | + 31)); |
---|
| 967 | + } |
---|
868 | 968 | break; |
---|
869 | 969 | case BPF_JMP | BPF_JNE | BPF_K: |
---|
870 | 970 | case BPF_JMP | BPF_JEQ | BPF_K: |
---|
.. | .. |
---|
872 | 972 | case BPF_JMP | BPF_JLT | BPF_K: |
---|
873 | 973 | case BPF_JMP | BPF_JGE | BPF_K: |
---|
874 | 974 | case BPF_JMP | BPF_JLE | BPF_K: |
---|
| 975 | + case BPF_JMP32 | BPF_JNE | BPF_K: |
---|
| 976 | + case BPF_JMP32 | BPF_JEQ | BPF_K: |
---|
| 977 | + case BPF_JMP32 | BPF_JGT | BPF_K: |
---|
| 978 | + case BPF_JMP32 | BPF_JLT | BPF_K: |
---|
| 979 | + case BPF_JMP32 | BPF_JGE | BPF_K: |
---|
| 980 | + case BPF_JMP32 | BPF_JLE | BPF_K: |
---|
| 981 | + { |
---|
| 982 | + bool is_jmp32 = BPF_CLASS(code) == BPF_JMP32; |
---|
| 983 | + |
---|
875 | 984 | /* |
---|
876 | 985 | * Need sign-extended load, so only positive |
---|
877 | 986 | * values can be used as imm in cmpldi |
---|
878 | 987 | */ |
---|
879 | | - if (imm >= 0 && imm < 32768) |
---|
880 | | - PPC_CMPLDI(dst_reg, imm); |
---|
881 | | - else { |
---|
| 988 | + if (imm >= 0 && imm < 32768) { |
---|
| 989 | + if (is_jmp32) |
---|
| 990 | + EMIT(PPC_RAW_CMPLWI(dst_reg, imm)); |
---|
| 991 | + else |
---|
| 992 | + EMIT(PPC_RAW_CMPLDI(dst_reg, imm)); |
---|
| 993 | + } else { |
---|
882 | 994 | /* sign-extending load */ |
---|
883 | 995 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
884 | 996 | /* ... but unsigned comparison */ |
---|
885 | | - PPC_CMPLD(dst_reg, b2p[TMP_REG_1]); |
---|
| 997 | + if (is_jmp32) |
---|
| 998 | + EMIT(PPC_RAW_CMPLW(dst_reg, |
---|
| 999 | + b2p[TMP_REG_1])); |
---|
| 1000 | + else |
---|
| 1001 | + EMIT(PPC_RAW_CMPLD(dst_reg, |
---|
| 1002 | + b2p[TMP_REG_1])); |
---|
886 | 1003 | } |
---|
887 | 1004 | break; |
---|
| 1005 | + } |
---|
888 | 1006 | case BPF_JMP | BPF_JSGT | BPF_K: |
---|
889 | 1007 | case BPF_JMP | BPF_JSLT | BPF_K: |
---|
890 | 1008 | case BPF_JMP | BPF_JSGE | BPF_K: |
---|
891 | 1009 | case BPF_JMP | BPF_JSLE | BPF_K: |
---|
| 1010 | + case BPF_JMP32 | BPF_JSGT | BPF_K: |
---|
| 1011 | + case BPF_JMP32 | BPF_JSLT | BPF_K: |
---|
| 1012 | + case BPF_JMP32 | BPF_JSGE | BPF_K: |
---|
| 1013 | + case BPF_JMP32 | BPF_JSLE | BPF_K: |
---|
| 1014 | + { |
---|
| 1015 | + bool is_jmp32 = BPF_CLASS(code) == BPF_JMP32; |
---|
| 1016 | + |
---|
892 | 1017 | /* |
---|
893 | 1018 | * signed comparison, so any 16-bit value |
---|
894 | 1019 | * can be used in cmpdi |
---|
895 | 1020 | */ |
---|
896 | | - if (imm >= -32768 && imm < 32768) |
---|
897 | | - PPC_CMPDI(dst_reg, imm); |
---|
898 | | - else { |
---|
| 1021 | + if (imm >= -32768 && imm < 32768) { |
---|
| 1022 | + if (is_jmp32) |
---|
| 1023 | + EMIT(PPC_RAW_CMPWI(dst_reg, imm)); |
---|
| 1024 | + else |
---|
| 1025 | + EMIT(PPC_RAW_CMPDI(dst_reg, imm)); |
---|
| 1026 | + } else { |
---|
899 | 1027 | PPC_LI32(b2p[TMP_REG_1], imm); |
---|
900 | | - PPC_CMPD(dst_reg, b2p[TMP_REG_1]); |
---|
| 1028 | + if (is_jmp32) |
---|
| 1029 | + EMIT(PPC_RAW_CMPW(dst_reg, |
---|
| 1030 | + b2p[TMP_REG_1])); |
---|
| 1031 | + else |
---|
| 1032 | + EMIT(PPC_RAW_CMPD(dst_reg, |
---|
| 1033 | + b2p[TMP_REG_1])); |
---|
901 | 1034 | } |
---|
902 | 1035 | break; |
---|
| 1036 | + } |
---|
903 | 1037 | case BPF_JMP | BPF_JSET | BPF_K: |
---|
| 1038 | + case BPF_JMP32 | BPF_JSET | BPF_K: |
---|
904 | 1039 | /* andi does not sign-extend the immediate */ |
---|
905 | 1040 | if (imm >= 0 && imm < 32768) |
---|
906 | 1041 | /* PPC_ANDI is _only/always_ dot-form */ |
---|
907 | | - PPC_ANDI(b2p[TMP_REG_1], dst_reg, imm); |
---|
| 1042 | + EMIT(PPC_RAW_ANDI(b2p[TMP_REG_1], dst_reg, imm)); |
---|
908 | 1043 | else { |
---|
909 | | - PPC_LI32(b2p[TMP_REG_1], imm); |
---|
910 | | - PPC_AND_DOT(b2p[TMP_REG_1], dst_reg, |
---|
911 | | - b2p[TMP_REG_1]); |
---|
| 1044 | + int tmp_reg = b2p[TMP_REG_1]; |
---|
| 1045 | + |
---|
| 1046 | + PPC_LI32(tmp_reg, imm); |
---|
| 1047 | + if (BPF_CLASS(code) == BPF_JMP) { |
---|
| 1048 | + EMIT(PPC_RAW_AND_DOT(tmp_reg, dst_reg, |
---|
| 1049 | + tmp_reg)); |
---|
| 1050 | + } else { |
---|
| 1051 | + EMIT(PPC_RAW_AND(tmp_reg, dst_reg, |
---|
| 1052 | + tmp_reg)); |
---|
| 1053 | + EMIT(PPC_RAW_RLWINM_DOT(tmp_reg, tmp_reg, |
---|
| 1054 | + 0, 0, 31)); |
---|
| 1055 | + } |
---|
912 | 1056 | } |
---|
913 | 1057 | break; |
---|
914 | 1058 | } |
---|
.. | .. |
---|
943 | 1087 | return 0; |
---|
944 | 1088 | } |
---|
945 | 1089 | |
---|
| 1090 | +/* Fix the branch target addresses for subprog calls */ |
---|
| 1091 | +static int bpf_jit_fixup_subprog_calls(struct bpf_prog *fp, u32 *image, |
---|
| 1092 | + struct codegen_context *ctx, u32 *addrs) |
---|
| 1093 | +{ |
---|
| 1094 | + const struct bpf_insn *insn = fp->insnsi; |
---|
| 1095 | + bool func_addr_fixed; |
---|
| 1096 | + u64 func_addr; |
---|
| 1097 | + u32 tmp_idx; |
---|
| 1098 | + int i, ret; |
---|
| 1099 | + |
---|
| 1100 | + for (i = 0; i < fp->len; i++) { |
---|
| 1101 | + /* |
---|
| 1102 | + * During the extra pass, only the branch target addresses for |
---|
| 1103 | + * the subprog calls need to be fixed. All other instructions |
---|
| 1104 | + * can left untouched. |
---|
| 1105 | + * |
---|
| 1106 | + * The JITed image length does not change because we already |
---|
| 1107 | + * ensure that the JITed instruction sequence for these calls |
---|
| 1108 | + * are of fixed length by padding them with NOPs. |
---|
| 1109 | + */ |
---|
| 1110 | + if (insn[i].code == (BPF_JMP | BPF_CALL) && |
---|
| 1111 | + insn[i].src_reg == BPF_PSEUDO_CALL) { |
---|
| 1112 | + ret = bpf_jit_get_func_addr(fp, &insn[i], true, |
---|
| 1113 | + &func_addr, |
---|
| 1114 | + &func_addr_fixed); |
---|
| 1115 | + if (ret < 0) |
---|
| 1116 | + return ret; |
---|
| 1117 | + |
---|
| 1118 | + /* |
---|
| 1119 | + * Save ctx->idx as this would currently point to the |
---|
| 1120 | + * end of the JITed image and set it to the offset of |
---|
| 1121 | + * the instruction sequence corresponding to the |
---|
| 1122 | + * subprog call temporarily. |
---|
| 1123 | + */ |
---|
| 1124 | + tmp_idx = ctx->idx; |
---|
| 1125 | + ctx->idx = addrs[i] / 4; |
---|
| 1126 | + bpf_jit_emit_func_call_rel(image, ctx, func_addr); |
---|
| 1127 | + |
---|
| 1128 | + /* |
---|
| 1129 | + * Restore ctx->idx here. This is safe as the length |
---|
| 1130 | + * of the JITed sequence remains unchanged. |
---|
| 1131 | + */ |
---|
| 1132 | + ctx->idx = tmp_idx; |
---|
| 1133 | + } |
---|
| 1134 | + } |
---|
| 1135 | + |
---|
| 1136 | + return 0; |
---|
| 1137 | +} |
---|
| 1138 | + |
---|
946 | 1139 | struct powerpc64_jit_data { |
---|
947 | 1140 | struct bpf_binary_header *header; |
---|
948 | 1141 | u32 *addrs; |
---|
.. | .. |
---|
950 | 1143 | u32 proglen; |
---|
951 | 1144 | struct codegen_context ctx; |
---|
952 | 1145 | }; |
---|
| 1146 | + |
---|
| 1147 | +bool bpf_jit_needs_zext(void) |
---|
| 1148 | +{ |
---|
| 1149 | + return true; |
---|
| 1150 | +} |
---|
953 | 1151 | |
---|
954 | 1152 | struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) |
---|
955 | 1153 | { |
---|
.. | .. |
---|
1054 | 1252 | skip_init_ctx: |
---|
1055 | 1253 | code_base = (u32 *)(image + FUNCTION_DESCR_SIZE); |
---|
1056 | 1254 | |
---|
| 1255 | + if (extra_pass) { |
---|
| 1256 | + /* |
---|
| 1257 | + * Do not touch the prologue and epilogue as they will remain |
---|
| 1258 | + * unchanged. Only fix the branch target address for subprog |
---|
| 1259 | + * calls in the body. |
---|
| 1260 | + * |
---|
| 1261 | + * This does not change the offsets and lengths of the subprog |
---|
| 1262 | + * call instruction sequences and hence, the size of the JITed |
---|
| 1263 | + * image as well. |
---|
| 1264 | + */ |
---|
| 1265 | + bpf_jit_fixup_subprog_calls(fp, code_base, &cgctx, addrs); |
---|
| 1266 | + |
---|
| 1267 | + /* There is no need to perform the usual passes. */ |
---|
| 1268 | + goto skip_codegen_passes; |
---|
| 1269 | + } |
---|
| 1270 | + |
---|
1057 | 1271 | /* Code generation passes 1-2 */ |
---|
1058 | 1272 | for (pass = 1; pass < 3; pass++) { |
---|
1059 | 1273 | /* Now build the prologue, body code & epilogue for real. */ |
---|
.. | .. |
---|
1067 | 1281 | proglen - (cgctx.idx * 4), cgctx.seen); |
---|
1068 | 1282 | } |
---|
1069 | 1283 | |
---|
| 1284 | +skip_codegen_passes: |
---|
1070 | 1285 | if (bpf_jit_enable > 1) |
---|
1071 | 1286 | /* |
---|
1072 | 1287 | * Note that we output the base address of the code_base |
---|
.. | .. |
---|
1086 | 1301 | |
---|
1087 | 1302 | bpf_flush_icache(bpf_hdr, (u8 *)bpf_hdr + (bpf_hdr->pages * PAGE_SIZE)); |
---|
1088 | 1303 | if (!fp->is_func || extra_pass) { |
---|
| 1304 | + bpf_prog_fill_jited_linfo(fp, addrs); |
---|
1089 | 1305 | out_addrs: |
---|
1090 | 1306 | kfree(addrs); |
---|
1091 | 1307 | kfree(jit_data); |
---|