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 | |
| 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>
| -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 | } |
