mips: bpf: implement jitting of BPF_ALU | BPF_ARSH | BPF_X
authorJiong Wang <jiong.wang@netronome.com>
Wed, 5 Dec 2018 18:52:30 +0000 (13:52 -0500)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 7 Dec 2018 21:30:48 +0000 (13:30 -0800)
Jitting of BPF_K is supported already, but not BPF_X. This patch complete
the support for the latter on both MIPS and microMIPS.

Cc: Paul Burton <paul.burton@mips.com>
Cc: linux-mips@vger.kernel.org
Acked-by: Paul Burton <paul.burton@mips.com>
Signed-off-by: Jiong Wang <jiong.wang@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/mips/include/asm/uasm.h
arch/mips/include/uapi/asm/inst.h
arch/mips/mm/uasm-micromips.c
arch/mips/mm/uasm-mips.c
arch/mips/mm/uasm.c
arch/mips/net/ebpf_jit.c

index 59dae37..b1990dd 100644 (file)
@@ -157,6 +157,7 @@ Ip_u2u1s3(_slti);
 Ip_u2u1s3(_sltiu);
 Ip_u3u1u2(_sltu);
 Ip_u2u1u3(_sra);
+Ip_u3u2u1(_srav);
 Ip_u2u1u3(_srl);
 Ip_u3u2u1(_srlv);
 Ip_u3u1u2(_subu);
index 273ef58..40fbb5d 100644 (file)
@@ -371,6 +371,7 @@ enum mm_32a_minor_op {
        mm_srl32_op = 0x040,
        mm_srlv32_op = 0x050,
        mm_sra_op = 0x080,
+       mm_srav_op = 0x090,
        mm_rotr_op = 0x0c0,
        mm_lwxs_op = 0x118,
        mm_addu32_op = 0x150,
index 24e5b0d..75ef904 100644 (file)
@@ -104,6 +104,7 @@ static const struct insn insn_table_MM[insn_invalid] = {
        [insn_sltiu]    = {M(mm_sltiu32_op, 0, 0, 0, 0, 0), RT | RS | SIMM},
        [insn_sltu]     = {M(mm_pool32a_op, 0, 0, 0, 0, mm_sltu_op), RT | RS | RD},
        [insn_sra]      = {M(mm_pool32a_op, 0, 0, 0, 0, mm_sra_op), RT | RS | RD},
+       [insn_srav]     = {M(mm_pool32a_op, 0, 0, 0, 0, mm_srav_op), RT | RS | RD},
        [insn_srl]      = {M(mm_pool32a_op, 0, 0, 0, 0, mm_srl32_op), RT | RS | RD},
        [insn_srlv]     = {M(mm_pool32a_op, 0, 0, 0, 0, mm_srlv32_op), RT | RS | RD},
        [insn_rotr]     = {M(mm_pool32a_op, 0, 0, 0, 0, mm_rotr_op), RT | RS | RD},
index 60ceb93..6abe40f 100644 (file)
@@ -171,6 +171,7 @@ static const struct insn insn_table[insn_invalid] = {
        [insn_sltiu]    = {M(sltiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM},
        [insn_sltu]     = {M(spec_op, 0, 0, 0, 0, sltu_op), RS | RT | RD},
        [insn_sra]      = {M(spec_op, 0, 0, 0, 0, sra_op),  RT | RD | RE},
+       [insn_srav]     = {M(spec_op, 0, 0, 0, 0, srav_op), RS | RT | RD},
        [insn_srl]      = {M(spec_op, 0, 0, 0, 0, srl_op),  RT | RD | RE},
        [insn_srlv]     = {M(spec_op, 0, 0, 0, 0, srlv_op),  RS | RT | RD},
        [insn_subu]     = {M(spec_op, 0, 0, 0, 0, subu_op),     RS | RT | RD},
index 57570c0..45b6264 100644 (file)
@@ -61,10 +61,10 @@ enum opcode {
        insn_mthc0, insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_nor,
        insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sb,
        insn_sc, insn_scd, insn_sd, insn_sh, insn_sll, insn_sllv,
-       insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra, insn_srl,
-       insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, insn_tlbp,
-       insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, insn_xor,
-       insn_xori, insn_yield,
+       insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra, insn_srav,
+       insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall,
+       insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh,
+       insn_xor, insn_xori, insn_yield,
        insn_invalid /* insn_invalid must be last */
 };
 
@@ -353,6 +353,7 @@ I_u2u1s3(_slti)
 I_u2u1s3(_sltiu)
 I_u3u1u2(_sltu)
 I_u2u1u3(_sra)
+I_u3u2u1(_srav)
 I_u2u1u3(_srl)
 I_u3u2u1(_srlv)
 I_u2u1u3(_rotr)
index aeb7b1b..b16710a 100644 (file)
@@ -854,6 +854,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
        case BPF_ALU | BPF_MOD | BPF_X: /* ALU_REG */
        case BPF_ALU | BPF_LSH | BPF_X: /* ALU_REG */
        case BPF_ALU | BPF_RSH | BPF_X: /* ALU_REG */
+       case BPF_ALU | BPF_ARSH | BPF_X: /* ALU_REG */
                src = ebpf_to_mips_reg(ctx, insn, src_reg_no_fp);
                dst = ebpf_to_mips_reg(ctx, insn, dst_reg);
                if (src < 0 || dst < 0)
@@ -913,6 +914,9 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
                case BPF_RSH:
                        emit_instr(ctx, srlv, dst, dst, src);
                        break;
+               case BPF_ARSH:
+                       emit_instr(ctx, srav, dst, dst, src);
+                       break;
                default:
                        pr_err("ALU_REG NOT HANDLED\n");
                        return -EINVAL;