aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/net/bpf_jit_comp.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2017-04-30 20:57:20 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-02 15:04:50 -0400
commit85f68fe89832057584a9e66e1e7e53d53e50faff (patch)
treeaf912d9385e6e29acc556896e82199b422302190 /arch/arm64/net/bpf_jit_comp.c
parenta481649e1c2a4900450e967165524282bbdf91e0 (diff)
bpf, arm64: implement jiting of BPF_XADD
This work adds BPF_XADD for BPF_W/BPF_DW to the arm64 JIT and therefore completes JITing of all BPF instructions, meaning we can thus also remove the 'notyet' label and do not need to fall back to the interpreter when BPF_XADD is used in a program! This now also brings arm64 JIT in line with x86_64, s390x, ppc64, sparc64, where all current eBPF features are supported. BPF_W example from test_bpf: .u.insns_int = { BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_W, R10, -40, 0x10), BPF_STX_XADD(BPF_W, R10, R0, -40), BPF_LDX_MEM(BPF_W, R0, R10, -40), BPF_EXIT_INSN(), }, [...] 00000020: 52800247 mov w7, #0x12 // #18 00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40 00000028: d280020a mov x10, #0x10 // #16 0000002c: b82b6b2a str w10, [x25,x11] // start of xadd mapping: 00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40 00000034: 8b19014a add x10, x10, x25 00000038: f9800151 prfm pstl1strm, [x10] 0000003c: 885f7d4b ldxr w11, [x10] 00000040: 0b07016b add w11, w11, w7 00000044: 880b7d4b stxr w11, w11, [x10] 00000048: 35ffffab cbnz w11, 0x0000003c // end of xadd mapping: [...] BPF_DW example from test_bpf: .u.insns_int = { BPF_ALU32_IMM(BPF_MOV, R0, 0x12), BPF_ST_MEM(BPF_DW, R10, -40, 0x10), BPF_STX_XADD(BPF_DW, R10, R0, -40), BPF_LDX_MEM(BPF_DW, R0, R10, -40), BPF_EXIT_INSN(), }, [...] 00000020: 52800247 mov w7, #0x12 // #18 00000024: 928004eb mov x11, #0xffffffffffffffd8 // #-40 00000028: d280020a mov x10, #0x10 // #16 0000002c: f82b6b2a str x10, [x25,x11] // start of xadd mapping: 00000030: 928004ea mov x10, #0xffffffffffffffd8 // #-40 00000034: 8b19014a add x10, x10, x25 00000038: f9800151 prfm pstl1strm, [x10] 0000003c: c85f7d4b ldxr x11, [x10] 00000040: 8b07016b add x11, x11, x7 00000044: c80b7d4b stxr w11, x11, [x10] 00000048: 35ffffab cbnz w11, 0x0000003c // end of xadd mapping: [...] Tested on Cavium ThunderX ARMv8, test suite results after the patch: No JIT: [ 3751.855362] test_bpf: Summary: 311 PASSED, 0 FAILED, [0/303 JIT'ed] With JIT: [ 3573.759527] test_bpf: Summary: 311 PASSED, 0 FAILED, [303/303 JIT'ed] Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/arm64/net/bpf_jit_comp.c')
-rw-r--r--arch/arm64/net/bpf_jit_comp.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 304736870dca..4f2b35130f3c 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -321,6 +321,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
321 const s32 imm = insn->imm; 321 const s32 imm = insn->imm;
322 const int i = insn - ctx->prog->insnsi; 322 const int i = insn - ctx->prog->insnsi;
323 const bool is64 = BPF_CLASS(code) == BPF_ALU64; 323 const bool is64 = BPF_CLASS(code) == BPF_ALU64;
324 const bool isdw = BPF_SIZE(code) == BPF_DW;
324 u8 jmp_cond; 325 u8 jmp_cond;
325 s32 jmp_offset; 326 s32 jmp_offset;
326 327
@@ -681,7 +682,16 @@ emit_cond_jmp:
681 case BPF_STX | BPF_XADD | BPF_W: 682 case BPF_STX | BPF_XADD | BPF_W:
682 /* STX XADD: lock *(u64 *)(dst + off) += src */ 683 /* STX XADD: lock *(u64 *)(dst + off) += src */
683 case BPF_STX | BPF_XADD | BPF_DW: 684 case BPF_STX | BPF_XADD | BPF_DW:
684 goto notyet; 685 emit_a64_mov_i(1, tmp, off, ctx);
686 emit(A64_ADD(1, tmp, tmp, dst), ctx);
687 emit(A64_PRFM(tmp, PST, L1, STRM), ctx);
688 emit(A64_LDXR(isdw, tmp2, tmp), ctx);
689 emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
690 emit(A64_STXR(isdw, tmp2, tmp, tmp2), ctx);
691 jmp_offset = -3;
692 check_imm19(jmp_offset);
693 emit(A64_CBNZ(0, tmp2, jmp_offset), ctx);
694 break;
685 695
686 /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */ 696 /* R0 = ntohx(*(size *)(((struct sk_buff *)R6)->data + imm)) */
687 case BPF_LD | BPF_ABS | BPF_W: 697 case BPF_LD | BPF_ABS | BPF_W:
@@ -748,10 +758,6 @@ emit_cond_jmp:
748 } 758 }
749 break; 759 break;
750 } 760 }
751notyet:
752 pr_info_once("*** NOT YET: opcode %02x ***\n", code);
753 return -EFAULT;
754
755 default: 761 default:
756 pr_err_once("unknown opcode %02x\n", code); 762 pr_err_once("unknown opcode %02x\n", code);
757 return -EINVAL; 763 return -EINVAL;