diff options
author | Zi Shen Lim <zlim.lnx@gmail.com> | 2014-09-16 16:29:23 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2014-10-20 12:47:03 -0400 |
commit | 30d3d94cc3d507a23dcb09e5c365464e4aa9f580 (patch) | |
tree | 61915f1797c20cb0c0cca32d97cf81d1734298a5 /arch/arm64/net | |
parent | d65a634a0acefd6b6e8718e2399b6771ccb17b24 (diff) |
arm64: bpf: add 'load 64-bit immediate' instruction
Commit 02ab695bb37e (net: filter: add "load 64-bit immediate" eBPF
instruction) introduced a new eBPF instruction. Let's add support
for this for arm64 as well.
Our arm64 eBPF JIT compiler now passes the new "load 64-bit
immediate" test case introduced in the same commit 02ab695bb37e.
Signed-off-by: Zi Shen Lim <zlim.lnx@gmail.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/net')
-rw-r--r-- | arch/arm64/net/bpf_jit_comp.c | 31 |
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 | */ | ||
208 | static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) | 214 | static 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 | } |