arm: bpf: eliminate zero extension code-gen

Cc: Shubham Bansal <illusionist.neo@gmail.com>
Signed-off-by: Jiong Wang <jiong.wang@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Jiong Wang 2019-05-24 23:25:22 +01:00 committed by Alexei Starovoitov
parent 9d120b4127
commit 163541e6ba
1 changed files with 31 additions and 11 deletions

View File

@ -736,7 +736,8 @@ static inline void emit_a32_alu_r64(const bool is64, const s8 dst[],
/* ALU operation */ /* ALU operation */
emit_alu_r(rd[1], rs, true, false, op, ctx); emit_alu_r(rd[1], rs, true, false, op, ctx);
emit_a32_mov_i(rd[0], 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(rd[0], 0, ctx);
} }
arm_bpf_put_reg64(dst, rd, ctx); arm_bpf_put_reg64(dst, rd, ctx);
@ -758,8 +759,9 @@ static inline void emit_a32_mov_r64(const bool is64, const s8 dst[],
struct jit_ctx *ctx) { struct jit_ctx *ctx) {
if (!is64) { if (!is64) {
emit_a32_mov_r(dst_lo, src_lo, ctx); emit_a32_mov_r(dst_lo, src_lo, ctx);
/* Zero out high 4 bytes */ if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(dst_hi, 0, ctx); /* Zero out high 4 bytes */
emit_a32_mov_i(dst_hi, 0, ctx);
} else if (__LINUX_ARM_ARCH__ < 6 && } else if (__LINUX_ARM_ARCH__ < 6 &&
ctx->cpu_architecture < CPU_ARCH_ARMv5TE) { ctx->cpu_architecture < CPU_ARCH_ARMv5TE) {
/* complete 8 byte move */ /* complete 8 byte move */
@ -1060,17 +1062,20 @@ static inline void emit_ldx_r(const s8 dst[], const s8 src,
case BPF_B: case BPF_B:
/* Load a Byte */ /* Load a Byte */
emit(ARM_LDRB_I(rd[1], rm, off), ctx); emit(ARM_LDRB_I(rd[1], rm, off), ctx);
emit_a32_mov_i(rd[0], 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(rd[0], 0, ctx);
break; break;
case BPF_H: case BPF_H:
/* Load a HalfWord */ /* Load a HalfWord */
emit(ARM_LDRH_I(rd[1], rm, off), ctx); emit(ARM_LDRH_I(rd[1], rm, off), ctx);
emit_a32_mov_i(rd[0], 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(rd[0], 0, ctx);
break; break;
case BPF_W: case BPF_W:
/* Load a Word */ /* Load a Word */
emit(ARM_LDR_I(rd[1], rm, off), ctx); emit(ARM_LDR_I(rd[1], rm, off), ctx);
emit_a32_mov_i(rd[0], 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(rd[0], 0, ctx);
break; break;
case BPF_DW: case BPF_DW:
/* Load a Double Word */ /* Load a Double Word */
@ -1359,6 +1364,11 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
case BPF_ALU64 | BPF_MOV | BPF_X: case BPF_ALU64 | BPF_MOV | BPF_X:
switch (BPF_SRC(code)) { switch (BPF_SRC(code)) {
case BPF_X: case BPF_X:
if (imm == 1) {
/* Special mov32 for zext */
emit_a32_mov_i(dst_hi, 0, ctx);
break;
}
emit_a32_mov_r64(is64, dst, src, ctx); emit_a32_mov_r64(is64, dst, src, ctx);
break; break;
case BPF_K: case BPF_K:
@ -1438,7 +1448,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
} }
emit_udivmod(rd_lo, rd_lo, rt, ctx, BPF_OP(code)); emit_udivmod(rd_lo, rd_lo, rt, ctx, BPF_OP(code));
arm_bpf_put_reg32(dst_lo, rd_lo, ctx); arm_bpf_put_reg32(dst_lo, rd_lo, ctx);
emit_a32_mov_i(dst_hi, 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(dst_hi, 0, ctx);
break; break;
case BPF_ALU64 | BPF_DIV | BPF_K: case BPF_ALU64 | BPF_DIV | BPF_K:
case BPF_ALU64 | BPF_DIV | BPF_X: case BPF_ALU64 | BPF_DIV | BPF_X:
@ -1453,7 +1464,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
return -EINVAL; return -EINVAL;
if (imm) if (imm)
emit_a32_alu_i(dst_lo, imm, ctx, BPF_OP(code)); emit_a32_alu_i(dst_lo, imm, ctx, BPF_OP(code));
emit_a32_mov_i(dst_hi, 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(dst_hi, 0, ctx);
break; break;
/* dst = dst << imm */ /* dst = dst << imm */
case BPF_ALU64 | BPF_LSH | BPF_K: case BPF_ALU64 | BPF_LSH | BPF_K:
@ -1488,7 +1500,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
/* dst = ~dst */ /* dst = ~dst */
case BPF_ALU | BPF_NEG: case BPF_ALU | BPF_NEG:
emit_a32_alu_i(dst_lo, 0, ctx, BPF_OP(code)); emit_a32_alu_i(dst_lo, 0, ctx, BPF_OP(code));
emit_a32_mov_i(dst_hi, 0, ctx); if (!ctx->prog->aux->verifier_zext)
emit_a32_mov_i(dst_hi, 0, ctx);
break; break;
/* dst = ~dst (64 bit) */ /* dst = ~dst (64 bit) */
case BPF_ALU64 | BPF_NEG: case BPF_ALU64 | BPF_NEG:
@ -1544,11 +1557,13 @@ emit_bswap_uxt:
#else /* ARMv6+ */ #else /* ARMv6+ */
emit(ARM_UXTH(rd[1], rd[1]), ctx); emit(ARM_UXTH(rd[1], rd[1]), ctx);
#endif #endif
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx); if (!ctx->prog->aux->verifier_zext)
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
break; break;
case 32: case 32:
/* zero-extend 32 bits into 64 bits */ /* zero-extend 32 bits into 64 bits */
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx); if (!ctx->prog->aux->verifier_zext)
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
break; break;
case 64: case 64:
/* nop */ /* nop */
@ -1838,6 +1853,11 @@ void bpf_jit_compile(struct bpf_prog *prog)
/* Nothing to do here. We support Internal BPF. */ /* Nothing to do here. We support Internal BPF. */
} }
bool bpf_jit_needs_zext(void)
{
return true;
}
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
{ {
struct bpf_prog *tmp, *orig_prog = prog; struct bpf_prog *tmp, *orig_prog = prog;