| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/31 01:33 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"BPF_JIT"
],
"FocusSymbols": [
"bpf_int_jit_compile",
"build_insn",
"jit_smod64",
"emit_alu_r"
],
"Reasoning": "The patch adds support for signed division and modulo operations in the MIPS BPF JIT compiler. It modifies the MIPS micro-assembler to support signed div/mod instructions and updates the BPF JIT compiler to use them when translating BPF_DIV and BPF_MOD instructions with the signed flag. This is a functional change to reachable core kernel logic (BPF JIT) and should be fuzzed.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/31 01:33 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 339ed4ef30e49dd478d034979131cf82e62cd266\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Fri Jul 31 01:33:09 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h\nindex b43bfd4452521..9d3edb59efc09 100644\n--- a/arch/mips/include/asm/uasm.h\n+++ b/arch/mips/include/asm/uasm.h\n@@ -85,15 +85,20 @@ Ip_u1u2(_ctc1);\n Ip_u2u1(_ctcmsa);\n Ip_u2u1s3(_daddiu);\n Ip_u3u1u2(_daddu);\n+Ip_u1u2(_ddiv);\n+Ip_u3u1u2(_ddiv_r6);\n Ip_u1u2(_ddivu);\n Ip_u3u1u2(_ddivu_r6);\n Ip_u1(_di);\n Ip_u2u1msbu3(_dins);\n Ip_u2u1msbu3(_dinsm);\n Ip_u2u1msbu3(_dinsu);\n+Ip_u1u2(_div);\n+Ip_u3u1u2(_div_r6);\n Ip_u1u2(_divu);\n Ip_u3u1u2(_divu_r6);\n Ip_u1u2u3(_dmfc0);\n+Ip_u3u1u2(_dmod);\n Ip_u3u1u2(_dmodu);\n Ip_u1u2u3(_dmtc0);\n Ip_u1u2(_dmultu);\n@@ -135,6 +140,7 @@ Ip_u1u2u3(_mfc0);\n Ip_u1u2u3(_mfhc0);\n Ip_u1(_mfhi);\n Ip_u1(_mflo);\n+Ip_u3u1u2(_mod);\n Ip_u3u1u2(_modu);\n Ip_u3u1u2(_movn);\n Ip_u3u1u2(_movz);\ndiff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c\nindex e15c6700cd088..ef1a2b0400700 100644\n--- a/arch/mips/mm/uasm-mips.c\n+++ b/arch/mips/mm/uasm-mips.c\n@@ -75,6 +75,9 @@ static const struct insn insn_table[insn_invalid] = {\n \t[insn_ctcmsa]\t= {M(msa_op, 0, msa_ctc_op, 0, 0, msa_elm_op), RD | RE},\n \t[insn_daddiu]\t= {M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM},\n \t[insn_daddu]\t= {M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD},\n+\t[insn_ddiv]\t= {M(spec_op, 0, 0, 0, 0, ddiv_op), RS | RT},\n+\t[insn_ddiv_r6]\t= {M(spec_op, 0, 0, 0, ddiv_ddiv6_op, ddiv_op),\n+\t\t\t\tRS | RT | RD},\n \t[insn_ddivu]\t= {M(spec_op, 0, 0, 0, 0, ddivu_op), RS | RT},\n \t[insn_ddivu_r6]\t= {M(spec_op, 0, 0, 0, ddivu_ddivu6_op, ddivu_op),\n \t\t\t\tRS | RT | RD},\n@@ -82,10 +85,15 @@ static const struct insn insn_table[insn_invalid] = {\n \t[insn_dins]\t= {M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE},\n \t[insn_dinsm]\t= {M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE},\n \t[insn_dinsu]\t= {M(spec3_op, 0, 0, 0, 0, dinsu_op), RS | RT | RD | RE},\n+\t[insn_div]\t= {M(spec_op, 0, 0, 0, 0, div_op), RS | RT},\n+\t[insn_div_r6]\t= {M(spec_op, 0, 0, 0, div_div6_op, div_op),\n+\t\t\t\tRS | RT | RD},\n \t[insn_divu]\t= {M(spec_op, 0, 0, 0, 0, divu_op), RS | RT},\n \t[insn_divu_r6]\t= {M(spec_op, 0, 0, 0, divu_divu6_op, divu_op),\n \t\t\t\tRS | RT | RD},\n \t[insn_dmfc0]\t= {M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},\n+\t[insn_dmod]\t= {M(spec_op, 0, 0, 0, ddiv_dmod_op, ddiv_op),\n+\t\t\t\tRS | RT | RD},\n \t[insn_dmodu]\t= {M(spec_op, 0, 0, 0, ddivu_dmodu_op, ddivu_op),\n \t\t\t\tRS | RT | RD},\n \t[insn_dmtc0]\t= {M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},\n@@ -140,6 +148,8 @@ static const struct insn insn_table[insn_invalid] = {\n \t[insn_mfhc0]\t= {M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET},\n \t[insn_mfhi]\t= {M(spec_op, 0, 0, 0, 0, mfhi_op), RD},\n \t[insn_mflo]\t= {M(spec_op, 0, 0, 0, 0, mflo_op), RD},\n+\t[insn_mod]\t= {M(spec_op, 0, 0, 0, div_mod_op, div_op),\n+\t\t\t\tRS | RT | RD},\n \t[insn_modu]\t= {M(spec_op, 0, 0, 0, divu_modu_op, divu_op),\n \t\t\t\tRS | RT | RD},\n \t[insn_movn]\t= {M(spec_op, 0, 0, 0, 0, movn_op), RS | RT | RD},\ndiff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c\nindex 125140979d62c..06d722665451f 100644\n--- a/arch/mips/mm/uasm.c\n+++ b/arch/mips/mm/uasm.c\n@@ -49,18 +49,20 @@ enum opcode {\n \tinsn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1,\n \tinsn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bgtz, insn_blez,\n \tinsn_bltz, insn_bltzl, insn_bne, insn_break, insn_cache, insn_cfc1,\n-\tinsn_cfcmsa, insn_ctc1, insn_ctcmsa, insn_daddiu, insn_daddu, insn_ddivu,\n-\tinsn_ddivu_r6, insn_di, insn_dins, insn_dinsm, insn_dinsu, insn_divu,\n-\tinsn_divu_r6, insn_dmfc0, insn_dmodu, insn_dmtc0, insn_dmultu,\n+\tinsn_cfcmsa, insn_ctc1, insn_ctcmsa, insn_daddiu, insn_daddu, insn_ddiv,\n+\tinsn_ddiv_r6, insn_ddivu, insn_ddivu_r6, insn_di, insn_dins, insn_dinsm,\n+\tinsn_dinsu, insn_div, insn_div_r6, insn_divu, insn_divu_r6, insn_dmfc0,\n+\tinsn_dmod, insn_dmodu, insn_dmtc0, insn_dmultu,\n \tinsn_dmulu, insn_drotr, insn_drotr32, insn_dsbh, insn_dshd, insn_dsll,\n \tinsn_dsll32, insn_dsllv, insn_dsra, insn_dsra32, insn_dsrav, insn_dsrl,\n \tinsn_dsrl32, insn_dsrlv, insn_dsubu, insn_eret, insn_ext, insn_ins,\n \tinsn_j, insn_jal, insn_jalr, insn_jr, insn_lb, insn_lbu, insn_ld,\n \tinsn_lddir, insn_ldpte, insn_ldx, insn_lh, insn_lhu, insn_ll, insn_lld,\n \tinsn_lui, insn_lw, insn_lwu, insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi,\n-\tinsn_mflo, insn_modu, insn_movn, insn_movz, insn_mtc0, insn_mthc0,\n-\tinsn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu, insn_muhu, insn_nor,\n-\tinsn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sb, insn_sc,\n+\tinsn_mflo, insn_mod, insn_modu, insn_movn, insn_movz, insn_mtc0,\n+\tinsn_mthc0, insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu,\n+\tinsn_muhu, insn_nor, insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr,\n+\tinsn_sb, insn_sc,\n \tinsn_scd, insn_seleqz, insn_selnez, insn_sd, insn_sh, insn_sll,\n \tinsn_sllv, insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra,\n \tinsn_srav, insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync,\n@@ -287,9 +289,12 @@ I_u1u2(_cfc1)\n I_u2u1(_cfcmsa)\n I_u1u2(_ctc1)\n I_u2u1(_ctcmsa)\n+I_u1u2(_ddiv)\n+I_u3u1u2(_ddiv_r6)\n I_u1u2(_ddivu)\n I_u3u1u2(_ddivu_r6)\n I_u1u2u3(_dmfc0)\n+I_u3u1u2(_dmod)\n I_u3u1u2(_dmodu)\n I_u1u2u3(_dmtc0)\n I_u1u2(_dmultu)\n@@ -297,6 +302,8 @@ I_u3u1u2(_dmulu)\n I_u2u1s3(_daddiu)\n I_u3u1u2(_daddu)\n I_u1(_di);\n+I_u1u2(_div)\n+I_u3u1u2(_div_r6)\n I_u1u2(_divu)\n I_u3u1u2(_divu_r6)\n I_u2u1(_dsbh);\n@@ -332,6 +339,7 @@ I_u2s3u1(_lw)\n I_u2s3u1(_lwu)\n I_u1u2u3(_mfc0)\n I_u1u2u3(_mfhc0)\n+I_u3u1u2(_mod)\n I_u3u1u2(_modu)\n I_u3u1u2(_movn)\n I_u3u1u2(_movz)\ndiff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c\nindex 6ee4abe6a1f70..a67885d28942f 100644\n--- a/arch/mips/net/bpf_jit_comp.c\n+++ b/arch/mips/net/bpf_jit_comp.c\n@@ -208,7 +208,7 @@ void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src)\n }\n \n /* Validate ALU immediate range */\n-bool valid_alu_i(u8 op, s32 imm)\n+bool valid_alu_i(u8 op, s32 imm, bool is_signed)\n {\n \tswitch (BPF_OP(op)) {\n \tcase BPF_NEG:\n@@ -237,6 +237,9 @@ bool valid_alu_i(u8 op, s32 imm)\n \t\treturn imm == 0 || (imm \u003e 0 \u0026\u0026 is_power_of_2(imm));\n \tcase BPF_DIV:\n \tcase BPF_MOD:\n+\t\t/* Do not use unsigned shift/mask rewrites for signed div/mod. */\n+\t\tif (is_signed)\n+\t\t\treturn false;\n \t\t/* imm must be an 17-bit power of two */\n \t\treturn (u32)imm \u003c= 0x10000 \u0026\u0026 is_power_of_2((u32)imm);\n \t}\n@@ -338,8 +341,40 @@ void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op)\n \tclobber_reg(ctx, dst);\n }\n \n+static void emit_div(struct jit_context *ctx, u8 dst, u8 src, bool is_signed)\n+{\n+\tif (cpu_has_mips32r6) {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, div_r6, dst, dst, src);\n+\t\telse\n+\t\t\temit(ctx, divu_r6, dst, dst, src);\n+\t} else {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, div, dst, src);\n+\t\telse\n+\t\t\temit(ctx, divu, dst, src);\n+\t\temit(ctx, mflo, dst);\n+\t}\n+}\n+\n+static void emit_mod(struct jit_context *ctx, u8 dst, u8 src, bool is_signed)\n+{\n+\tif (cpu_has_mips32r6) {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, mod, dst, dst, src);\n+\t\telse\n+\t\t\temit(ctx, modu, dst, dst, src);\n+\t} else {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, div, dst, src);\n+\t\telse\n+\t\t\temit(ctx, divu, dst, src);\n+\t\temit(ctx, mfhi, dst);\n+\t}\n+}\n+\n /* ALU register operation (32-bit) */\n-void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op)\n+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op, bool is_signed)\n {\n \tswitch (BPF_OP(op)) {\n \t/* dst = dst \u0026 src */\n@@ -385,21 +420,11 @@ void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op)\n \t\tbreak;\n \t/* dst = dst / src */\n \tcase BPF_DIV:\n-\t\tif (cpu_has_mips32r6) {\n-\t\t\temit(ctx, divu_r6, dst, dst, src);\n-\t\t} else {\n-\t\t\temit(ctx, divu, dst, src);\n-\t\t\temit(ctx, mflo, dst);\n-\t\t}\n+\t\temit_div(ctx, dst, src, is_signed);\n \t\tbreak;\n \t/* dst = dst % src */\n \tcase BPF_MOD:\n-\t\tif (cpu_has_mips32r6) {\n-\t\t\temit(ctx, modu, dst, dst, src);\n-\t\t} else {\n-\t\t\temit(ctx, divu, dst, src);\n-\t\t\temit(ctx, mfhi, dst);\n-\t\t}\n+\t\temit_mod(ctx, dst, src, is_signed);\n \t\tbreak;\n \t}\n \tclobber_reg(ctx, dst);\ndiff --git a/arch/mips/net/bpf_jit_comp.h b/arch/mips/net/bpf_jit_comp.h\nindex a37fe20818eb9..39266daa6da6d 100644\n--- a/arch/mips/net/bpf_jit_comp.h\n+++ b/arch/mips/net/bpf_jit_comp.h\n@@ -163,7 +163,7 @@ void emit_mov_i(struct jit_context *ctx, u8 dst, s32 imm);\n void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src);\n \n /* Validate ALU/ALU64 immediate range */\n-bool valid_alu_i(u8 op, s32 imm);\n+bool valid_alu_i(u8 op, s32 imm, bool is_signed);\n \n /* Rewrite ALU/ALU64 immediate operation */\n bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val);\n@@ -172,7 +172,8 @@ bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val);\n void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op);\n \n /* ALU register operation (32-bit) */\n-void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op);\n+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op,\n+\t\tbool is_signed);\n \n /* Atomic read-modify-write (32-bit) */\n void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code);\ndiff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c\nindex 40a878b672f5d..c8d45a5d54d83 100644\n--- a/arch/mips/net/bpf_jit_comp32.c\n+++ b/arch/mips/net/bpf_jit_comp32.c\n@@ -512,7 +512,7 @@ static void emit_mul_r64(struct jit_context *ctx,\n \tclobber_reg64(ctx, dst);\n }\n \n-/* Helper function for 64-bit modulo */\n+/* Helper function for unsigned 64-bit modulo */\n static u64 jit_mod64(u64 a, u64 b)\n {\n \tu64 rem;\n@@ -521,9 +521,17 @@ static u64 jit_mod64(u64 a, u64 b)\n \treturn rem;\n }\n \n+/* Helper function for signed 64-bit modulo */\n+static s64 jit_smod64(s64 a, s64 b)\n+{\n+\tu64 quot = div64_s64(a, b);\n+\n+\treturn a - quot * b;\n+}\n+\n /* ALU div/mod register (64-bit) */\n-static void emit_divmod_r64(struct jit_context *ctx,\n-\t\t\t const u8 dst[], const u8 src[], u8 op)\n+static void emit_divmod_r64(struct jit_context *ctx, const u8 dst[],\n+\t\t\t const u8 src[], u8 op, bool is_signed)\n {\n \tconst u8 *r0 = bpf2mips32[BPF_REG_0]; /* Mapped to v0-v1 */\n \tconst u8 *r1 = bpf2mips32[BPF_REG_1]; /* Mapped to a0-a1 */\n@@ -546,11 +554,11 @@ static void emit_divmod_r64(struct jit_context *ctx,\n \tswitch (BPF_OP(op)) {\n \t/* dst = dst / src */\n \tcase BPF_DIV:\n-\t\taddr = (u32)\u0026div64_u64;\n+\t\taddr = is_signed ? (u32)\u0026div64_s64 : (u32)\u0026div64_u64;\n \t\tbreak;\n \t/* dst = dst % src */\n \tcase BPF_MOD:\n-\t\taddr = (u32)\u0026jit_mod64;\n+\t\taddr = is_signed ? (u32)\u0026jit_smod64 : (u32)\u0026jit_mod64;\n \t\tbreak;\n \t}\n \temit_mov_i(ctx, MIPS_R_T9, addr);\n@@ -1469,6 +1477,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tu8 code = insn-\u003ecode;\n \ts16 off = insn-\u003eoff;\n \ts32 imm = insn-\u003eimm;\n+\tbool is_signed = off == 1;\n \ts32 val, rel;\n \tu8 alu, jmp;\n \n@@ -1516,9 +1525,10 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU | BPF_MUL | BPF_K:\n \tcase BPF_ALU | BPF_DIV | BPF_K:\n \tcase BPF_ALU | BPF_MOD | BPF_K:\n-\t\tif (!valid_alu_i(BPF_OP(code), imm)) {\n+\t\tif (!valid_alu_i(BPF_OP(code), imm, is_signed)) {\n \t\t\temit_mov_i(ctx, MIPS_R_T6, imm);\n-\t\t\temit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code));\n+\t\t\temit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code),\n+\t\t\t\t is_signed);\n \t\t} else if (rewrite_alu_i(BPF_OP(code), imm, \u0026alu, \u0026val)) {\n \t\t\temit_alu_i(ctx, lo(dst), val, alu);\n \t\t}\n@@ -1546,7 +1556,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU | BPF_MUL | BPF_X:\n \tcase BPF_ALU | BPF_DIV | BPF_X:\n \tcase BPF_ALU | BPF_MOD | BPF_X:\n-\t\temit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code));\n+\t\temit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code), is_signed);\n \t\temit_zext_ver(ctx, dst);\n \t\tbreak;\n \t/* dst = imm (64-bit) */\n@@ -1599,7 +1609,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \t\t * and then do the operation on this register.\n \t\t */\n \t\temit_mov_se_i64(ctx, tmp, imm);\n-\t\temit_divmod_r64(ctx, dst, tmp, BPF_OP(code));\n+\t\temit_divmod_r64(ctx, dst, tmp, BPF_OP(code), is_signed);\n \t\tbreak;\n \t/* dst = dst \u0026 src (64-bit) */\n \t/* dst = dst | src (64-bit) */\n@@ -1629,7 +1639,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \t/* dst = dst % src (64-bit) */\n \tcase BPF_ALU64 | BPF_DIV | BPF_X:\n \tcase BPF_ALU64 | BPF_MOD | BPF_X:\n-\t\temit_divmod_r64(ctx, dst, src, BPF_OP(code));\n+\t\temit_divmod_r64(ctx, dst, src, BPF_OP(code), is_signed);\n \t\tbreak;\n \t/* dst = htole(dst) */\n \t/* dst = htobe(dst) */\ndiff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c\nindex fa7e9aa37f498..ca2741f14483d 100644\n--- a/arch/mips/net/bpf_jit_comp64.c\n+++ b/arch/mips/net/bpf_jit_comp64.c\n@@ -197,8 +197,43 @@ static void emit_alu_i64(struct jit_context *ctx, u8 dst, s32 imm, u8 op)\n \tclobber_reg(ctx, dst);\n }\n \n+static void emit_div64(struct jit_context *ctx, u8 dst, u8 src,\n+\t\t bool is_signed)\n+{\n+\tif (cpu_has_mips64r6) {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, ddiv_r6, dst, dst, src);\n+\t\telse\n+\t\t\temit(ctx, ddivu_r6, dst, dst, src);\n+\t} else {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, ddiv, dst, src);\n+\t\telse\n+\t\t\temit(ctx, ddivu, dst, src);\n+\t\temit(ctx, mflo, dst);\n+\t}\n+}\n+\n+static void emit_mod64(struct jit_context *ctx, u8 dst, u8 src,\n+\t\t bool is_signed)\n+{\n+\tif (cpu_has_mips64r6) {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, dmod, dst, dst, src);\n+\t\telse\n+\t\t\temit(ctx, dmodu, dst, dst, src);\n+\t} else {\n+\t\tif (is_signed)\n+\t\t\temit(ctx, ddiv, dst, src);\n+\t\telse\n+\t\t\temit(ctx, ddivu, dst, src);\n+\t\temit(ctx, mfhi, dst);\n+\t}\n+}\n+\n /* ALU register operation (64-bit) */\n-static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)\n+static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op,\n+\t\t\t bool is_signed)\n {\n \tswitch (BPF_OP(op)) {\n \t/* dst = dst \u003c\u003c src */\n@@ -235,25 +270,15 @@ static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)\n \t\tbreak;\n \t/* dst = dst / src */\n \tcase BPF_DIV:\n-\t\tif (cpu_has_mips64r6) {\n-\t\t\temit(ctx, ddivu_r6, dst, dst, src);\n-\t\t} else {\n-\t\t\temit(ctx, ddivu, dst, src);\n-\t\t\temit(ctx, mflo, dst);\n-\t\t}\n+\t\temit_div64(ctx, dst, src, is_signed);\n \t\tbreak;\n \t/* dst = dst % src */\n \tcase BPF_MOD:\n-\t\tif (cpu_has_mips64r6) {\n-\t\t\temit(ctx, dmodu, dst, dst, src);\n-\t\t} else {\n-\t\t\temit(ctx, ddivu, dst, src);\n-\t\t\temit(ctx, mfhi, dst);\n-\t\t}\n+\t\temit_mod64(ctx, dst, src, is_signed);\n \t\tbreak;\n \tdefault:\n \t\t/* Width-generic operations */\n-\t\temit_alu_r(ctx, dst, src, op);\n+\t\temit_alu_r(ctx, dst, src, op, false);\n \t}\n \tclobber_reg(ctx, dst);\n }\n@@ -640,6 +665,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tu8 code = insn-\u003ecode;\n \ts16 off = insn-\u003eoff;\n \ts32 imm = insn-\u003eimm;\n+\tbool is_signed = off == 1;\n \ts32 val, rel;\n \tu8 alu, jmp;\n \n@@ -674,9 +700,9 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU | BPF_AND | BPF_K:\n \tcase BPF_ALU | BPF_XOR | BPF_K:\n \tcase BPF_ALU | BPF_LSH | BPF_K:\n-\t\tif (!valid_alu_i(BPF_OP(code), imm)) {\n+\t\tif (!valid_alu_i(BPF_OP(code), imm, false)) {\n \t\t\temit_mov_i(ctx, MIPS_R_T4, imm);\n-\t\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));\n+\t\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code), false);\n \t\t} else if (rewrite_alu_i(BPF_OP(code), imm, \u0026alu, \u0026val)) {\n \t\t\temit_alu_i(ctx, dst, val, alu);\n \t\t}\n@@ -696,10 +722,11 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU | BPF_MUL | BPF_K:\n \tcase BPF_ALU | BPF_DIV | BPF_K:\n \tcase BPF_ALU | BPF_MOD | BPF_K:\n-\t\tif (!valid_alu_i(BPF_OP(code), imm)) {\n+\t\tif (!valid_alu_i(BPF_OP(code), imm, is_signed)) {\n \t\t\temit_sext(ctx, dst, dst);\n \t\t\temit_mov_i(ctx, MIPS_R_T4, imm);\n-\t\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));\n+\t\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code),\n+\t\t\t\t is_signed);\n \t\t} else if (rewrite_alu_i(BPF_OP(code), imm, \u0026alu, \u0026val)) {\n \t\t\temit_sext(ctx, dst, dst);\n \t\t\temit_alu_i(ctx, dst, val, alu);\n@@ -714,7 +741,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU | BPF_OR | BPF_X:\n \tcase BPF_ALU | BPF_XOR | BPF_X:\n \tcase BPF_ALU | BPF_LSH | BPF_X:\n-\t\temit_alu_r(ctx, dst, src, BPF_OP(code));\n+\t\temit_alu_r(ctx, dst, src, BPF_OP(code), false);\n \t\temit_zext_ver(ctx, dst);\n \t\tbreak;\n \t/* dst = dst \u003e\u003e src */\n@@ -733,7 +760,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU | BPF_MOD | BPF_X:\n \t\temit_sext(ctx, dst, dst);\n \t\temit_sext(ctx, MIPS_R_T4, src);\n-\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));\n+\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code), is_signed);\n \t\temit_zext_ver(ctx, dst);\n \t\tbreak;\n \t/* dst = imm (64-bit) */\n@@ -770,9 +797,10 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU64 | BPF_MUL | BPF_K:\n \tcase BPF_ALU64 | BPF_DIV | BPF_K:\n \tcase BPF_ALU64 | BPF_MOD | BPF_K:\n-\t\tif (!valid_alu_i(BPF_OP(code), imm)) {\n+\t\tif (!valid_alu_i(BPF_OP(code), imm, is_signed)) {\n \t\t\temit_mov_i(ctx, MIPS_R_T4, imm);\n-\t\t\temit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code));\n+\t\t\temit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code),\n+\t\t\t\t is_signed);\n \t\t} else if (rewrite_alu_i(BPF_OP(code), imm, \u0026alu, \u0026val)) {\n \t\t\temit_alu_i64(ctx, dst, val, alu);\n \t\t}\n@@ -799,7 +827,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n \tcase BPF_ALU64 | BPF_MUL | BPF_X:\n \tcase BPF_ALU64 | BPF_DIV | BPF_X:\n \tcase BPF_ALU64 | BPF_MOD | BPF_X:\n-\t\temit_alu_r64(ctx, dst, src, BPF_OP(code));\n+\t\temit_alu_r64(ctx, dst, src, BPF_OP(code), is_signed);\n \t\tbreak;\n \t/* dst = htole(dst) */\n \t/* dst = htobe(dst) */\n"
} |
| 2/1 | 2026/07/31 01:33 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"BPF_JIT"
],
"FocusSymbols": [
"bpf_int_jit_compile",
"build_insn",
"jit_smod64",
"emit_alu_r"
],
"Reasoning": "The patch adds support for signed division and modulo operations in the MIPS BPF JIT compiler. It modifies the MIPS micro-assembler to support signed div/mod instructions and updates the BPF JIT compiler to use them when translating BPF_DIV and BPF_MOD instructions with the signed flag. This is a functional change to reachable core kernel logic (BPF JIT) and should be fuzzed.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 339ed4ef30e49dd478d034979131cf82e62cd266
Author: syz-cluster <triage@syzkaller.com>
Date: Fri Jul 31 01:33:09 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index b43bfd4452521..9d3edb59efc09 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -85,15 +85,20 @@ Ip_u1u2(_ctc1);
Ip_u2u1(_ctcmsa);
Ip_u2u1s3(_daddiu);
Ip_u3u1u2(_daddu);
+Ip_u1u2(_ddiv);
+Ip_u3u1u2(_ddiv_r6);
Ip_u1u2(_ddivu);
Ip_u3u1u2(_ddivu_r6);
Ip_u1(_di);
Ip_u2u1msbu3(_dins);
Ip_u2u1msbu3(_dinsm);
Ip_u2u1msbu3(_dinsu);
+Ip_u1u2(_div);
+Ip_u3u1u2(_div_r6);
Ip_u1u2(_divu);
Ip_u3u1u2(_divu_r6);
Ip_u1u2u3(_dmfc0);
+Ip_u3u1u2(_dmod);
Ip_u3u1u2(_dmodu);
Ip_u1u2u3(_dmtc0);
Ip_u1u2(_dmultu);
@@ -135,6 +140,7 @@ Ip_u1u2u3(_mfc0);
Ip_u1u2u3(_mfhc0);
Ip_u1(_mfhi);
Ip_u1(_mflo);
+Ip_u3u1u2(_mod);
Ip_u3u1u2(_modu);
Ip_u3u1u2(_movn);
Ip_u3u1u2(_movz);
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c
index e15c6700cd088..ef1a2b0400700 100644
--- a/arch/mips/mm/uasm-mips.c
+++ b/arch/mips/mm/uasm-mips.c
@@ -75,6 +75,9 @@ static const struct insn insn_table[insn_invalid] = {
[insn_ctcmsa] = {M(msa_op, 0, msa_ctc_op, 0, 0, msa_elm_op), RD | RE},
[insn_daddiu] = {M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM},
[insn_daddu] = {M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD},
+ [insn_ddiv] = {M(spec_op, 0, 0, 0, 0, ddiv_op), RS | RT},
+ [insn_ddiv_r6] = {M(spec_op, 0, 0, 0, ddiv_ddiv6_op, ddiv_op),
+ RS | RT | RD},
[insn_ddivu] = {M(spec_op, 0, 0, 0, 0, ddivu_op), RS | RT},
[insn_ddivu_r6] = {M(spec_op, 0, 0, 0, ddivu_ddivu6_op, ddivu_op),
RS | RT | RD},
@@ -82,10 +85,15 @@ static const struct insn insn_table[insn_invalid] = {
[insn_dins] = {M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE},
[insn_dinsm] = {M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE},
[insn_dinsu] = {M(spec3_op, 0, 0, 0, 0, dinsu_op), RS | RT | RD | RE},
+ [insn_div] = {M(spec_op, 0, 0, 0, 0, div_op), RS | RT},
+ [insn_div_r6] = {M(spec_op, 0, 0, 0, div_div6_op, div_op),
+ RS | RT | RD},
[insn_divu] = {M(spec_op, 0, 0, 0, 0, divu_op), RS | RT},
[insn_divu_r6] = {M(spec_op, 0, 0, 0, divu_divu6_op, divu_op),
RS | RT | RD},
[insn_dmfc0] = {M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
+ [insn_dmod] = {M(spec_op, 0, 0, 0, ddiv_dmod_op, ddiv_op),
+ RS | RT | RD},
[insn_dmodu] = {M(spec_op, 0, 0, 0, ddivu_dmodu_op, ddivu_op),
RS | RT | RD},
[insn_dmtc0] = {M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
@@ -140,6 +148,8 @@ static const struct insn insn_table[insn_invalid] = {
[insn_mfhc0] = {M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET},
[insn_mfhi] = {M(spec_op, 0, 0, 0, 0, mfhi_op), RD},
[insn_mflo] = {M(spec_op, 0, 0, 0, 0, mflo_op), RD},
+ [insn_mod] = {M(spec_op, 0, 0, 0, div_mod_op, div_op),
+ RS | RT | RD},
[insn_modu] = {M(spec_op, 0, 0, 0, divu_modu_op, divu_op),
RS | RT | RD},
[insn_movn] = {M(spec_op, 0, 0, 0, 0, movn_op), RS | RT | RD},
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 125140979d62c..06d722665451f 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -49,18 +49,20 @@ enum opcode {
insn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1,
insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bgtz, insn_blez,
insn_bltz, insn_bltzl, insn_bne, insn_break, insn_cache, insn_cfc1,
- insn_cfcmsa, insn_ctc1, insn_ctcmsa, insn_daddiu, insn_daddu, insn_ddivu,
- insn_ddivu_r6, insn_di, insn_dins, insn_dinsm, insn_dinsu, insn_divu,
- insn_divu_r6, insn_dmfc0, insn_dmodu, insn_dmtc0, insn_dmultu,
+ insn_cfcmsa, insn_ctc1, insn_ctcmsa, insn_daddiu, insn_daddu, insn_ddiv,
+ insn_ddiv_r6, insn_ddivu, insn_ddivu_r6, insn_di, insn_dins, insn_dinsm,
+ insn_dinsu, insn_div, insn_div_r6, insn_divu, insn_divu_r6, insn_dmfc0,
+ insn_dmod, insn_dmodu, insn_dmtc0, insn_dmultu,
insn_dmulu, insn_drotr, insn_drotr32, insn_dsbh, insn_dshd, insn_dsll,
insn_dsll32, insn_dsllv, insn_dsra, insn_dsra32, insn_dsrav, insn_dsrl,
insn_dsrl32, insn_dsrlv, insn_dsubu, insn_eret, insn_ext, insn_ins,
insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, insn_lbu, insn_ld,
insn_lddir, insn_ldpte, insn_ldx, insn_lh, insn_lhu, insn_ll, insn_lld,
insn_lui, insn_lw, insn_lwu, insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi,
- insn_mflo, insn_modu, insn_movn, insn_movz, insn_mtc0, insn_mthc0,
- insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu, insn_muhu, insn_nor,
- insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sb, insn_sc,
+ insn_mflo, insn_mod, insn_modu, insn_movn, insn_movz, insn_mtc0,
+ insn_mthc0, insn_mthi, insn_mtlo, insn_mul, insn_multu, insn_mulu,
+ insn_muhu, insn_nor, insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr,
+ insn_sb, insn_sc,
insn_scd, insn_seleqz, insn_selnez, insn_sd, insn_sh, insn_sll,
insn_sllv, insn_slt, insn_slti, insn_sltiu, insn_sltu, insn_sra,
insn_srav, insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync,
@@ -287,9 +289,12 @@ I_u1u2(_cfc1)
I_u2u1(_cfcmsa)
I_u1u2(_ctc1)
I_u2u1(_ctcmsa)
+I_u1u2(_ddiv)
+I_u3u1u2(_ddiv_r6)
I_u1u2(_ddivu)
I_u3u1u2(_ddivu_r6)
I_u1u2u3(_dmfc0)
+I_u3u1u2(_dmod)
I_u3u1u2(_dmodu)
I_u1u2u3(_dmtc0)
I_u1u2(_dmultu)
@@ -297,6 +302,8 @@ I_u3u1u2(_dmulu)
I_u2u1s3(_daddiu)
I_u3u1u2(_daddu)
I_u1(_di);
+I_u1u2(_div)
+I_u3u1u2(_div_r6)
I_u1u2(_divu)
I_u3u1u2(_divu_r6)
I_u2u1(_dsbh);
@@ -332,6 +339,7 @@ I_u2s3u1(_lw)
I_u2s3u1(_lwu)
I_u1u2u3(_mfc0)
I_u1u2u3(_mfhc0)
+I_u3u1u2(_mod)
I_u3u1u2(_modu)
I_u3u1u2(_movn)
I_u3u1u2(_movz)
diff --git a/arch/mips/net/bpf_jit_comp.c b/arch/mips/net/bpf_jit_comp.c
index 6ee4abe6a1f70..a67885d28942f 100644
--- a/arch/mips/net/bpf_jit_comp.c
+++ b/arch/mips/net/bpf_jit_comp.c
@@ -208,7 +208,7 @@ void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src)
}
/* Validate ALU immediate range */
-bool valid_alu_i(u8 op, s32 imm)
+bool valid_alu_i(u8 op, s32 imm, bool is_signed)
{
switch (BPF_OP(op)) {
case BPF_NEG:
@@ -237,6 +237,9 @@ bool valid_alu_i(u8 op, s32 imm)
return imm == 0 || (imm > 0 && is_power_of_2(imm));
case BPF_DIV:
case BPF_MOD:
+ /* Do not use unsigned shift/mask rewrites for signed div/mod. */
+ if (is_signed)
+ return false;
/* imm must be an 17-bit power of two */
return (u32)imm <= 0x10000 && is_power_of_2((u32)imm);
}
@@ -338,8 +341,40 @@ void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op)
clobber_reg(ctx, dst);
}
+static void emit_div(struct jit_context *ctx, u8 dst, u8 src, bool is_signed)
+{
+ if (cpu_has_mips32r6) {
+ if (is_signed)
+ emit(ctx, div_r6, dst, dst, src);
+ else
+ emit(ctx, divu_r6, dst, dst, src);
+ } else {
+ if (is_signed)
+ emit(ctx, div, dst, src);
+ else
+ emit(ctx, divu, dst, src);
+ emit(ctx, mflo, dst);
+ }
+}
+
+static void emit_mod(struct jit_context *ctx, u8 dst, u8 src, bool is_signed)
+{
+ if (cpu_has_mips32r6) {
+ if (is_signed)
+ emit(ctx, mod, dst, dst, src);
+ else
+ emit(ctx, modu, dst, dst, src);
+ } else {
+ if (is_signed)
+ emit(ctx, div, dst, src);
+ else
+ emit(ctx, divu, dst, src);
+ emit(ctx, mfhi, dst);
+ }
+}
+
/* ALU register operation (32-bit) */
-void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op)
+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op, bool is_signed)
{
switch (BPF_OP(op)) {
/* dst = dst & src */
@@ -385,21 +420,11 @@ void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op)
break;
/* dst = dst / src */
case BPF_DIV:
- if (cpu_has_mips32r6) {
- emit(ctx, divu_r6, dst, dst, src);
- } else {
- emit(ctx, divu, dst, src);
- emit(ctx, mflo, dst);
- }
+ emit_div(ctx, dst, src, is_signed);
break;
/* dst = dst % src */
case BPF_MOD:
- if (cpu_has_mips32r6) {
- emit(ctx, modu, dst, dst, src);
- } else {
- emit(ctx, divu, dst, src);
- emit(ctx, mfhi, dst);
- }
+ emit_mod(ctx, dst, src, is_signed);
break;
}
clobber_reg(ctx, dst);
diff --git a/arch/mips/net/bpf_jit_comp.h b/arch/mips/net/bpf_jit_comp.h
index a37fe20818eb9..39266daa6da6d 100644
--- a/arch/mips/net/bpf_jit_comp.h
+++ b/arch/mips/net/bpf_jit_comp.h
@@ -163,7 +163,7 @@ void emit_mov_i(struct jit_context *ctx, u8 dst, s32 imm);
void emit_mov_r(struct jit_context *ctx, u8 dst, u8 src);
/* Validate ALU/ALU64 immediate range */
-bool valid_alu_i(u8 op, s32 imm);
+bool valid_alu_i(u8 op, s32 imm, bool is_signed);
/* Rewrite ALU/ALU64 immediate operation */
bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val);
@@ -172,7 +172,8 @@ bool rewrite_alu_i(u8 op, s32 imm, u8 *alu, s32 *val);
void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op);
/* ALU register operation (32-bit) */
-void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op);
+void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op,
+ bool is_signed);
/* Atomic read-modify-write (32-bit) */
void emit_atomic_r(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 code);
diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
index 40a878b672f5d..c8d45a5d54d83 100644
--- a/arch/mips/net/bpf_jit_comp32.c
+++ b/arch/mips/net/bpf_jit_comp32.c
@@ -512,7 +512,7 @@ static void emit_mul_r64(struct jit_context *ctx,
clobber_reg64(ctx, dst);
}
-/* Helper function for 64-bit modulo */
+/* Helper function for unsigned 64-bit modulo */
static u64 jit_mod64(u64 a, u64 b)
{
u64 rem;
@@ -521,9 +521,17 @@ static u64 jit_mod64(u64 a, u64 b)
return rem;
}
+/* Helper function for signed 64-bit modulo */
+static s64 jit_smod64(s64 a, s64 b)
+{
+ u64 quot = div64_s64(a, b);
+
+ return a - quot * b;
+}
+
/* ALU div/mod register (64-bit) */
-static void emit_divmod_r64(struct jit_context *ctx,
- const u8 dst[], const u8 src[], u8 op)
+static void emit_divmod_r64(struct jit_context *ctx, const u8 dst[],
+ const u8 src[], u8 op, bool is_signed)
{
const u8 *r0 = bpf2mips32[BPF_REG_0]; /* Mapped to v0-v1 */
const u8 *r1 = bpf2mips32[BPF_REG_1]; /* Mapped to a0-a1 */
@@ -546,11 +554,11 @@ static void emit_divmod_r64(struct jit_context *ctx,
switch (BPF_OP(op)) {
/* dst = dst / src */
case BPF_DIV:
- addr = (u32)&div64_u64;
+ addr = is_signed ? (u32)&div64_s64 : (u32)&div64_u64;
break;
/* dst = dst % src */
case BPF_MOD:
- addr = (u32)&jit_mod64;
+ addr = is_signed ? (u32)&jit_smod64 : (u32)&jit_mod64;
break;
}
emit_mov_i(ctx, MIPS_R_T9, addr);
@@ -1469,6 +1477,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
u8 code = insn->code;
s16 off = insn->off;
s32 imm = insn->imm;
+ bool is_signed = off == 1;
s32 val, rel;
u8 alu, jmp;
@@ -1516,9 +1525,10 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU | BPF_MUL | BPF_K:
case BPF_ALU | BPF_DIV | BPF_K:
case BPF_ALU | BPF_MOD | BPF_K:
- if (!valid_alu_i(BPF_OP(code), imm)) {
+ if (!valid_alu_i(BPF_OP(code), imm, is_signed)) {
emit_mov_i(ctx, MIPS_R_T6, imm);
- emit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code));
+ emit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code),
+ is_signed);
} else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
emit_alu_i(ctx, lo(dst), val, alu);
}
@@ -1546,7 +1556,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU | BPF_MUL | BPF_X:
case BPF_ALU | BPF_DIV | BPF_X:
case BPF_ALU | BPF_MOD | BPF_X:
- emit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code));
+ emit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code), is_signed);
emit_zext_ver(ctx, dst);
break;
/* dst = imm (64-bit) */
@@ -1599,7 +1609,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
* and then do the operation on this register.
*/
emit_mov_se_i64(ctx, tmp, imm);
- emit_divmod_r64(ctx, dst, tmp, BPF_OP(code));
+ emit_divmod_r64(ctx, dst, tmp, BPF_OP(code), is_signed);
break;
/* dst = dst & src (64-bit) */
/* dst = dst | src (64-bit) */
@@ -1629,7 +1639,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
/* dst = dst % src (64-bit) */
case BPF_ALU64 | BPF_DIV | BPF_X:
case BPF_ALU64 | BPF_MOD | BPF_X:
- emit_divmod_r64(ctx, dst, src, BPF_OP(code));
+ emit_divmod_r64(ctx, dst, src, BPF_OP(code), is_signed);
break;
/* dst = htole(dst) */
/* dst = htobe(dst) */
diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
index fa7e9aa37f498..ca2741f14483d 100644
--- a/arch/mips/net/bpf_jit_comp64.c
+++ b/arch/mips/net/bpf_jit_comp64.c
@@ -197,8 +197,43 @@ static void emit_alu_i64(struct jit_context *ctx, u8 dst, s32 imm, u8 op)
clobber_reg(ctx, dst);
}
+static void emit_div64(struct jit_context *ctx, u8 dst, u8 src,
+ bool is_signed)
+{
+ if (cpu_has_mips64r6) {
+ if (is_signed)
+ emit(ctx, ddiv_r6, dst, dst, src);
+ else
+ emit(ctx, ddivu_r6, dst, dst, src);
+ } else {
+ if (is_signed)
+ emit(ctx, ddiv, dst, src);
+ else
+ emit(ctx, ddivu, dst, src);
+ emit(ctx, mflo, dst);
+ }
+}
+
+static void emit_mod64(struct jit_context *ctx, u8 dst, u8 src,
+ bool is_signed)
+{
+ if (cpu_has_mips64r6) {
+ if (is_signed)
+ emit(ctx, dmod, dst, dst, src);
+ else
+ emit(ctx, dmodu, dst, dst, src);
+ } else {
+ if (is_signed)
+ emit(ctx, ddiv, dst, src);
+ else
+ emit(ctx, ddivu, dst, src);
+ emit(ctx, mfhi, dst);
+ }
+}
+
/* ALU register operation (64-bit) */
-static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)
+static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op,
+ bool is_signed)
{
switch (BPF_OP(op)) {
/* dst = dst << src */
@@ -235,25 +270,15 @@ static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op)
break;
/* dst = dst / src */
case BPF_DIV:
- if (cpu_has_mips64r6) {
- emit(ctx, ddivu_r6, dst, dst, src);
- } else {
- emit(ctx, ddivu, dst, src);
- emit(ctx, mflo, dst);
- }
+ emit_div64(ctx, dst, src, is_signed);
break;
/* dst = dst % src */
case BPF_MOD:
- if (cpu_has_mips64r6) {
- emit(ctx, dmodu, dst, dst, src);
- } else {
- emit(ctx, ddivu, dst, src);
- emit(ctx, mfhi, dst);
- }
+ emit_mod64(ctx, dst, src, is_signed);
break;
default:
/* Width-generic operations */
- emit_alu_r(ctx, dst, src, op);
+ emit_alu_r(ctx, dst, src, op, false);
}
clobber_reg(ctx, dst);
}
@@ -640,6 +665,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
u8 code = insn->code;
s16 off = insn->off;
s32 imm = insn->imm;
+ bool is_signed = off == 1;
s32 val, rel;
u8 alu, jmp;
@@ -674,9 +700,9 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU | BPF_AND | BPF_K:
case BPF_ALU | BPF_XOR | BPF_K:
case BPF_ALU | BPF_LSH | BPF_K:
- if (!valid_alu_i(BPF_OP(code), imm)) {
+ if (!valid_alu_i(BPF_OP(code), imm, false)) {
emit_mov_i(ctx, MIPS_R_T4, imm);
- emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));
+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code), false);
} else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
emit_alu_i(ctx, dst, val, alu);
}
@@ -696,10 +722,11 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU | BPF_MUL | BPF_K:
case BPF_ALU | BPF_DIV | BPF_K:
case BPF_ALU | BPF_MOD | BPF_K:
- if (!valid_alu_i(BPF_OP(code), imm)) {
+ if (!valid_alu_i(BPF_OP(code), imm, is_signed)) {
emit_sext(ctx, dst, dst);
emit_mov_i(ctx, MIPS_R_T4, imm);
- emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));
+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code),
+ is_signed);
} else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
emit_sext(ctx, dst, dst);
emit_alu_i(ctx, dst, val, alu);
@@ -714,7 +741,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU | BPF_OR | BPF_X:
case BPF_ALU | BPF_XOR | BPF_X:
case BPF_ALU | BPF_LSH | BPF_X:
- emit_alu_r(ctx, dst, src, BPF_OP(code));
+ emit_alu_r(ctx, dst, src, BPF_OP(code), false);
emit_zext_ver(ctx, dst);
break;
/* dst = dst >> src */
@@ -733,7 +760,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU | BPF_MOD | BPF_X:
emit_sext(ctx, dst, dst);
emit_sext(ctx, MIPS_R_T4, src);
- emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code));
+ emit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code), is_signed);
emit_zext_ver(ctx, dst);
break;
/* dst = imm (64-bit) */
@@ -770,9 +797,10 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU64 | BPF_MUL | BPF_K:
case BPF_ALU64 | BPF_DIV | BPF_K:
case BPF_ALU64 | BPF_MOD | BPF_K:
- if (!valid_alu_i(BPF_OP(code), imm)) {
+ if (!valid_alu_i(BPF_OP(code), imm, is_signed)) {
emit_mov_i(ctx, MIPS_R_T4, imm);
- emit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code));
+ emit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code),
+ is_signed);
} else if (rewrite_alu_i(BPF_OP(code), imm, &alu, &val)) {
emit_alu_i64(ctx, dst, val, alu);
}
@@ -799,7 +827,7 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_ALU64 | BPF_MUL | BPF_X:
case BPF_ALU64 | BPF_DIV | BPF_X:
case BPF_ALU64 | BPF_MOD | BPF_X:
- emit_alu_r64(ctx, dst, src, BPF_OP(code));
+ emit_alu_r64(ctx, dst, src, BPF_OP(code), is_signed);
break;
/* dst = htole(dst) */
/* dst = htobe(dst) */
|
| 3/2 | 2026/07/31 01:33 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11046 output: 35 thoughts: 528 Thoughts: **MIPS BPF JIT Compiler: Signed Division and Modulo Support - Worthy of Fuzzing** Okay, so I'm looking at a patch that introduces signed division and modulo support for the MIPS BPF JIT compiler. This is significant, it extends the BPF capabilities on MIPS, specifically by adding the necessary MIPS instructions (`ddiv`, `ddiv_r6`, `div`, `div_r6`, `dmod`, `mod`, etc.) within `arch/mips/include/asm/uasm.h`, `arch/mips/mm/uasm-mips.c`, and `arch/mips/mm/uasm.c`. The core of the change lies in leveraging these instructions when `is_signed` is true for `BPF_DIV` and `BPF_MOD` instructions in `arch/mips/net/bpf_jit_comp.c`, `arch/mips/net/bpf_jit_comp32.c`, and `arch/mips/net/bpf_jit_comp64.c`. Functionally, this means the MIPS BPF JIT compiler can now handle signed division and modulo operations. The crucial question is reachability, and yes, this is absolutely reachable. We can trigger this functionality via the `bpf()` syscall by loading a BPF program containing signed division/modulo instructions. Thinking about fuzzing, the immediate thought is MIPS support in general. And yes, syzkaller has MIPS support. We have `mips64le`, `mips32`, etc., covered! Now, the important part: this patch modifies reachable core kernel logic related to the MIPS architecture. The instructions tell me that. I need to verify that this code can be executed. Based on the prompt, this means I need to use my code search tools to confirm execution. So, this definitely means it's WorthFuzzing=true. Before I say that with confidence, I need to check the configurations. CONFIG_BPF_JIT is necessary as it provides the BPF JIT infrastructure. Also, CONFIG_MIPS is obviously needed because the changes are specific to the MIPS architecture. Now, let's dive into the code: I'll focus on the specific files and functions that have been modified. I need to search for instances of the functions: `emit_div`, `emit_mod`, `emit_alu_r`, `emit_divmod_r64`, `emit_div64`, `emit_mod64`, `emit_alu_r64`, and `build_insn`. I'll also double-check `arch/mips/net/bpf_jit_comp32.c` and `arch/mips/net/bpf_jit_comp64.c` to be certain. Given all of this, I'm confident that this is a change worth fuzzing. |
| 4/2 | 2026/07/31 01:33 | tool | grepper |
0mArgs:{
"Expression": "bpf_int_jit_compile",
"PathPrefix": "arch/mips/net/"
}Results: {
"Output": "arch/mips/net/bpf_jit_comp.c=932=bool bpf_jit_needs_zext(void)\n--\narch/mips/net/bpf_jit_comp.c-936-\narch/mips/net/bpf_jit_comp.c:937:struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\narch/mips/net/bpf_jit_comp.c-938-{\n"
} |
| 5/2 | 2026/07/31 01:33 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 12389 output: 31 thoughts: 157 Thoughts: **My Focus: MIPS BPF JIT Compilation** Okay, so I need to zero in on a specific area within the MIPS BPF JIT compiler. My primary targets are the `build_insn` functions, specifically within `arch/mips/net/bpf_jit_comp32.c` and `arch/mips/net/bpf_jit_comp64.c`. That's where the core instruction building logic resides, naturally. Beyond `build_insn`, I'll need to understand the division and modulo implementations. The functions to examine will be `emit_div`, `emit_mod`, `emit_div64`, `emit_mod64`, `emit_divmod_r64` and `jit_smod64`. Getting these functions working correctly is paramount for performance and correctness. Now, a quick sanity check before I dive deeper. I'm going to quickly cross-reference `arch/mips/net/bpf_jit_comp32.c` and `arch/mips/net/bpf_jit_comp64.c` to see if `build_insn` is declared static. Knowing that will impact the way I think about its scope and potential for modification. |
| 6/2 | 2026/07/31 01:33 | tool | grepper |
0mArgs:{
"Expression": "build_insn",
"PathPrefix": "arch/mips/net/"
}Results: {
"Output": "arch/mips/net/bpf_jit_comp.c=875=static int build_body(struct jit_context *ctx)\n--\narch/mips/net/bpf_jit_comp.c-895-\narch/mips/net/bpf_jit_comp.c:896:\t\tret = build_insn(insn, ctx);\narch/mips/net/bpf_jit_comp.c-897-\t\tif (ret \u003c 0)\n--\narch/mips/net/bpf_jit_comp.h=223=void build_epilogue(struct jit_context *ctx, int dest_reg);\n--\narch/mips/net/bpf_jit_comp.h-233- */\narch/mips/net/bpf_jit_comp.h:234:int build_insn(const struct bpf_insn *insn, struct jit_context *ctx);\narch/mips/net/bpf_jit_comp.h-235-\n--\narch/mips/net/bpf_jit_comp32.c=1452=void build_epilogue(struct jit_context *ctx, int dest_reg)\n--\narch/mips/net/bpf_jit_comp32.c-1470-/* Build one eBPF instruction */\narch/mips/net/bpf_jit_comp32.c:1471:int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\narch/mips/net/bpf_jit_comp32.c-1472-{\n--\narch/mips/net/bpf_jit_comp64.c=644=void build_epilogue(struct jit_context *ctx, int dest_reg)\n--\narch/mips/net/bpf_jit_comp64.c-659-/* Build one eBPF instruction */\narch/mips/net/bpf_jit_comp64.c:660:int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\narch/mips/net/bpf_jit_comp64.c-661-{\n"
} |
| 7/2 | 2026/07/31 01:33 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13409 output: 32 thoughts: 174 Thoughts: **Analyzing MIPS BPF JIT Compilation Functions** Okay, so I'm looking at these BPF JIT compilation functions for MIPS, and the first thing that jumps out is that `build_insn` isn't static. This is interesting, as static functions typically have internal linkage within the compilation unit, which suggests `build_insn` might be used more broadly. Then I see a couple of functions, `emit_div` and `emit_mod`, that *are* static, and they reside in `arch/mips/net/bpf_jit_comp.c`. That's expected, given their role in generating optimized code for division and modulo operations. Similarly, `emit_div64` and `emit_mod64` are static in `arch/mips/net/bpf_jit_comp64.c`, and `emit_divmod_r64` and `jit_smod64` are static in `arch/mips/net/bpf_jit_comp32.c`. Now, I'm going to quickly check `arch/mips/net/bpf_jit_comp.c` to see if I can find `emit_alu_r`, since I'm trying to get a handle on the function's scope and possible dependencies. This will help me build a clearer mental model of the MIPS BPF JIT compiler's architecture. |
| 8/2 | 2026/07/31 01:33 | tool | grepper |
0mArgs:{
"Expression": "emit_alu_r",
"PathPrefix": "arch/mips/net/"
}Results: {
"Output": "arch/mips/net/bpf_jit_comp.c=360=static void emit_mod(struct jit_context *ctx, u8 dst, u8 src, bool is_signed)\n--\narch/mips/net/bpf_jit_comp.c-376-/* ALU register operation (32-bit) */\narch/mips/net/bpf_jit_comp.c:377:void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op, bool is_signed)\narch/mips/net/bpf_jit_comp.c-378-{\n--\narch/mips/net/bpf_jit_comp.h=172=void emit_alu_i(struct jit_context *ctx, u8 dst, s32 imm, u8 op);\n--\narch/mips/net/bpf_jit_comp.h-174-/* ALU register operation (32-bit) */\narch/mips/net/bpf_jit_comp.h:175:void emit_alu_r(struct jit_context *ctx, u8 dst, u8 src, u8 op,\narch/mips/net/bpf_jit_comp.h-176-\t\tbool is_signed);\n--\narch/mips/net/bpf_jit_comp32.c=201=static void emit_alu_i64(struct jit_context *ctx,\n--\narch/mips/net/bpf_jit_comp32.c-266-/* ALU register operation (64-bit) */\narch/mips/net/bpf_jit_comp32.c:267:static void emit_alu_r64(struct jit_context *ctx,\narch/mips/net/bpf_jit_comp32.c-268-\t\t\t const u8 dst[], const u8 src[], u8 op)\n--\narch/mips/net/bpf_jit_comp32.c=1471=int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n--\narch/mips/net/bpf_jit_comp32.c-1529-\t\t\temit_mov_i(ctx, MIPS_R_T6, imm);\narch/mips/net/bpf_jit_comp32.c:1530:\t\t\temit_alu_r(ctx, lo(dst), MIPS_R_T6, BPF_OP(code),\narch/mips/net/bpf_jit_comp32.c-1531-\t\t\t\t is_signed);\n--\narch/mips/net/bpf_jit_comp32.c-1558-\tcase BPF_ALU | BPF_MOD | BPF_X:\narch/mips/net/bpf_jit_comp32.c:1559:\t\temit_alu_r(ctx, lo(dst), lo(src), BPF_OP(code), is_signed);\narch/mips/net/bpf_jit_comp32.c-1560-\t\temit_zext_ver(ctx, dst);\n--\narch/mips/net/bpf_jit_comp32.c-1623-\tcase BPF_ALU64 | BPF_SUB | BPF_X:\narch/mips/net/bpf_jit_comp32.c:1624:\t\temit_alu_r64(ctx, dst, src, BPF_OP(code));\narch/mips/net/bpf_jit_comp32.c-1625-\t\tbreak;\n--\narch/mips/net/bpf_jit_comp64.c=217=static void emit_mod64(struct jit_context *ctx, u8 dst, u8 src,\n--\narch/mips/net/bpf_jit_comp64.c-234-/* ALU register operation (64-bit) */\narch/mips/net/bpf_jit_comp64.c:235:static void emit_alu_r64(struct jit_context *ctx, u8 dst, u8 src, u8 op,\narch/mips/net/bpf_jit_comp64.c-236-\t\t\t bool is_signed)\n--\narch/mips/net/bpf_jit_comp64.c-280-\t\t/* Width-generic operations */\narch/mips/net/bpf_jit_comp64.c:281:\t\temit_alu_r(ctx, dst, src, op, false);\narch/mips/net/bpf_jit_comp64.c-282-\t}\n--\narch/mips/net/bpf_jit_comp64.c=660=int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)\n--\narch/mips/net/bpf_jit_comp64.c-704-\t\t\temit_mov_i(ctx, MIPS_R_T4, imm);\narch/mips/net/bpf_jit_comp64.c:705:\t\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code), false);\narch/mips/net/bpf_jit_comp64.c-706-\t\t} else if (rewrite_alu_i(BPF_OP(code), imm, \u0026alu, \u0026val)) {\n--\narch/mips/net/bpf_jit_comp64.c-727-\t\t\temit_mov_i(ctx, MIPS_R_T4, imm);\narch/mips/net/bpf_jit_comp64.c:728:\t\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code),\narch/mips/net/bpf_jit_comp64.c-729-\t\t\t\t is_signed);\n--\narch/mips/net/bpf_jit_comp64.c-743-\tcase BPF_ALU | BPF_LSH | BPF_X:\narch/mips/net/bpf_jit_comp64.c:744:\t\temit_alu_r(ctx, dst, src, BPF_OP(code), false);\narch/mips/net/bpf_jit_comp64.c-745-\t\temit_zext_ver(ctx, dst);\n--\narch/mips/net/bpf_jit_comp64.c-762-\t\temit_sext(ctx, MIPS_R_T4, src);\narch/mips/net/bpf_jit_comp64.c:763:\t\temit_alu_r(ctx, dst, MIPS_R_T4, BPF_OP(code), is_signed);\narch/mips/net/bpf_jit_comp64.c-764-\t\temit_zext_ver(ctx, dst);\n--\narch/mips/net/bpf_jit_comp64.c-801-\t\t\temit_mov_i(ctx, MIPS_R_T4, imm);\narch/mips/net/bpf_jit_comp64.c:802:\t\t\temit_alu_r64(ctx, dst, MIPS_R_T4, BPF_OP(code),\narch/mips/net/bpf_jit_comp64.c-803-\t\t\t\t is_signed);\n--\narch/mips/net/bpf_jit_comp64.c-829-\tcase BPF_ALU64 | BPF_MOD | BPF_X:\narch/mips/net/bpf_jit_comp64.c:830:\t\temit_alu_r64(ctx, dst, src, BPF_OP(code), is_signed);\narch/mips/net/bpf_jit_comp64.c-831-\t\tbreak;\n"
} |
| 9/2 | 2026/07/31 01:33 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 15908 output: 33 thoughts: 351 Thoughts: **Fuzzing the MIPS BPF JIT Compiler** Okay, so this patch introduces signed division and modulo support to the BPF JIT compiler specifically on MIPS architecture. That's a good target for fuzzing. The prime entry point is definitely `bpf_int_jit_compile`. I'll want to target that for sure. Given the architecture-specific code, I'll need to dig into the calls to `build_insn`. I see it defined in both `bpf_jit_comp32.c` and `bpf_jit_comp64.c`. But hold on, `build_insn` isn't static, so it should have a unique symbol address, which is good for fuzzing. `bpf_int_jit_compile` is the main thing here, but I need to understand how the instructions are built. Let's confirm how `bpf_int_jit_compile` interacts with `build_insn`. I'll peek at `arch/mips/net/bpf_jit_comp.c`, right, it looks like `build_body` calls `build_insn`, so that's the chain. I can probably fuzz the `bpf_int_jit_compile` function, and see how it builds instructions. Now, config requirements are important. Naturally, `CONFIG_BPF_JIT` is a must. And, since this is MIPS specific, I don't need `CONFIG_MIPS` because it's the architecture itself. I will look into `arch/mips/Kconfig` or `arch/mips/net/Makefile` to see if there are any architecture specific configuration details or dependencies. |
| 10/2 | 2026/07/31 01:33 | tool | grepper |
0mArgs:{
"Expression": "bpf_jit_comp",
"PathPrefix": "arch/mips/net/"
}Results: {
"Output": "arch/mips/net/Makefile-3-\narch/mips/net/Makefile:4:obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o\narch/mips/net/Makefile-5-\narch/mips/net/Makefile=6=ifeq ($(CONFIG_32BIT),y)\narch/mips/net/Makefile:7: obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o\narch/mips/net/Makefile-8-else\narch/mips/net/Makefile:9: obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o\narch/mips/net/Makefile-10-endif\n--\narch/mips/net/bpf_jit_comp.c-18- *\narch/mips/net/bpf_jit_comp.c:19: * - bpf_jit_comp.h\narch/mips/net/bpf_jit_comp.c-20- * Common definitions and utilities.\narch/mips/net/bpf_jit_comp.c-21- *\narch/mips/net/bpf_jit_comp.c:22: * - bpf_jit_comp.c\narch/mips/net/bpf_jit_comp.c-23- * Implementation of JIT top-level logic and exported JIT API functions.\n--\narch/mips/net/bpf_jit_comp.c-27- *\narch/mips/net/bpf_jit_comp.c:28: * - bpf_jit_comp32.c\narch/mips/net/bpf_jit_comp.c-29- * Implementation of functions to JIT prologue, epilogue and a single eBPF\n--\narch/mips/net/bpf_jit_comp.c-33- *\narch/mips/net/bpf_jit_comp.c:34: * - bpf_jit_comp64.c\narch/mips/net/bpf_jit_comp.c-35- * Ditto, for 64-bit MIPS CPUs.\n--\narch/mips/net/bpf_jit_comp.c-116-\narch/mips/net/bpf_jit_comp.c:117:#include \"bpf_jit_comp.h\"\narch/mips/net/bpf_jit_comp.c-118-\n--\narch/mips/net/bpf_jit_comp32.c-22-\narch/mips/net/bpf_jit_comp32.c:23:#include \"bpf_jit_comp.h\"\narch/mips/net/bpf_jit_comp32.c-24-\n--\narch/mips/net/bpf_jit_comp64.c-21-\narch/mips/net/bpf_jit_comp64.c:22:#include \"bpf_jit_comp.h\"\narch/mips/net/bpf_jit_comp64.c-23-\n"
} |
| 11/2 | 2026/07/31 01:33 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 17434 output: 29 thoughts: 335 Thoughts: **My Assessment of the BPF JIT Configuration and Micro-Assembler Integration** Okay, so I'm looking at this BPF JIT setup, and the key configuration item here is clearly `CONFIG_BPF_JIT`. That's the one I need to focus on. My initial targets are the core symbols: `bpf_int_jit_compile`, and the `build_insn` functions, which are in `bpf_jit_comp32.c` and `bpf_jit_comp64.c`. I need to confirm if these functions are accessible externally. Interestingly, `build_insn` is *not* static, so that's helpful. Now, `bpf_int_jit_compile` seems to be the primary entry point, so that's good to know. The `build_body` is a static helper function. I see `emit_alu_r` is non-static in `bpf_jit_comp.c`, which makes it a global symbol. So I need to add those to my understanding. It makes sense, `bpf_int_jit_compile`, `build_insn`, and `emit_alu_r` are important. I'm verifying that `bpf_int_jit_compile` is indeed the *only* entry point for the BPF JIT, to avoid getting distracted. That's confirmed. Let's double-check the related configurations, just to be thorough. I'm aware that `CONFIG_BPF_SYSCALL` is generally a prerequisite for BPF, but `CONFIG_BPF_JIT` is the specific one I'm concerned with here. Now, let's go back and review this patch a little more closely. I see that it's adding instructions to `uasm-mips.c` and `uasm.c`. It's pretty clear that these files are part of the MIPS micro-assembler. I need to check the MIPS architecture's Makefile to see which configuration option is enabling `uasm.c`. That will provide further clarity. |
| 12/2 | 2026/07/31 01:33 | tool | grepper |
0mArgs:{
"Expression": "uasm",
"PathPrefix": "arch/mips/mm/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1624 lines.\nUse more precise expression if possible.\n\narch/mips/mm/Makefile=19=ifdef CONFIG_CPU_MICROMIPS\narch/mips/mm/Makefile:20:obj-y\t\t\t\t+= uasm-micromips.o\narch/mips/mm/Makefile-21-else\narch/mips/mm/Makefile:22:obj-y\t\t\t\t+= uasm-mips.o\narch/mips/mm/Makefile-23-endif\n--\narch/mips/mm/page.c-35-\narch/mips/mm/page.c:36:#include \u003casm/uasm.h\u003e\narch/mips/mm/page.c-37-\n--\narch/mips/mm/page.c=51=UASM_L_LA(_copy_pref_store)\n--\narch/mips/mm/page.c-53-/* We need one branch and therefore one relocation per target label. */\narch/mips/mm/page.c:54:static struct uasm_label labels[5];\narch/mips/mm/page.c:55:static struct uasm_reloc relocs[5];\narch/mips/mm/page.c-56-\n--\narch/mips/mm/page.c-63- */\narch/mips/mm/page.c:64:#define _uasm_i_pref(a, b, c, d)\t\t\\\narch/mips/mm/page.c-65-do {\t\t\t\t\t\t\\\n--\narch/mips/mm/page.c-67-\t\tif (c \u003c= 0xff \u0026\u0026 c \u003e= -0x100)\t\\\narch/mips/mm/page.c:68:\t\t\tuasm_i_pref(a, b, c, d);\\\narch/mips/mm/page.c-69-\t} else {\t\t\t\t\\\narch/mips/mm/page.c:70:\t\tuasm_i_pref(a, b, c, d);\t\\\narch/mips/mm/page.c-71-\t}\t\t\t\t\t\\\n--\narch/mips/mm/page.c=91=pg_addiu(u32 **buf, unsigned int reg1, unsigned int reg2, unsigned int off)\n--\narch/mips/mm/page.c-96-\t\tif (off \u003e 0x7fff) {\narch/mips/mm/page.c:97:\t\t\tuasm_i_lui(buf, GPR_T9, uasm_rel_hi(off));\narch/mips/mm/page.c:98:\t\t\tuasm_i_addiu(buf, GPR_T9, GPR_T9, uasm_rel_lo(off));\narch/mips/mm/page.c-99-\t\t} else\narch/mips/mm/page.c:100:\t\t\tuasm_i_addiu(buf, GPR_T9, GPR_ZERO, off);\narch/mips/mm/page.c:101:\t\tuasm_i_daddu(buf, reg1, reg2, GPR_T9);\narch/mips/mm/page.c-102-\t} else {\narch/mips/mm/page.c-103-\t\tif (off \u003e 0x7fff) {\narch/mips/mm/page.c:104:\t\t\tuasm_i_lui(buf, GPR_T9, uasm_rel_hi(off));\narch/mips/mm/page.c:105:\t\t\tuasm_i_addiu(buf, GPR_T9, GPR_T9, uasm_rel_lo(off));\narch/mips/mm/page.c-106-\t\t\tUASM_i_ADDU(buf, reg1, reg2, GPR_T9);\n--\narch/mips/mm/page.c=221=static void build_clear_store(u32 **buf, int off)\n--\narch/mips/mm/page.c-223-\tif (cpu_has_64bit_gp_regs || cpu_has_64bit_zero_reg) {\narch/mips/mm/page.c:224:\t\tuasm_i_sd(buf, GPR_ZERO, off, GPR_A0);\narch/mips/mm/page.c-225-\t} else {\narch/mips/mm/page.c:226:\t\tuasm_i_sw(buf, GPR_ZERO, off, GPR_A0);\narch/mips/mm/page.c-227-\t}\n--\narch/mips/mm/page.c=230=static inline void build_clear_pref(u32 **buf, int off)\n--\narch/mips/mm/page.c-235-\tif (pref_bias_clear_store) {\narch/mips/mm/page.c:236:\t\t_uasm_i_pref(buf, pref_dst_mode, pref_bias_clear_store + off,\narch/mips/mm/page.c-237-\t\t\t GPR_A0);\n--\narch/mips/mm/page.c-239-\t\tif (cpu_has_cache_cdex_s) {\narch/mips/mm/page.c:240:\t\t\tuasm_i_cache(buf, Create_Dirty_Excl_SD, off, GPR_A0);\narch/mips/mm/page.c-241-\t\t} else if (cpu_has_cache_cdex_p) {\n--\narch/mips/mm/page.c-243-\t\t\t cpu_is_r4600_v1_x()) {\narch/mips/mm/page.c:244:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c:245:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c:246:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c:247:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c-248-\t\t\t}\n--\narch/mips/mm/page.c-251-\t\t\t cpu_is_r4600_v2_x())\narch/mips/mm/page.c:252:\t\t\t\tuasm_i_lw(buf, GPR_ZERO, GPR_ZERO, GPR_AT);\narch/mips/mm/page.c-253-\narch/mips/mm/page.c:254:\t\t\tuasm_i_cache(buf, Create_Dirty_Excl_D, off, GPR_A0);\narch/mips/mm/page.c-255-\t\t}\n--\narch/mips/mm/page.c=264=void build_clear_page(void)\n--\narch/mips/mm/page.c-267-\tu32 *buf = \u0026__clear_page_start;\narch/mips/mm/page.c:268:\tstruct uasm_label *l = labels;\narch/mips/mm/page.c:269:\tstruct uasm_reloc *r = relocs;\narch/mips/mm/page.c-270-\tint i;\n--\narch/mips/mm/page.c-293-\telse\narch/mips/mm/page.c:294:\t\tuasm_i_ori(\u0026buf, GPR_A2, GPR_A0, off);\narch/mips/mm/page.c-295-\narch/mips/mm/page.c-296-\tif (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) \u0026\u0026 cpu_is_r4600_v2_x())\narch/mips/mm/page.c:297:\t\tuasm_i_lui(\u0026buf, GPR_AT, uasm_rel_hi(0xa0000000));\narch/mips/mm/page.c-298-\n--\narch/mips/mm/page.c-304-\t}\narch/mips/mm/page.c:305:\tuasm_l_clear_pref(\u0026l, buf);\narch/mips/mm/page.c-306-\tdo {\n--\narch/mips/mm/page.c-315-\t\tif (off == -clear_word_size)\narch/mips/mm/page.c:316:\t\t\tuasm_il_bne(\u0026buf, \u0026r, GPR_A0, GPR_A2, label_clear_pref);\narch/mips/mm/page.c-317-\t\tbuild_clear_store(\u0026buf, off);\n--\narch/mips/mm/page.c-322-\t\tpg_addiu(\u0026buf, GPR_A2, GPR_A0, pref_bias_clear_store);\narch/mips/mm/page.c:323:\t\tuasm_l_clear_nopref(\u0026l, buf);\narch/mips/mm/page.c-324-\t\toff = 0;\n--\narch/mips/mm/page.c-332-\t\t\tif (off == -clear_word_size)\narch/mips/mm/page.c:333:\t\t\t\tuasm_il_bne(\u0026buf, \u0026r, GPR_A0, GPR_A2,\narch/mips/mm/page.c-334-\t\t\t\t\t label_clear_nopref);\n--\narch/mips/mm/page.c-339-\narch/mips/mm/page.c:340:\tuasm_i_jr(\u0026buf, GPR_RA);\narch/mips/mm/page.c:341:\tuasm_i_nop(\u0026buf);\narch/mips/mm/page.c-342-\n--\narch/mips/mm/page.c-344-\narch/mips/mm/page.c:345:\tuasm_resolve_relocs(relocs, labels);\narch/mips/mm/page.c-346-\n--\narch/mips/mm/page.c=357=static void build_copy_load(u32 **buf, int reg, int off)\n--\narch/mips/mm/page.c-359-\tif (cpu_has_64bit_gp_regs) {\narch/mips/mm/page.c:360:\t\tuasm_i_ld(buf, reg, off, GPR_A1);\narch/mips/mm/page.c-361-\t} else {\narch/mips/mm/page.c:362:\t\tuasm_i_lw(buf, reg, off, GPR_A1);\narch/mips/mm/page.c-363-\t}\n--\narch/mips/mm/page.c=366=static void build_copy_store(u32 **buf, int reg, int off)\n--\narch/mips/mm/page.c-368-\tif (cpu_has_64bit_gp_regs) {\narch/mips/mm/page.c:369:\t\tuasm_i_sd(buf, reg, off, GPR_A0);\narch/mips/mm/page.c-370-\t} else {\narch/mips/mm/page.c:371:\t\tuasm_i_sw(buf, reg, off, GPR_A0);\narch/mips/mm/page.c-372-\t}\n--\narch/mips/mm/page.c=375=static inline void build_copy_load_pref(u32 **buf, int off)\n--\narch/mips/mm/page.c-380-\tif (pref_bias_copy_load)\narch/mips/mm/page.c:381:\t\t_uasm_i_pref(buf, pref_src_mode, pref_bias_copy_load + off, GPR_A1);\narch/mips/mm/page.c-382-}\n--\narch/mips/mm/page.c=384=static inline void build_copy_store_pref(u32 **buf, int off)\n--\narch/mips/mm/page.c-389-\tif (pref_bias_copy_store) {\narch/mips/mm/page.c:390:\t\t_uasm_i_pref(buf, pref_dst_mode, pref_bias_copy_store + off,\narch/mips/mm/page.c-391-\t\t\t GPR_A0);\n--\narch/mips/mm/page.c-393-\t\tif (cpu_has_cache_cdex_s) {\narch/mips/mm/page.c:394:\t\t\tuasm_i_cache(buf, Create_Dirty_Excl_SD, off, GPR_A0);\narch/mips/mm/page.c-395-\t\t} else if (cpu_has_cache_cdex_p) {\n--\narch/mips/mm/page.c-397-\t\t\t cpu_is_r4600_v1_x()) {\narch/mips/mm/page.c:398:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c:399:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c:400:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c:401:\t\t\t\tuasm_i_nop(buf);\narch/mips/mm/page.c-402-\t\t\t}\n--\narch/mips/mm/page.c-405-\t\t\t cpu_is_r4600_v2_x())\narch/mips/mm/page.c:406:\t\t\t\tuasm_i_lw(buf, GPR_ZERO, GPR_ZERO, GPR_AT);\narch/mips/mm/page.c-407-\narch/mips/mm/page.c:408:\t\t\tuasm_i_cache(buf, Create_Dirty_Excl_D, off, GPR_A0);\narch/mips/mm/page.c-409-\t\t}\n--\narch/mips/mm/page.c=413=void build_copy_page(void)\n--\narch/mips/mm/page.c-416-\tu32 *buf = \u0026__copy_page_start;\narch/mips/mm/page.c:417:\tstruct uasm_label *l = labels;\narch/mips/mm/page.c:418:\tstruct uasm_reloc *r = relocs;\narch/mips/mm/page.c-419-\tint i;\n--\narch/mips/mm/page.c-446-\telse\narch/mips/mm/page.c:447:\t\tuasm_i_ori(\u0026buf, GPR_A2, GPR_A0, off);\narch/mips/mm/page.c-448-\narch/mips/mm/page.c-449-\tif (IS_ENABLED(CONFIG_WAR_R4600_V2_HIT_CACHEOP) \u0026\u0026 cpu_is_r4600_v2_x())\narch/mips/mm/page.c:450:\t\tuasm_i_lui(\u0026buf, GPR_AT, uasm_rel_hi(0xa0000000));\narch/mips/mm/page.c-451-\n--\narch/mips/mm/page.c-463-\t}\narch/mips/mm/page.c:464:\tuasm_l_copy_pref_both(\u0026l, buf);\narch/mips/mm/page.c-465-\tdo {\n--\narch/mips/mm/page.c-503-\t\tif (off == -(4 * copy_word_size))\narch/mips/mm/page.c:504:\t\t\tuasm_il_bne(\u0026buf, \u0026r, GPR_A2, GPR_A0, label_copy_pref_both);\narch/mips/mm/page.c-505-\t\tbuild_copy_store(\u0026buf, GPR_T3, off + 3 * copy_word_size);\n--\narch/mips/mm/page.c-511-\t\t\t pref_bias_copy_load - pref_bias_copy_store);\narch/mips/mm/page.c:512:\t\tuasm_l_copy_pref_store(\u0026l, buf);\narch/mips/mm/page.c-513-\t\toff = 0;\n--\narch/mips/mm/page.c-544-\t\t\tif (off == -(4 * copy_word_size))\narch/mips/mm/page.c:545:\t\t\t\tuasm_il_bne(\u0026buf, \u0026r, GPR_A2, GPR_A0,\narch/mips/mm/page.c-546-\t\t\t\t\t label_copy_pref_store);\n--\narch/mips/mm/page.c-553-\t\tpg_addiu(\u0026buf, GPR_A2, GPR_A0, pref_bias_copy_store);\narch/mips/mm/page.c:554:\t\tuasm_l_copy_nopref(\u0026l, buf);\narch/mips/mm/page.c-555-\t\toff = 0;\n--\narch/mips/mm/page.c-578-\t\t\tif (off == -(4 * copy_word_size))\narch/mips/mm/page.c:579:\t\t\t\tuasm_il_bne(\u0026buf, \u0026r, GPR_A2, GPR_A0,\narch/mips/mm/page.c-580-\t\t\t\t\t label_copy_nopref);\n--\narch/mips/mm/page.c-585-\narch/mips/mm/page.c:586:\tuasm_i_jr(\u0026buf, GPR_RA);\narch/mips/mm/page.c:587:\tuasm_i_nop(\u0026buf);\narch/mips/mm/page.c-588-\n--\narch/mips/mm/page.c-590-\narch/mips/mm/page.c:591:\tuasm_resolve_relocs(relocs, labels);\narch/mips/mm/page.c-592-\n--\narch/mips/mm/tlbex.c-37-#include \u003casm/regdef.h\u003e\narch/mips/mm/tlbex.c:38:#include \u003casm/uasm.h\u003e\narch/mips/mm/tlbex.c-39-#include \u003casm/setup.h\u003e\n--\narch/mips/mm/tlbex.c=204=static int hazard_instance;\narch/mips/mm/tlbex.c-205-\narch/mips/mm/tlbex.c:206:static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)\narch/mips/mm/tlbex.c-207-{\n--\narch/mips/mm/tlbex.c-209-\tcase 0 ... 7:\narch/mips/mm/tlbex.c:210:\t\tuasm_il_bgezl(p, r, 0, label_tlbw_hazard_0 + instance);\narch/mips/mm/tlbex.c-211-\t\treturn;\n--\narch/mips/mm/tlbex.c-216-\narch/mips/mm/tlbex.c:217:static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)\narch/mips/mm/tlbex.c-218-{\n--\narch/mips/mm/tlbex.c-220-\tcase 0 ... 7:\narch/mips/mm/tlbex.c:221:\t\tuasm_build_label(l, *p, label_tlbw_hazard_0 + instance);\narch/mips/mm/tlbex.c-222-\t\tbreak;\n--\narch/mips/mm/tlbex.c=295=static u32 tlb_handler[128];\n--\narch/mips/mm/tlbex.c-297-/* simply assume worst case size for labels and relocs */\narch/mips/mm/tlbex.c:298:static struct uasm_label labels[128];\narch/mips/mm/tlbex.c:299:static struct uasm_reloc relocs[128];\narch/mips/mm/tlbex.c-300-\n--\narch/mips/mm/tlbex.c=369=static void build_restore_work_registers(u32 **p)\n--\narch/mips/mm/tlbex.c-371-\tif (scratch_reg \u003e= 0) {\narch/mips/mm/tlbex.c:372:\t\tuasm_i_ehb(p);\narch/mips/mm/tlbex.c-373-\t\tUASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);\n--\narch/mips/mm/tlbex.c=389=static void build_r3000_tlb_refill_handler(void)\n--\narch/mips/mm/tlbex.c-396-\narch/mips/mm/tlbex.c:397:\tuasm_i_mfc0(\u0026p, GPR_K0, C0_BADVADDR);\narch/mips/mm/tlbex.c:398:\tuasm_i_lui(\u0026p, GPR_K1, uasm_rel_hi(pgdc)); /* cp0 delay */\narch/mips/mm/tlbex.c:399:\tuasm_i_lw(\u0026p, GPR_K1, uasm_rel_lo(pgdc), GPR_K1);\narch/mips/mm/tlbex.c:400:\tuasm_i_srl(\u0026p, GPR_K0, GPR_K0, 22); /* load delay */\narch/mips/mm/tlbex.c:401:\tuasm_i_sll(\u0026p, GPR_K0, GPR_K0, 2);\narch/mips/mm/tlbex.c:402:\tuasm_i_addu(\u0026p, GPR_K1, GPR_K1, GPR_K0);\narch/mips/mm/tlbex.c:403:\tuasm_i_mfc0(\u0026p, GPR_K0, C0_CONTEXT);\narch/mips/mm/tlbex.c:404:\tuasm_i_lw(\u0026p, GPR_K1, 0, GPR_K1); /* cp0 delay */\narch/mips/mm/tlbex.c:405:\tuasm_i_andi(\u0026p, GPR_K0, GPR_K0, 0xffc); /* load delay */\narch/mips/mm/tlbex.c:406:\tuasm_i_addu(\u0026p, GPR_K1, GPR_K1, GPR_K0);\narch/mips/mm/tlbex.c:407:\tuasm_i_lw(\u0026p, GPR_K0, 0, GPR_K1);\narch/mips/mm/tlbex.c:408:\tuasm_i_nop(\u0026p); /* load delay */\narch/mips/mm/tlbex.c:409:\tuasm_i_mtc0(\u0026p, GPR_K0, C0_ENTRYLO0);\narch/mips/mm/tlbex.c:410:\tuasm_i_mfc0(\u0026p, GPR_K1, C0_EPC); /* cp0 delay */\narch/mips/mm/tlbex.c:411:\tuasm_i_tlbwr(\u0026p); /* cp0 delay */\narch/mips/mm/tlbex.c:412:\tuasm_i_jr(\u0026p, GPR_K1);\narch/mips/mm/tlbex.c:413:\tuasm_i_rfe(\u0026p); /* branch delay */\narch/mips/mm/tlbex.c-414-\n--\narch/mips/mm/tlbex.c=458=static void __maybe_unused build_tlb_probe_entry(u32 **p)\n--\narch/mips/mm/tlbex.c-465-\tcase CPU_NEVADA:\narch/mips/mm/tlbex.c:466:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c:467:\t\tuasm_i_tlbp(p);\narch/mips/mm/tlbex.c-468-\t\tbreak;\n--\narch/mips/mm/tlbex.c-470-\tdefault:\narch/mips/mm/tlbex.c:471:\t\tuasm_i_tlbp(p);\narch/mips/mm/tlbex.c-472-\t\tbreak;\n--\narch/mips/mm/tlbex.c-475-\narch/mips/mm/tlbex.c:476:void build_tlb_write_entry(u32 **p, struct uasm_label **l,\narch/mips/mm/tlbex.c:477:\t\t\t struct uasm_reloc **r,\narch/mips/mm/tlbex.c-478-\t\t\t enum tlb_write_entry wmode)\n--\narch/mips/mm/tlbex.c-482-\tswitch (wmode) {\narch/mips/mm/tlbex.c:483:\tcase tlb_random: tlbw = uasm_i_tlbwr; break;\narch/mips/mm/tlbex.c:484:\tcase tlb_indexed: tlbw = uasm_i_tlbwi; break;\narch/mips/mm/tlbex.c-485-\t}\n--\narch/mips/mm/tlbex.c-488-\t\tif (cpu_has_mips_r2_exec_hazard)\narch/mips/mm/tlbex.c:489:\t\t\tuasm_i_ehb(p);\narch/mips/mm/tlbex.c-490-\t\ttlbw(p);\n--\narch/mips/mm/tlbex.c-504-\t\t */\narch/mips/mm/tlbex.c:505:\t\tuasm_bgezl_hazard(p, r, hazard_instance);\narch/mips/mm/tlbex.c-506-\t\ttlbw(p);\narch/mips/mm/tlbex.c:507:\t\tuasm_bgezl_label(l, p, hazard_instance);\narch/mips/mm/tlbex.c-508-\t\thazard_instance++;\narch/mips/mm/tlbex.c:509:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-510-\t\tbreak;\n--\narch/mips/mm/tlbex.c-513-\tcase CPU_R4700:\narch/mips/mm/tlbex.c:514:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-515-\t\ttlbw(p);\narch/mips/mm/tlbex.c:516:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-517-\t\tbreak;\n--\narch/mips/mm/tlbex.c-520-\tcase CPU_NEVADA:\narch/mips/mm/tlbex.c:521:\t\tuasm_i_nop(p); /* QED specifies 2 nops hazard */\narch/mips/mm/tlbex.c:522:\t\tuasm_i_nop(p); /* QED specifies 2 nops hazard */\narch/mips/mm/tlbex.c-523-\t\ttlbw(p);\n--\narch/mips/mm/tlbex.c-529-\tcase CPU_PR4450:\narch/mips/mm/tlbex.c:530:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-531-\t\ttlbw(p);\n--\narch/mips/mm/tlbex.c-555-\t\tif (m4kc_tlbp_war())\narch/mips/mm/tlbex.c:556:\t\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-557-\t\tfallthrough;\n--\narch/mips/mm/tlbex.c-562-\tcase CPU_RM7000:\narch/mips/mm/tlbex.c:563:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c:564:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c:565:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c:566:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-567-\t\ttlbw(p);\n--\narch/mips/mm/tlbex.c-571-\t\ttlbw(p);\narch/mips/mm/tlbex.c:572:\t\tuasm_i_nop(p);\narch/mips/mm/tlbex.c-573-\t\tbreak;\n--\narch/mips/mm/tlbex.c=583=static __maybe_unused void build_convert_pte_to_entrylo(u32 **p,\n--\narch/mips/mm/tlbex.c-600-#ifdef CONFIG_PHYS_ADDR_T_64BIT\narch/mips/mm/tlbex.c:601:\t\tuasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL));\narch/mips/mm/tlbex.c-602-#else\n--\narch/mips/mm/tlbex.c-609-\narch/mips/mm/tlbex.c:610:static void build_restore_pagemask(u32 **p, struct uasm_reloc **r,\narch/mips/mm/tlbex.c-611-\t\t\t\t unsigned int tmp, enum label_id lid,\n--\narch/mips/mm/tlbex.c-619-\t\tif (scratch_reg \u003e= 0)\narch/mips/mm/tlbex.c:620:\t\t\tuasm_i_ehb(p);\narch/mips/mm/tlbex.c-621-\n--\narch/mips/mm/tlbex.c-623-\t\tif (PM_DEFAULT_MASK \u003e\u003e 16) {\narch/mips/mm/tlbex.c:624:\t\t\tuasm_i_lui(p, tmp, PM_DEFAULT_MASK \u003e\u003e 16);\narch/mips/mm/tlbex.c:625:\t\t\tuasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK \u0026 0xffff);\narch/mips/mm/tlbex.c:626:\t\t\tuasm_i_mtc0(p, tmp, C0_PAGEMASK);\narch/mips/mm/tlbex.c:627:\t\t\tuasm_il_b(p, r, lid);\narch/mips/mm/tlbex.c-628-\t\t} else if (PM_DEFAULT_MASK) {\narch/mips/mm/tlbex.c:629:\t\t\tuasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);\narch/mips/mm/tlbex.c:630:\t\t\tuasm_i_mtc0(p, tmp, C0_PAGEMASK);\narch/mips/mm/tlbex.c:631:\t\t\tuasm_il_b(p, r, lid);\narch/mips/mm/tlbex.c-632-\t\t} else {\narch/mips/mm/tlbex.c:633:\t\t\tuasm_i_mtc0(p, 0, C0_PAGEMASK);\narch/mips/mm/tlbex.c:634:\t\t\tuasm_il_b(p, r, lid);\narch/mips/mm/tlbex.c-635-\t\t}\n--\narch/mips/mm/tlbex.c-642-\t\tif (PM_DEFAULT_MASK \u003e\u003e 16) {\narch/mips/mm/tlbex.c:643:\t\t\tuasm_i_lui(p, tmp, PM_DEFAULT_MASK \u003e\u003e 16);\narch/mips/mm/tlbex.c:644:\t\t\tuasm_i_ori(p, tmp, tmp, PM_DEFAULT_MASK \u0026 0xffff);\narch/mips/mm/tlbex.c:645:\t\t\tuasm_il_b(p, r, lid);\narch/mips/mm/tlbex.c:646:\t\t\tuasm_i_mtc0(p, tmp, C0_PAGEMASK);\narch/mips/mm/tlbex.c-647-\t\t} else if (PM_DEFAULT_MASK) {\narch/mips/mm/tlbex.c:648:\t\t\tuasm_i_ori(p, tmp, 0, PM_DEFAULT_MASK);\narch/mips/mm/tlbex.c:649:\t\t\tuasm_il_b(p, r, lid);\narch/mips/mm/tlbex.c:650:\t\t\tuasm_i_mtc0(p, tmp, C0_PAGEMASK);\narch/mips/mm/tlbex.c-651-\t\t} else {\narch/mips/mm/tlbex.c:652:\t\t\tuasm_il_b(p, r, lid);\narch/mips/mm/tlbex.c:653:\t\t\tuasm_i_mtc0(p, 0, C0_PAGEMASK);\narch/mips/mm/tlbex.c-654-\t\t}\n--\narch/mips/mm/tlbex.c-657-\narch/mips/mm/tlbex.c:658:static void build_huge_tlb_write_entry(u32 **p, struct uasm_label **l,\narch/mips/mm/tlbex.c:659:\t\t\t\t struct uasm_reloc **r,\narch/mips/mm/tlbex.c-660-\t\t\t\t unsigned int tmp,\n--\narch/mips/mm/tlbex.c-664-\t/* Set huge page tlb entry size */\narch/mips/mm/tlbex.c:665:\tuasm_i_lui(p, tmp, PM_HUGE_MASK \u003e\u003e 16);\narch/mips/mm/tlbex.c:666:\tuasm_i_ori(p, tmp, tmp, PM_HUGE_MASK \u0026 0xffff);\narch/mips/mm/tlbex.c:667:\tuasm_i_mtc0(p, tmp, C0_PAGEMASK);\narch/mips/mm/tlbex.c-668-\n--\narch/mips/mm/tlbex.c=677=static void\narch/mips/mm/tlbex.c:678:build_is_huge_pte(u32 **p, struct uasm_reloc **r, unsigned int tmp,\narch/mips/mm/tlbex.c-679-\t\t unsigned int pmd, int lid)\n--\narch/mips/mm/tlbex.c-682-\tif (use_bbit_insns()) {\narch/mips/mm/tlbex.c:683:\t\tuasm_il_bbit1(p, r, tmp, ilog2(_PAGE_HUGE), lid);\narch/mips/mm/tlbex.c-684-\t} else {\narch/mips/mm/tlbex.c:685:\t\tuasm_i_andi(p, tmp, tmp, _PAGE_HUGE);\narch/mips/mm/tlbex.c:686:\t\tuasm_il_bnez(p, r, tmp, lid);\narch/mips/mm/tlbex.c-687-\t}\n--\narch/mips/mm/tlbex.c=690=static void build_huge_update_entries(u32 **p, unsigned int pte,\n--\narch/mips/mm/tlbex.c-707-\tif (!small_sequence)\narch/mips/mm/tlbex.c:708:\t\tuasm_i_lui(p, tmp, HPAGE_SIZE \u003e\u003e (7 + 16));\narch/mips/mm/tlbex.c-709-\n--\narch/mips/mm/tlbex.c-720-\narch/mips/mm/tlbex.c:721:static void build_huge_handler_tail(u32 **p, struct uasm_reloc **r,\narch/mips/mm/tlbex.c:722:\t\t\t\t struct uasm_label **l,\narch/mips/mm/tlbex.c-723-\t\t\t\t unsigned int pte,\n--\narch/mips/mm/tlbex.c-728-\tUASM_i_SC(p, pte, 0, ptr);\narch/mips/mm/tlbex.c:729:\tuasm_il_beqz(p, r, pte, label_tlb_huge_update);\narch/mips/mm/tlbex.c-730-\tUASM_i_LW(p, pte, 0, ptr); /* Needed because SC killed our PTE */\n--\narch/mips/mm/tlbex.c-737-\t\tUASM_i_MFC0(p, ptr, C0_ENTRYHI);\narch/mips/mm/tlbex.c:738:\t\tuasm_i_ori(p, ptr, ptr, MIPS_ENTRYHI_EHINV);\narch/mips/mm/tlbex.c-739-\t\tUASM_i_MTC0(p, ptr, C0_ENTRYHI);\n--\narch/mips/mm/tlbex.c-741-\narch/mips/mm/tlbex.c:742:\t\tuasm_i_xori(p, ptr, ptr, MIPS_ENTRYHI_EHINV);\narch/mips/mm/tlbex.c-743-\t\tUASM_i_MTC0(p, ptr, C0_ENTRYHI);\n--\narch/mips/mm/tlbex.c-759- */\narch/mips/mm/tlbex.c:760:void build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,\narch/mips/mm/tlbex.c-761-\t\t unsigned int tmp, unsigned int ptr)\n--\narch/mips/mm/tlbex.c-768-\t */\narch/mips/mm/tlbex.c:769:\tuasm_i_dmfc0(p, tmp, C0_BADVADDR);\narch/mips/mm/tlbex.c-770-\n--\narch/mips/mm/tlbex.c-782-\t\t */\narch/mips/mm/tlbex.c:783:\t\tuasm_i_dsrl_safe(p, ptr, tmp, PGDIR_SHIFT + PGD_TABLE_ORDER + PAGE_SHIFT - 3);\narch/mips/mm/tlbex.c:784:\t\tuasm_il_bnez(p, r, ptr, label_vmalloc);\narch/mips/mm/tlbex.c-785-\t} else {\narch/mips/mm/tlbex.c:786:\t\tuasm_il_bltz(p, r, tmp, label_vmalloc);\narch/mips/mm/tlbex.c-787-\t}\narch/mips/mm/tlbex.c:788:\t/* No uasm_i_nop needed here, since the next insn doesn't touch TMP. */\narch/mips/mm/tlbex.c-789-\n--\narch/mips/mm/tlbex.c-803-\t\t/* Clear lower 23 bits of context. */\narch/mips/mm/tlbex.c:804:\t\tuasm_i_dins(p, ptr, 0, 0, 23);\narch/mips/mm/tlbex.c-805-\narch/mips/mm/tlbex.c-806-\t\t/* insert bit[63:59] of CAC_BASE into bit[11:6] of ptr */\narch/mips/mm/tlbex.c:807:\t\tuasm_i_ori(p, ptr, ptr, ((u64)(CAC_BASE) \u003e\u003e 53));\narch/mips/mm/tlbex.c:808:\t\tuasm_i_drotr(p, ptr, ptr, 11);\narch/mips/mm/tlbex.c-809-#elif defined(CONFIG_SMP)\narch/mips/mm/tlbex.c-810-\t\tUASM_i_CPUID_MFC0(p, ptr, SMP_CPUID_REG);\narch/mips/mm/tlbex.c:811:\t\tuasm_i_dsrl_safe(p, ptr, ptr, SMP_CPUID_PTRSHIFT);\narch/mips/mm/tlbex.c-812-\t\tUASM_i_LA_mostly(p, tmp, pgdc);\narch/mips/mm/tlbex.c:813:\t\tuasm_i_daddu(p, ptr, ptr, tmp);\narch/mips/mm/tlbex.c:814:\t\tuasm_i_dmfc0(p, tmp, C0_BADVADDR);\narch/mips/mm/tlbex.c:815:\t\tuasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);\narch/mips/mm/tlbex.c-816-#else\narch/mips/mm/tlbex.c-817-\t\tUASM_i_LA_mostly(p, ptr, pgdc);\narch/mips/mm/tlbex.c:818:\t\tuasm_i_ld(p, ptr, uasm_rel_lo(pgdc), ptr);\narch/mips/mm/tlbex.c-819-#endif\n--\narch/mips/mm/tlbex.c-821-\narch/mips/mm/tlbex.c:822:\tuasm_l_vmalloc_done(l, *p);\narch/mips/mm/tlbex.c-823-\narch/mips/mm/tlbex.c-824-\t/* get pgd offset in bytes */\narch/mips/mm/tlbex.c:825:\tuasm_i_dsrl_safe(p, tmp, tmp, PGDIR_SHIFT - 3);\narch/mips/mm/tlbex.c-826-\narch/mips/mm/tlbex.c:827:\tuasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)\u003c\u003c3);\narch/mips/mm/tlbex.c:828:\tuasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */\narch/mips/mm/tlbex.c-829-#ifndef __PAGETABLE_PUD_FOLDED\narch/mips/mm/tlbex.c:830:\tuasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */\narch/mips/mm/tlbex.c:831:\tuasm_i_ld(p, ptr, 0, ptr); /* get pud pointer */\narch/mips/mm/tlbex.c:832:\tuasm_i_dsrl_safe(p, tmp, tmp, PUD_SHIFT - 3); /* get pud offset in bytes */\narch/mips/mm/tlbex.c:833:\tuasm_i_andi(p, tmp, tmp, (PTRS_PER_PUD - 1) \u003c\u003c 3);\narch/mips/mm/tlbex.c:834:\tuasm_i_daddu(p, ptr, ptr, tmp); /* add in pud offset */\narch/mips/mm/tlbex.c-835-#endif\narch/mips/mm/tlbex.c-836-#ifndef __PAGETABLE_PMD_FOLDED\narch/mips/mm/tlbex.c:837:\tuasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */\narch/mips/mm/tlbex.c:838:\tuasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */\narch/mips/mm/tlbex.c:839:\tuasm_i_dsrl_safe(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */\narch/mips/mm/tlbex.c:840:\tuasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)\u003c\u003c3);\narch/mips/mm/tlbex.c:841:\tuasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */\narch/mips/mm/tlbex.c-842-#endif\n--\narch/mips/mm/tlbex.c=850=static void\narch/mips/mm/tlbex.c:851:build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,\narch/mips/mm/tlbex.c-852-\t\t\tunsigned int bvaddr, unsigned int ptr,\n--\narch/mips/mm/tlbex.c-858-\narch/mips/mm/tlbex.c:859:\tsingle_insn_swpd = uasm_in_compat_space_p(swpd) \u0026\u0026 !uasm_rel_lo(swpd);\narch/mips/mm/tlbex.c-860-\narch/mips/mm/tlbex.c:861:\tuasm_l_vmalloc(l, *p);\narch/mips/mm/tlbex.c-862-\n--\narch/mips/mm/tlbex.c-864-\t\tif (single_insn_swpd) {\narch/mips/mm/tlbex.c:865:\t\t\tuasm_il_bltz(p, r, bvaddr, label_vmalloc_done);\narch/mips/mm/tlbex.c:866:\t\t\tuasm_i_lui(p, ptr, uasm_rel_hi(swpd));\narch/mips/mm/tlbex.c-867-\t\t\tdid_vmalloc_branch = 1;\n--\narch/mips/mm/tlbex.c-869-\t\t} else {\narch/mips/mm/tlbex.c:870:\t\t\tuasm_il_bgez(p, r, bvaddr, label_large_segbits_fault);\narch/mips/mm/tlbex.c-871-\t\t}\n--\narch/mips/mm/tlbex.c-874-\t\tif (single_insn_swpd) {\narch/mips/mm/tlbex.c:875:\t\t\tuasm_il_b(p, r, label_vmalloc_done);\narch/mips/mm/tlbex.c:876:\t\t\tuasm_i_lui(p, ptr, uasm_rel_hi(swpd));\narch/mips/mm/tlbex.c-877-\t\t} else {\narch/mips/mm/tlbex.c-878-\t\t\tUASM_i_LA_mostly(p, ptr, swpd);\narch/mips/mm/tlbex.c:879:\t\t\tuasm_il_b(p, r, label_vmalloc_done);\narch/mips/mm/tlbex.c:880:\t\t\tif (uasm_in_compat_space_p(swpd))\narch/mips/mm/tlbex.c:881:\t\t\t\tuasm_i_addiu(p, ptr, ptr, uasm_rel_lo(swpd));\narch/mips/mm/tlbex.c-882-\t\t\telse\narch/mips/mm/tlbex.c:883:\t\t\t\tuasm_i_daddiu(p, ptr, ptr, uasm_rel_lo(swpd));\narch/mips/mm/tlbex.c-884-\t\t}\n--\narch/mips/mm/tlbex.c-886-\tif (mode != not_refill \u0026\u0026 check_for_high_segbits) {\narch/mips/mm/tlbex.c:887:\t\tuasm_l_large_segbits_fault(l, *p);\n\n"
} |
| 13/2 | 2026/07/31 01:33 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31019 output: 159 thoughts: 1448 Thoughts: **My Analysis of the MIPS BPF JIT Patch** Okay, let's break this down. This patch is adding support for division and modulo operations, specifically signed ones, within the MIPS BPF JIT compiler. The `uasm` micro-assembler is the key, and it's being updated to handle the new `ddiv`, `ddiv_r6`, `div`, `div_r6`, `dmod`, and `mod` instructions. These are essential for the BPF JIT, which is, of course, controlled by the `CONFIG_BPF_JIT` configuration option. Good, so `CONFIG_BPF_JIT` is definitely the enabling config. No need to worry about `CONFIG_MIPS32_O32` or anything like that. Since the patch touches both `bpf_jit_comp32.c` and `bpf_jit_comp64.c`, this applies to both 32-bit and 64-bit MIPS architectures. So, I will just set the config to `BPF_JIT` which is the correct one. Now, let's consider the key symbols. `bpf_int_jit_compile` is the main entry point for the BPF JIT, so that's a good starting point. Then we have `build_insn`, the workhorse function translating BPF instructions to MIPS code. Also, functions like `emit_alu_r`, `emit_div`, `emit_mod`, `emit_div64`, `emit_mod64` should be taken into account. Interestingly, `jit_smod64` is static, which is usually a red flag when fuzzing, because it means it can't be called directly. But, in this case, its address is *taken* via a function pointer: ```c case BPF_MOD: addr = is_signed ? (u32)&jit_smod64 : (u32)&jit_mod64; break; ``` That *forces* it to have a distinct symbol address, making it a viable target. Going to look at `jit_smod64` in `arch/mips/net/bpf_jit_comp32.c`, confirmed, it's there. So `jit_smod64` is a go! `build_insn` is another obvious candidate because it is in both `.c` files, so if I pick it, it will trigger both. I should also include `emit_alu_r`. Okay, I've confirmed that `CONFIG_BPF_JIT` is the sole config needed. Therefore, the focus symbols are: - `bpf_int_jit_compile` - `build_insn` - `jit_smod64` - `emit_alu_r` Enable config: `BPF_JIT` **Reasoning:** This patch fundamentally alters core kernel functionality by providing new signed division and modulo capabilities to the BPF JIT compiler. It modifies how instructions are translated and executed, making it a critical area for fuzzing. Going to double-check that `jit_smod64` is specifically 32-bit. It *is* in `arch/mips/net/bpf_jit_comp32.c`. On 64-bit, as seen in `arch/mips/net/bpf_jit_comp64.c`, hardware division/modulo instructions are used. So yes, `jit_smod64` is needed for 32-bit emulation of 64-bit signed modulo. All right, that covers it. Let's call `set-results`. |
| 14/2 | 2026/07/31 01:33 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"BPF_JIT"
],
"FocusSymbols": [
"bpf_int_jit_compile",
"build_insn",
"jit_smod64",
"emit_alu_r"
],
"Reasoning": "The patch adds support for signed division and modulo operations in the MIPS BPF JIT compiler. It modifies the MIPS micro-assembler to support signed div/mod instructions and updates the BPF JIT compiler to use them when translating BPF_DIV and BPF_MOD instructions with the signed flag. This is a functional change to reachable core kernel logic (BPF JIT) and should be fuzzed.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"BPF_JIT"
],
"FocusSymbols": [
"bpf_int_jit_compile",
"build_insn",
"jit_smod64",
"emit_alu_r"
],
"Reasoning": "The patch adds support for signed division and modulo operations in the MIPS BPF JIT compiler. It modifies the MIPS micro-assembler to support signed div/mod instructions and updates the BPF JIT compiler to use them when translating BPF_DIV and BPF_MOD instructions with the signed flag. This is a functional change to reachable core kernel logic (BPF JIT) and should be fuzzed.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|