aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/net/bpf_jit_comp.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 80cc76972798..618d2cdc2f1b 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -205,6 +205,12 @@ static void build_epilogue(struct jit_ctx *ctx)
205 emit(A64_RET(A64_LR), ctx); 205 emit(A64_RET(A64_LR), ctx);
206} 206}
207 207
208/* JITs an eBPF instruction.
209 * Returns:
210 * 0 - successfully JITed an 8-byte eBPF instruction.
211 * >0 - successfully JITed a 16-byte eBPF instruction.
212 * <0 - failed to JIT.
213 */
208static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) 214static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
209{ 215{
210 const u8 code = insn->code; 216 const u8 code = insn->code;
@@ -464,6 +470,27 @@ emit_cond_jmp:
464 emit(A64_B(jmp_offset), ctx); 470 emit(A64_B(jmp_offset), ctx);
465 break; 471 break;
466 472
473 /* dst = imm64 */
474 case BPF_LD | BPF_IMM | BPF_DW:
475 {
476 const struct bpf_insn insn1 = insn[1];
477 u64 imm64;
478
479 if (insn1.code != 0 || insn1.src_reg != 0 ||
480 insn1.dst_reg != 0 || insn1.off != 0) {
481 /* Note: verifier in BPF core must catch invalid
482 * instructions.
483 */
484 pr_err_once("Invalid BPF_LD_IMM64 instruction\n");
485 return -EINVAL;
486 }
487
488 imm64 = (u64)insn1.imm << 32 | imm;
489 emit_a64_mov_i64(dst, imm64, ctx);
490
491 return 1;
492 }
493
467 /* LDX: dst = *(size *)(src + off) */ 494 /* LDX: dst = *(size *)(src + off) */
468 case BPF_LDX | BPF_MEM | BPF_W: 495 case BPF_LDX | BPF_MEM | BPF_W:
469 case BPF_LDX | BPF_MEM | BPF_H: 496 case BPF_LDX | BPF_MEM | BPF_H:
@@ -615,6 +642,10 @@ static int build_body(struct jit_ctx *ctx)
615 ctx->offset[i] = ctx->idx; 642 ctx->offset[i] = ctx->idx;
616 643
617 ret = build_insn(insn, ctx); 644 ret = build_insn(insn, ctx);
645 if (ret > 0) {
646 i++;
647 continue;
648 }
618 if (ret) 649 if (ret)
619 return ret; 650 return ret;
620 } 651 }