mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
bpf, mips64: remove ld_abs/ld_ind
Since LD_ABS/LD_IND instructions are now removed from the core and reimplemented through a combination of inlined BPF instructions and a slow-path helper, we can get rid of the complexity from mips64 JIT. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
0d2d0cedc0
commit
4db25cc988
1 changed files with 0 additions and 104 deletions
|
@ -1267,110 +1267,6 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPF_LD | BPF_B | BPF_ABS:
|
|
||||||
case BPF_LD | BPF_H | BPF_ABS:
|
|
||||||
case BPF_LD | BPF_W | BPF_ABS:
|
|
||||||
case BPF_LD | BPF_DW | BPF_ABS:
|
|
||||||
ctx->flags |= EBPF_SAVE_RA;
|
|
||||||
|
|
||||||
gen_imm_to_reg(insn, MIPS_R_A1, ctx);
|
|
||||||
emit_instr(ctx, addiu, MIPS_R_A2, MIPS_R_ZERO, size_to_len(insn));
|
|
||||||
|
|
||||||
if (insn->imm < 0) {
|
|
||||||
emit_const_to_reg(ctx, MIPS_R_T9, (u64)bpf_internal_load_pointer_neg_helper);
|
|
||||||
} else {
|
|
||||||
emit_const_to_reg(ctx, MIPS_R_T9, (u64)ool_skb_header_pointer);
|
|
||||||
emit_instr(ctx, daddiu, MIPS_R_A3, MIPS_R_SP, ctx->tmp_offset);
|
|
||||||
}
|
|
||||||
goto ld_skb_common;
|
|
||||||
|
|
||||||
case BPF_LD | BPF_B | BPF_IND:
|
|
||||||
case BPF_LD | BPF_H | BPF_IND:
|
|
||||||
case BPF_LD | BPF_W | BPF_IND:
|
|
||||||
case BPF_LD | BPF_DW | BPF_IND:
|
|
||||||
ctx->flags |= EBPF_SAVE_RA;
|
|
||||||
src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
|
|
||||||
if (src < 0)
|
|
||||||
return src;
|
|
||||||
ts = get_reg_val_type(ctx, this_idx, insn->src_reg);
|
|
||||||
if (ts == REG_32BIT_ZERO_EX) {
|
|
||||||
/* sign extend */
|
|
||||||
emit_instr(ctx, sll, MIPS_R_A1, src, 0);
|
|
||||||
src = MIPS_R_A1;
|
|
||||||
}
|
|
||||||
if (insn->imm >= S16_MIN && insn->imm <= S16_MAX) {
|
|
||||||
emit_instr(ctx, daddiu, MIPS_R_A1, src, insn->imm);
|
|
||||||
} else {
|
|
||||||
gen_imm_to_reg(insn, MIPS_R_AT, ctx);
|
|
||||||
emit_instr(ctx, daddu, MIPS_R_A1, MIPS_R_AT, src);
|
|
||||||
}
|
|
||||||
/* truncate to 32-bit int */
|
|
||||||
emit_instr(ctx, sll, MIPS_R_A1, MIPS_R_A1, 0);
|
|
||||||
emit_instr(ctx, daddiu, MIPS_R_A3, MIPS_R_SP, ctx->tmp_offset);
|
|
||||||
emit_instr(ctx, slt, MIPS_R_AT, MIPS_R_A1, MIPS_R_ZERO);
|
|
||||||
|
|
||||||
emit_const_to_reg(ctx, MIPS_R_T8, (u64)bpf_internal_load_pointer_neg_helper);
|
|
||||||
emit_const_to_reg(ctx, MIPS_R_T9, (u64)ool_skb_header_pointer);
|
|
||||||
emit_instr(ctx, addiu, MIPS_R_A2, MIPS_R_ZERO, size_to_len(insn));
|
|
||||||
emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_T8, MIPS_R_AT);
|
|
||||||
|
|
||||||
ld_skb_common:
|
|
||||||
emit_instr(ctx, jalr, MIPS_R_RA, MIPS_R_T9);
|
|
||||||
/* delay slot move */
|
|
||||||
emit_instr(ctx, daddu, MIPS_R_A0, MIPS_R_S0, MIPS_R_ZERO);
|
|
||||||
|
|
||||||
/* Check the error value */
|
|
||||||
b_off = b_imm(exit_idx, ctx);
|
|
||||||
if (is_bad_offset(b_off)) {
|
|
||||||
target = j_target(ctx, exit_idx);
|
|
||||||
if (target == (unsigned int)-1)
|
|
||||||
return -E2BIG;
|
|
||||||
|
|
||||||
if (!(ctx->offsets[this_idx] & OFFSETS_B_CONV)) {
|
|
||||||
ctx->offsets[this_idx] |= OFFSETS_B_CONV;
|
|
||||||
ctx->long_b_conversion = 1;
|
|
||||||
}
|
|
||||||
emit_instr(ctx, bne, MIPS_R_V0, MIPS_R_ZERO, 4 * 3);
|
|
||||||
emit_instr(ctx, nop);
|
|
||||||
emit_instr(ctx, j, target);
|
|
||||||
emit_instr(ctx, nop);
|
|
||||||
} else {
|
|
||||||
emit_instr(ctx, beq, MIPS_R_V0, MIPS_R_ZERO, b_off);
|
|
||||||
emit_instr(ctx, nop);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN
|
|
||||||
need_swap = false;
|
|
||||||
#else
|
|
||||||
need_swap = true;
|
|
||||||
#endif
|
|
||||||
dst = MIPS_R_V0;
|
|
||||||
switch (BPF_SIZE(insn->code)) {
|
|
||||||
case BPF_B:
|
|
||||||
emit_instr(ctx, lbu, dst, 0, MIPS_R_V0);
|
|
||||||
break;
|
|
||||||
case BPF_H:
|
|
||||||
emit_instr(ctx, lhu, dst, 0, MIPS_R_V0);
|
|
||||||
if (need_swap)
|
|
||||||
emit_instr(ctx, wsbh, dst, dst);
|
|
||||||
break;
|
|
||||||
case BPF_W:
|
|
||||||
emit_instr(ctx, lw, dst, 0, MIPS_R_V0);
|
|
||||||
if (need_swap) {
|
|
||||||
emit_instr(ctx, wsbh, dst, dst);
|
|
||||||
emit_instr(ctx, rotr, dst, dst, 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BPF_DW:
|
|
||||||
emit_instr(ctx, ld, dst, 0, MIPS_R_V0);
|
|
||||||
if (need_swap) {
|
|
||||||
emit_instr(ctx, dsbh, dst, dst);
|
|
||||||
emit_instr(ctx, dshd, dst, dst);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case BPF_ALU | BPF_END | BPF_FROM_BE:
|
case BPF_ALU | BPF_END | BPF_FROM_BE:
|
||||||
case BPF_ALU | BPF_END | BPF_FROM_LE:
|
case BPF_ALU | BPF_END | BPF_FROM_LE:
|
||||||
dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
|
dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
|
||||||
|
|
Loading…
Reference in a new issue