forked from Minki/linux
bpf, mips64: remove unneeded zero check from div/mod with k
The verifier in both cBPF and eBPF reject div/mod by 0 imm, so this can never load. Remove emitting such test and reject it from being JITed instead (the latter is actually also not needed, but given practice in sparc64, ppc64 today, so doesn't hurt to add it here either). Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: David Daney <david.daney@cavium.com> Reviewed-by: David Daney <david.daney@cavium.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
1fb5c9c622
commit
e472d5d8af
@ -741,16 +741,11 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
|
||||
break;
|
||||
case BPF_ALU | BPF_DIV | BPF_K: /* ALU_IMM */
|
||||
case BPF_ALU | BPF_MOD | BPF_K: /* ALU_IMM */
|
||||
if (insn->imm == 0)
|
||||
return -EINVAL;
|
||||
dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
|
||||
if (dst < 0)
|
||||
return dst;
|
||||
if (insn->imm == 0) { /* Div by zero */
|
||||
b_off = b_imm(exit_idx, ctx);
|
||||
if (is_bad_offset(b_off))
|
||||
return -E2BIG;
|
||||
emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off);
|
||||
emit_instr(ctx, addu, MIPS_R_V0, MIPS_R_ZERO, MIPS_R_ZERO);
|
||||
}
|
||||
td = get_reg_val_type(ctx, this_idx, insn->dst_reg);
|
||||
if (td == REG_64BIT || td == REG_32BIT_ZERO_EX)
|
||||
/* sign extend */
|
||||
@ -770,19 +765,13 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
|
||||
break;
|
||||
case BPF_ALU64 | BPF_DIV | BPF_K: /* ALU_IMM */
|
||||
case BPF_ALU64 | BPF_MOD | BPF_K: /* ALU_IMM */
|
||||
if (insn->imm == 0)
|
||||
return -EINVAL;
|
||||
dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
|
||||
if (dst < 0)
|
||||
return dst;
|
||||
if (insn->imm == 0) { /* Div by zero */
|
||||
b_off = b_imm(exit_idx, ctx);
|
||||
if (is_bad_offset(b_off))
|
||||
return -E2BIG;
|
||||
emit_instr(ctx, beq, MIPS_R_ZERO, MIPS_R_ZERO, b_off);
|
||||
emit_instr(ctx, addu, MIPS_R_V0, MIPS_R_ZERO, MIPS_R_ZERO);
|
||||
}
|
||||
if (get_reg_val_type(ctx, this_idx, insn->dst_reg) == REG_32BIT)
|
||||
emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
|
||||
|
||||
if (insn->imm == 1) {
|
||||
/* div by 1 is a nop, mod by 1 is zero */
|
||||
if (bpf_op == BPF_MOD)
|
||||
|
Loading…
Reference in New Issue
Block a user