AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/30 04:50 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_int_jit_compile",
    "bpf_jit_needs_zext"
  ],
  "Reasoning": "The patch introduces a new BPF JIT compiler for the m68k architecture. The code is reachable during BPF program loading when JIT is enabled, and can be tested in QEMU.",
  "WorthFuzzing": true
}

1/1 2026/07/30 04:50 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 3c70cb6d38777d5f518f52f83411e4eabdf4d7d0\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Thu Jul 30 04:50:06 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/MAINTAINERS b/MAINTAINERS\nindex 2fb1c75afd163..530551834c163 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -4701,6 +4701,12 @@ L:\tbpf@vger.kernel.org\n S:\tMaintained\n F:\tarch/loongarch/net/\n \n+BPF JIT for M68K\n+M:\tKuan-Wei Chiu \u003cvisitorckw@gmail.com\u003e\n+L:\tbpf@vger.kernel.org\n+S:\tMaintained\n+F:\tarch/m68k/net/\n+\n BPF JIT for MIPS (32-BIT AND 64-BIT)\n M:\tJohan Almbladh \u003cjohan.almbladh@anyfinetworks.com\u003e\n M:\tPaul Burton \u003cpaulburton@kernel.org\u003e\ndiff --git a/arch/m68k/Kbuild b/arch/m68k/Kbuild\nindex 7762af9f6defe..058ad41a728c5 100644\n--- a/arch/m68k/Kbuild\n+++ b/arch/m68k/Kbuild\n@@ -1,5 +1,5 @@\n # SPDX-License-Identifier: GPL-2.0-only\n-obj-y\t\t\t\t+= kernel/ mm/\n+obj-y\t\t\t\t+= kernel/ mm/ net/\n obj-$(CONFIG_Q40)\t\t+= q40/\n obj-$(CONFIG_AMIGA)\t\t+= amiga/\n obj-$(CONFIG_ATARI)\t\t+= atari/\ndiff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig\nindex 11835eb59d94d..da43d6660c5ce 100644\n--- a/arch/m68k/Kconfig\n+++ b/arch/m68k/Kconfig\n@@ -8,6 +8,7 @@ config M68K\n \tselect ARCH_HAS_CPU_FINALIZE_INIT if MMU\n \tselect ARCH_HAS_CURRENT_STACK_POINTER\n \tselect ARCH_HAS_DMA_PREP_COHERENT if M68K_NONCOHERENT_DMA \u0026\u0026 !COLDFIRE\n+\tselect HAVE_EBPF_JIT if (!COLDFIRE \u0026\u0026 !M68000)\n \tselect ARCH_HAS_SYNC_DMA_FOR_DEVICE if M68K_NONCOHERENT_DMA\n \tselect ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS\n \tselect ARCH_MIGHT_HAVE_PC_PARPORT if ISA\ndiff --git a/arch/m68k/net/Makefile b/arch/m68k/net/Makefile\nnew file mode 100644\nindex 0000000000000..ec5b147633167\n--- /dev/null\n+++ b/arch/m68k/net/Makefile\n@@ -0,0 +1,2 @@\n+# SPDX-License-Identifier: GPL-2.0-only\n+obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o\ndiff --git a/arch/m68k/net/bpf_jit_comp.c b/arch/m68k/net/bpf_jit_comp.c\nnew file mode 100644\nindex 0000000000000..6d647bba96eb4\n--- /dev/null\n+++ b/arch/m68k/net/bpf_jit_comp.c\n@@ -0,0 +1,1630 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * BPF JIT compiler for m68k\n+ *\n+ * Copyright (C) 2026 Kuan-Wei Chiu \u003cvisitorckw@gmail.com\u003e\n+ */\n+\n+#include \u003clinux/bpf.h\u003e\n+#include \u003clinux/filter.h\u003e\n+#include \u003clinux/irqflags.h\u003e\n+#include \u003clinux/slab.h\u003e\n+#include \u003casm/cacheflush.h\u003e\n+#include \u003clinux/math64.h\u003e\n+#include \u003clinux/limits.h\u003e\n+\n+#define STACK_OFFSET(k) (-4 - (4 * (k)))\n+\n+enum {\n+\tBPF_R1_HI, BPF_R1_LO,\n+\tBPF_R2_HI, BPF_R2_LO,\n+\tBPF_R3_HI, BPF_R3_LO,\n+\tBPF_R4_HI, BPF_R4_LO,\n+\tBPF_R5_HI, BPF_R5_LO,\n+\tBPF_R6_HI, BPF_R6_LO,\n+\tBPF_R7_HI, BPF_R7_LO,\n+\tBPF_R8_HI, BPF_R8_LO,\n+\tBPF_R9_HI, BPF_R9_LO,\n+\tBPF_R10_HI, BPF_R10_LO,\n+\tBPF_AX_HI, BPF_AX_LO,\n+\tBPF_TC_HI, BPF_TC_LO,\n+\tBPF_JIT_SCRATCH_REGS,\n+};\n+\n+#define SCRATCH_SIZE (BPF_JIT_SCRATCH_REGS * 4)\n+\n+#define TMP_REG_1 14\n+#define TMP_REG_2 15\n+\n+#define M68K_D0 0\n+#define M68K_D1 1\n+#define M68K_D2 2\n+#define M68K_D3 3\n+#define M68K_D4 4\n+#define M68K_D5 5\n+\n+static const s8 bpf2m68k[16][2] = {\n+\t[BPF_REG_0]  = {M68K_D1, M68K_D0},\n+\t[BPF_REG_1]  = {STACK_OFFSET(BPF_R1_HI),  STACK_OFFSET(BPF_R1_LO)},\n+\t[BPF_REG_2]  = {STACK_OFFSET(BPF_R2_HI),  STACK_OFFSET(BPF_R2_LO)},\n+\t[BPF_REG_3]  = {STACK_OFFSET(BPF_R3_HI),  STACK_OFFSET(BPF_R3_LO)},\n+\t[BPF_REG_4]  = {STACK_OFFSET(BPF_R4_HI),  STACK_OFFSET(BPF_R4_LO)},\n+\t[BPF_REG_5]  = {STACK_OFFSET(BPF_R5_HI),  STACK_OFFSET(BPF_R5_LO)},\n+\t[BPF_REG_6]  = {STACK_OFFSET(BPF_R6_HI),  STACK_OFFSET(BPF_R6_LO)},\n+\t[BPF_REG_7]  = {STACK_OFFSET(BPF_R7_HI),  STACK_OFFSET(BPF_R7_LO)},\n+\t[BPF_REG_8]  = {STACK_OFFSET(BPF_R8_HI),  STACK_OFFSET(BPF_R8_LO)},\n+\t[BPF_REG_9]  = {STACK_OFFSET(BPF_R9_HI),  STACK_OFFSET(BPF_R9_LO)},\n+\t[BPF_REG_10] = {STACK_OFFSET(BPF_R10_HI), STACK_OFFSET(BPF_R10_LO)},\n+\t[BPF_REG_AX] = {STACK_OFFSET(BPF_AX_HI),  STACK_OFFSET(BPF_AX_LO)},\n+\t[TMP_REG_1]  = {M68K_D3, M68K_D2},\n+\t[TMP_REG_2]  = {M68K_D5, M68K_D4},\n+};\n+\n+struct jit_ctx {\n+\tconst struct bpf_prog *prog;\n+\tu16 *target;\n+\tunsigned int idx;\n+\tint *offsets;\n+};\n+\n+static noinline u32 jit_mul32(u32 a, u32 b)\n+{\n+\treturn a * b;\n+}\n+\n+static noinline u32 jit_div32(u32 a, u32 b)\n+{\n+\treturn b ? a / b : 0;\n+}\n+\n+static noinline u32 jit_mod32(u32 a, u32 b)\n+{\n+\treturn b ? a % b : a;\n+}\n+\n+static noinline s32 jit_sdiv32(s32 a, s32 b)\n+{\n+\tif (b == 0)\n+\t\treturn 0;\n+\tif (a == S32_MIN \u0026\u0026 b == -1)\n+\t\treturn S32_MIN;\n+\treturn a / b;\n+}\n+\n+static noinline s32 jit_smod32(s32 a, s32 b)\n+{\n+\tif (b == 0)\n+\t\treturn a;\n+\tif (a == S32_MIN \u0026\u0026 b == -1)\n+\t\treturn 0;\n+\treturn a % b;\n+}\n+\n+static noinline u64 jit_mul64(u64 a, u64 b)\n+{\n+\treturn a * b;\n+}\n+\n+static noinline u64 jit_div64(u64 a, u64 b)\n+{\n+\treturn b ? div64_u64(a, b) : 0;\n+}\n+\n+static noinline s64 jit_sdiv64(s64 a, s64 b)\n+{\n+\tif (b == 0)\n+\t\treturn 0;\n+\tif (a == S64_MIN \u0026\u0026 b == -1)\n+\t\treturn S64_MIN;\n+\treturn div64_s64(a, b);\n+}\n+\n+static noinline u64 jit_mod64(u64 a, u64 b)\n+{\n+\tu64 rem;\n+\n+\tif (b == 0)\n+\t\treturn a;\n+\tdiv64_u64_rem(a, b, \u0026rem);\n+\treturn rem;\n+}\n+\n+static noinline s64 jit_smod64(s64 a, s64 b)\n+{\n+\tif (b == 0)\n+\t\treturn a;\n+\tif (a == S64_MIN \u0026\u0026 b == -1)\n+\t\treturn 0;\n+\treturn a - div64_s64(a, b) * b;\n+}\n+\n+static u32 jit_atomic32(u32 *ptr, u32 val, u32 op, u32 cmp)\n+{\n+\tunsigned long flags;\n+\tu32 old;\n+\n+\tlocal_irq_save(flags);\n+\told = *ptr;\n+\tswitch (op) {\n+\tcase BPF_ADD:\n+\tcase BPF_ADD | BPF_FETCH:\n+\t\t*ptr += val;\n+\t\tbreak;\n+\tcase BPF_AND:\n+\tcase BPF_AND | BPF_FETCH:\n+\t\t*ptr \u0026= val;\n+\t\tbreak;\n+\tcase BPF_OR:\n+\tcase BPF_OR | BPF_FETCH:\n+\t\t*ptr |= val;\n+\t\tbreak;\n+\tcase BPF_XOR:\n+\tcase BPF_XOR | BPF_FETCH:\n+\t\t*ptr ^= val;\n+\t\tbreak;\n+\tcase BPF_XCHG:\n+\t\t*ptr = val;\n+\t\tbreak;\n+\tcase BPF_CMPXCHG:\n+\t\tif (old == cmp)\n+\t\t\t*ptr = val;\n+\t\tbreak;\n+\t}\n+\tlocal_irq_restore(flags);\n+\n+\treturn old;\n+}\n+\n+static u64 jit_atomic64(u32 *ptr, u32 val_hi, u32 val_lo, u32 op, u32 cmp_hi, u32 cmp_lo)\n+{\n+\tunsigned long flags;\n+\tu64 old, val, cmp;\n+\tu64 *ptr64 = (u64 *)ptr;\n+\n+\tval = ((u64)val_hi \u003c\u003c 32) | val_lo;\n+\tcmp = ((u64)cmp_hi \u003c\u003c 32) | cmp_lo;\n+\n+\tlocal_irq_save(flags);\n+\told = *ptr64;\n+\tswitch (op) {\n+\tcase BPF_ADD:\n+\tcase BPF_ADD | BPF_FETCH:\n+\t\t*ptr64 += val;\n+\t\tbreak;\n+\tcase BPF_AND:\n+\tcase BPF_AND | BPF_FETCH:\n+\t\t*ptr64 \u0026= val;\n+\t\tbreak;\n+\tcase BPF_OR:\n+\tcase BPF_OR | BPF_FETCH:\n+\t\t*ptr64 |= val;\n+\t\tbreak;\n+\tcase BPF_XOR:\n+\tcase BPF_XOR | BPF_FETCH:\n+\t\t*ptr64 ^= val;\n+\t\tbreak;\n+\tcase BPF_XCHG:\n+\t\t*ptr64 = val;\n+\t\tbreak;\n+\tcase BPF_CMPXCHG:\n+\t\tif (old == cmp)\n+\t\t\t*ptr64 = val;\n+\t\tbreak;\n+\t}\n+\tlocal_irq_restore(flags);\n+\n+\treturn old;\n+}\n+\n+static inline void emit_16(struct jit_ctx *ctx, u16 inst)\n+{\n+\tif (ctx-\u003etarget)\n+\t\tctx-\u003etarget[ctx-\u003eidx] = inst;\n+\tctx-\u003eidx++;\n+}\n+\n+static inline void emit_32(struct jit_ctx *ctx, u32 val)\n+{\n+\temit_16(ctx, val \u003e\u003e 16);\n+\temit_16(ctx, val \u0026 0xffff);\n+}\n+\n+static inline bool is_stacked(s8 reg)\n+{\n+\treturn reg \u003c 0;\n+}\n+\n+static s8 bpf_get_reg32(s8 bpf_reg, s8 tmp_reg, struct jit_ctx *ctx)\n+{\n+\tif (is_stacked(bpf_reg)) {\n+\t\temit_16(ctx, 0x202e | (tmp_reg \u003c\u003c 9));\t\t/* move.l d16(%fp), reg */\n+\t\temit_16(ctx, (u16)bpf_reg);\n+\t\treturn tmp_reg;\n+\t}\n+\treturn bpf_reg;\n+}\n+\n+static void bpf_put_reg32(s8 bpf_reg, s8 src_reg, struct jit_ctx *ctx)\n+{\n+\tif (is_stacked(bpf_reg)) {\n+\t\temit_16(ctx, 0x2d40 | src_reg);\t\t\t/* move.l reg, d16(%fp) */\n+\t\temit_16(ctx, (u16)bpf_reg);\n+\t} else if (bpf_reg != src_reg) {\n+\t\temit_16(ctx, 0x2000 | (bpf_reg \u003c\u003c 9) | src_reg); /* move.l src, dst */\n+\t}\n+}\n+\n+static void emit_alu32_neg(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\ts8 d_reg = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\n+\temit_16(ctx, 0x4480 | d_reg);\t\t\t\t/* neg.l d_reg */\n+\n+\tbpf_put_reg32(dst[1], d_reg, ctx);\n+\temit_16(ctx, 0x7000 | (tmp1[0] \u003c\u003c 9));\t\t\t/* moveq #0, tmp1 */\n+\tbpf_put_reg32(dst[0], tmp1[0], ctx);\n+}\n+\n+static void emit_alu64_neg(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\ts8 d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\ts8 d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\n+\temit_16(ctx, 0x4480 | d_lo);\t\t\t\t/* neg.l d_lo */\n+\temit_16(ctx, 0x4080 | d_hi);\t\t\t\t/* negx.l d_hi */\n+\n+\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\tbpf_put_reg32(dst[0], d_hi, ctx);\n+}\n+\n+static void emit_alu32_x(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_reg, s_reg;\n+\n+\td_reg = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\ts_reg = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\n+\tswitch (BPF_OP(insn-\u003ecode)) {\n+\tcase BPF_MOV:\n+\t\tif (insn-\u003eoff == 8 || insn-\u003eoff == 16) {\n+\t\t\tif (d_reg != s_reg)\n+\t\t\t\temit_16(ctx, 0x2000 | (d_reg \u003c\u003c 9) | s_reg); /* move.l src, dst */\n+\t\t\tif (insn-\u003eoff == 8)\n+\t\t\t\temit_16(ctx, 0x49c0 | d_reg);\t/* extb.l d_reg */\n+\t\t\telse\n+\t\t\t\temit_16(ctx, 0x48c0 | d_reg);\t/* ext.l d_reg */\n+\t\t} else {\n+\t\t\tif (d_reg != s_reg)\n+\t\t\t\temit_16(ctx, 0x2000 | (d_reg \u003c\u003c 9) | s_reg); /* move.l src, dst */\n+\t\t}\n+\t\tbreak;\n+\tcase BPF_ADD:\n+\t\temit_16(ctx, 0xd080 | (d_reg \u003c\u003c 9) | s_reg);\t/* add.l src, dst */\n+\t\tbreak;\n+\tcase BPF_SUB:\n+\t\temit_16(ctx, 0x9080 | (d_reg \u003c\u003c 9) | s_reg);\t/* sub.l src, dst */\n+\t\tbreak;\n+\tcase BPF_AND:\n+\t\temit_16(ctx, 0xc080 | (d_reg \u003c\u003c 9) | s_reg);\t/* and.l src, dst */\n+\t\tbreak;\n+\tcase BPF_OR:\n+\t\temit_16(ctx, 0x8080 | (d_reg \u003c\u003c 9) | s_reg);\t/* or.l src, dst */\n+\t\tbreak;\n+\tcase BPF_XOR:\n+\t\temit_16(ctx, 0xb180 | (s_reg \u003c\u003c 9) | d_reg);\t/* eor.l src, dst */\n+\t\tbreak;\n+\tcase BPF_LSH:\n+\tcase BPF_RSH:\n+\tcase BPF_ARSH: {\n+\t\ts8 count_reg = tmp2[1];\n+\n+\t\tif (s_reg != count_reg)\n+\t\t\temit_16(ctx, 0x2000 | (count_reg \u003c\u003c 9) | s_reg); /* move.l src, count */\n+\n+\t\temit_16(ctx, 0x0280 | count_reg);\t\t/* andi.l #imm, count */\n+\t\temit_32(ctx, 0x1f);\n+\n+\t\tif (BPF_OP(insn-\u003ecode) == BPF_LSH)\n+\t\t\temit_16(ctx, 0xe1a8 | (count_reg \u003c\u003c 9) | d_reg); /* lsl.l count, dst */\n+\t\telse if (BPF_OP(insn-\u003ecode) == BPF_RSH)\n+\t\t\temit_16(ctx, 0xe0a8 | (count_reg \u003c\u003c 9) | d_reg); /* lsr.l count, dst */\n+\t\telse\n+\t\t\temit_16(ctx, 0xe0a0 | (count_reg \u003c\u003c 9) | d_reg); /* asr.l count, dst */\n+\t\tbreak;\n+\t}\n+\t}\n+\n+\tbpf_put_reg32(dst[1], d_reg, ctx);\n+\temit_16(ctx, 0x7000 | (tmp1[0] \u003c\u003c 9));\t\t\t/* moveq #0, tmp1 */\n+\tbpf_put_reg32(dst[0], tmp1[0], ctx);\n+}\n+\n+static void emit_alu32_k(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_reg;\n+\n+\td_reg = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\n+\tswitch (BPF_OP(insn-\u003ecode)) {\n+\tcase BPF_MOV:\n+\t\temit_16(ctx, 0x203c | (d_reg \u003c\u003c 9));\t\t/* move.l #imm, dst */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tbreak;\n+\tcase BPF_ADD:\n+\t\temit_16(ctx, 0x0680 | d_reg);\t\t\t/* addi.l #imm, dst */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tbreak;\n+\tcase BPF_SUB:\n+\t\temit_16(ctx, 0x0480 | d_reg);\t\t\t/* subi.l #imm, dst */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tbreak;\n+\tcase BPF_AND:\n+\t\temit_16(ctx, 0x0280 | d_reg);\t\t\t/* andi.l #imm, dst */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tbreak;\n+\tcase BPF_OR:\n+\t\temit_16(ctx, 0x0080 | d_reg);\t\t\t/* ori.l #imm, dst */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tbreak;\n+\tcase BPF_XOR:\n+\t\temit_16(ctx, 0x0a80 | d_reg);\t\t\t/* eori.l #imm, dst */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tbreak;\n+\tcase BPF_LSH:\n+\tcase BPF_RSH:\n+\tcase BPF_ARSH:\n+\t\temit_16(ctx, 0x203c | (tmp2[1] \u003c\u003c 9));\t\t/* move.l #imm, count */\n+\t\temit_32(ctx, insn-\u003eimm \u0026 0x1f);\n+\n+\t\tif (BPF_OP(insn-\u003ecode) == BPF_LSH)\n+\t\t\temit_16(ctx, 0xe1a8 | (tmp2[1] \u003c\u003c 9) | d_reg);\t/* lsl.l count, dst */\n+\t\telse if (BPF_OP(insn-\u003ecode) == BPF_RSH)\n+\t\t\temit_16(ctx, 0xe0a8 | (tmp2[1] \u003c\u003c 9) | d_reg);\t/* lsr.l count, dst */\n+\t\telse\n+\t\t\temit_16(ctx, 0xe0a0 | (tmp2[1] \u003c\u003c 9) | d_reg);\t/* asr.l count, dst */\n+\t\tbreak;\n+\t}\n+\n+\tbpf_put_reg32(dst[1], d_reg, ctx);\n+\temit_16(ctx, 0x7000 | (tmp1[0] \u003c\u003c 9));\t\t\t/* moveq #0, tmp1 */\n+\tbpf_put_reg32(dst[0], tmp1[0], ctx);\n+}\n+\n+static void emit_alu64_x(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_lo, d_hi, s_lo, s_hi;\n+\n+\td_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\td_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\ts_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\ts_hi = bpf_get_reg32(src[0], tmp2[0], ctx);\n+\n+\tswitch (BPF_OP(insn-\u003ecode)) {\n+\tcase BPF_MOV:\n+\t\tif (insn-\u003eoff == 8 || insn-\u003eoff == 16 || insn-\u003eoff == 32) {\n+\t\t\tif (d_lo != s_lo)\n+\t\t\t\temit_16(ctx, 0x2000 | (d_lo \u003c\u003c 9) | s_lo); /* move.l src, dst */\n+\n+\t\t\tif (insn-\u003eoff == 8)\n+\t\t\t\temit_16(ctx, 0x49c0 | d_lo);\t\t/* extb.l d_lo */\n+\t\t\telse if (insn-\u003eoff == 16)\n+\t\t\t\temit_16(ctx, 0x48c0 | d_lo);\t\t/* ext.l d_lo */\n+\n+\t\t\temit_16(ctx, 0x4a80 | d_lo);\t\t\t/* tst.l d_lo */\n+\t\t\temit_16(ctx, 0x5bc0 | d_hi);\t\t\t/* smi d_hi */\n+\t\t\temit_16(ctx, 0x49c0 | d_hi);\t\t\t/* extb.l d_hi */\n+\t\t} else {\n+\t\t\tif (d_lo != s_lo)\n+\t\t\t\temit_16(ctx, 0x2000 | (d_lo \u003c\u003c 9) | s_lo); /* move.l s_lo, d_lo */\n+\t\t\tif (d_hi != s_hi)\n+\t\t\t\temit_16(ctx, 0x2000 | (d_hi \u003c\u003c 9) | s_hi); /* move.l s_hi, d_hi */\n+\t\t}\n+\t\tbreak;\n+\tcase BPF_ADD:\n+\t\temit_16(ctx, 0xd080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* add.l s_lo, d_lo */\n+\t\temit_16(ctx, 0xd180 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* addx.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_SUB:\n+\t\temit_16(ctx, 0x9080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* sub.l s_lo, d_lo */\n+\t\temit_16(ctx, 0x9180 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* subx.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_AND:\n+\t\temit_16(ctx, 0xc080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* and.l s_lo, d_lo */\n+\t\temit_16(ctx, 0xc080 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* and.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_OR:\n+\t\temit_16(ctx, 0x8080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* or.l s_lo, d_lo */\n+\t\temit_16(ctx, 0x8080 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* or.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_XOR:\n+\t\temit_16(ctx, 0xb180 | (s_lo \u003c\u003c 9) | d_lo);\t\t/* eor.l s_lo, d_lo */\n+\t\temit_16(ctx, 0xb180 | (s_hi \u003c\u003c 9) | d_hi);\t\t/* eor.l s_hi, d_hi */\n+\t\tbreak;\n+\t}\n+\n+\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\tbpf_put_reg32(dst[0], d_hi, ctx);\n+}\n+\n+static void emit_alu64_k(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_lo, d_hi, s_lo, s_hi;\n+\tu32 imm_lo = insn-\u003eimm;\n+\tu32 imm_hi = insn-\u003eimm \u003c 0 ? 0xffffffff : 0;\n+\n+\td_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\td_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\n+\tif (BPF_OP(insn-\u003ecode) == BPF_MOV) {\n+\t\temit_16(ctx, 0x203c | (d_lo \u003c\u003c 9));\t\t\t/* move.l #imm, d_lo */\n+\t\temit_32(ctx, imm_lo);\n+\t\temit_16(ctx, 0x203c | (d_hi \u003c\u003c 9));\t\t\t/* move.l #imm, d_hi */\n+\t\temit_32(ctx, imm_hi);\n+\t\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\t\tbpf_put_reg32(dst[0], d_hi, ctx);\n+\t\treturn;\n+\t}\n+\n+\ts_lo = tmp2[1];\n+\ts_hi = tmp2[0];\n+\n+\temit_16(ctx, 0x203c | (s_lo \u003c\u003c 9));\t\t\t\t/* move.l #imm, s_lo */\n+\temit_32(ctx, imm_lo);\n+\temit_16(ctx, 0x203c | (s_hi \u003c\u003c 9));\t\t\t\t/* move.l #imm, s_hi */\n+\temit_32(ctx, imm_hi);\n+\n+\tswitch (BPF_OP(insn-\u003ecode)) {\n+\tcase BPF_ADD:\n+\t\temit_16(ctx, 0xd080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* add.l s_lo, d_lo */\n+\t\temit_16(ctx, 0xd180 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* addx.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_SUB:\n+\t\temit_16(ctx, 0x9080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* sub.l s_lo, d_lo */\n+\t\temit_16(ctx, 0x9180 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* subx.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_AND:\n+\t\temit_16(ctx, 0xc080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* and.l s_lo, d_lo */\n+\t\temit_16(ctx, 0xc080 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* and.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_OR:\n+\t\temit_16(ctx, 0x8080 | (d_lo \u003c\u003c 9) | s_lo);\t\t/* or.l s_lo, d_lo */\n+\t\temit_16(ctx, 0x8080 | (d_hi \u003c\u003c 9) | s_hi);\t\t/* or.l s_hi, d_hi */\n+\t\tbreak;\n+\tcase BPF_XOR:\n+\t\temit_16(ctx, 0xb180 | (s_lo \u003c\u003c 9) | d_lo);\t\t/* eor.l s_lo, d_lo */\n+\t\temit_16(ctx, 0xb180 | (s_hi \u003c\u003c 9) | d_hi);\t\t/* eor.l s_hi, d_hi */\n+\t\tbreak;\n+\t}\n+\n+\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\tbpf_put_reg32(dst[0], d_hi, ctx);\n+}\n+\n+static void emit_alu64_shift(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_imm)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_lo, d_hi, count_reg;\n+\tint loop_start, done_idx;\n+\n+\td_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\td_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\tcount_reg = tmp2[1];\n+\n+\tif (is_imm) {\n+\t\temit_16(ctx, 0x203c | (count_reg \u003c\u003c 9));\t\t/* move.l #imm, count_reg */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t} else {\n+\t\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\t\ts8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\n+\t\tif (count_reg != s_lo)\n+\t\t\temit_16(ctx, 0x2000 | (count_reg \u003c\u003c 9) | s_lo);\t/* move.l s_lo, count_reg */\n+\t}\n+\n+\temit_16(ctx, 0x0280 | count_reg);\t\t\t/* andi.l #0x3f, count_reg */\n+\temit_32(ctx, 0x3f);\n+\n+\temit_16(ctx, 0x4a80 | count_reg);\t\t\t\t/* tst.l count_reg */\n+\temit_16(ctx, 0x6700);\t\t\t\t\t\t/* beq.w done_idx */\n+\tdone_idx = ctx-\u003eidx;\n+\temit_16(ctx, 0);\n+\n+\tloop_start = ctx-\u003eidx;\n+\n+\tif (BPF_OP(insn-\u003ecode) == BPF_LSH) {\n+\t\temit_16(ctx, 0xe388 | d_lo);\t\t\t\t/* lsll #1, d_lo */\n+\t\temit_16(ctx, 0xe390 | d_hi);\t\t\t\t/* roxl.l #1, d_hi */\n+\t} else if (BPF_OP(insn-\u003ecode) == BPF_RSH) {\n+\t\temit_16(ctx, 0xe288 | d_hi);\t\t\t\t/* lsrl #1, d_hi */\n+\t\temit_16(ctx, 0xe290 | d_lo);\t\t\t\t/* roxr.l #1, d_lo */\n+\t} else if (BPF_OP(insn-\u003ecode) == BPF_ARSH) {\n+\t\temit_16(ctx, 0xe280 | d_hi);\t\t\t\t/* asrl #1, d_hi */\n+\t\temit_16(ctx, 0xe290 | d_lo);\t\t\t\t/* roxr.l #1, d_lo */\n+\t}\n+\n+\temit_16(ctx, 0x5380 | count_reg);\t\t\t\t/* subq.l #1, count_reg */\n+\temit_16(ctx, 0x6600);\t\t\t\t\t\t/* bne.w loop_start */\n+\temit_16(ctx, (loop_start - (int)ctx-\u003eidx) * 2);\n+\n+\tif (ctx-\u003etarget)\n+\t\tctx-\u003etarget[done_idx] = (ctx-\u003eidx - done_idx) * 2;\n+\n+\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\tbpf_put_reg32(dst[0], d_hi, ctx);\n+}\n+\n+static void emit_bpf_end(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\ts8 d_lo, d_hi;\n+\tbool to_le = BPF_SRC(insn-\u003ecode) == BPF_TO_LE;\n+\tint imm = insn-\u003eimm;\n+\n+\td_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\td_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\n+\tif (to_le) {\n+\t\tswitch (imm) {\n+\t\tcase 16:\n+\t\t\temit_16(ctx, 0x0280 | d_lo);\t\t\t/* andi.l #0xffff, d_lo */\n+\t\t\temit_32(ctx, 0xffff);\n+\t\t\temit_16(ctx, 0xe058 | d_lo);\t\t\t/* ror.w #8, d_lo */\n+\t\t\temit_16(ctx, 0x7000 | (d_hi \u003c\u003c 9));\t\t/* moveq #0, d_hi */\n+\t\t\tbreak;\n+\t\tcase 32:\n+\t\t\temit_16(ctx, 0xe058 | d_lo);\t\t\t/* ror.w #8, d_lo */\n+\t\t\temit_16(ctx, 0x4840 | d_lo);\t\t\t/* swap d_lo */\n+\t\t\temit_16(ctx, 0xe058 | d_lo);\t\t\t/* ror.w #8, d_lo */\n+\t\t\temit_16(ctx, 0x7000 | (d_hi \u003c\u003c 9));\t\t/* moveq #0, d_hi */\n+\t\t\tbreak;\n+\t\tcase 64:\n+\t\t\temit_16(ctx, 0xe058 | d_lo);\t\t\t/* ror.w #8, d_lo */\n+\t\t\temit_16(ctx, 0x4840 | d_lo);\t\t\t/* swap d_lo */\n+\t\t\temit_16(ctx, 0xe058 | d_lo);\t\t\t/* ror.w #8, d_lo */\n+\n+\t\t\temit_16(ctx, 0xe058 | d_hi);\t\t\t/* ror.w #8, d_hi */\n+\t\t\temit_16(ctx, 0x4840 | d_hi);\t\t\t/* swap d_hi */\n+\t\t\temit_16(ctx, 0xe058 | d_hi);\t\t\t/* ror.w #8, d_hi */\n+\n+\t\t\temit_16(ctx, 0xc140 | (d_hi \u003c\u003c 9) | d_lo);\t/* exg d_lo, d_hi */\n+\t\t\tbreak;\n+\t\t}\n+\t} else {\n+\t\tswitch (imm) {\n+\t\tcase 16:\n+\t\t\temit_16(ctx, 0x0280 | d_lo);\t\t\t/* andi.l #0xffff, d_lo */\n+\t\t\temit_32(ctx, 0xffff);\n+\t\t\temit_16(ctx, 0x7000 | (d_hi \u003c\u003c 9));\t\t/* moveq #0, d_hi */\n+\t\t\tbreak;\n+\t\tcase 32:\n+\t\t\temit_16(ctx, 0x7000 | (d_hi \u003c\u003c 9));\t\t/* moveq #0, d_hi */\n+\t\t\tbreak;\n+\t\tcase 64:\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\tbpf_put_reg32(dst[0], d_hi, ctx);\n+}\n+\n+static void emit_math_call(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_64)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_lo, d_hi, s_lo, s_hi = 0;\n+\tvoid *func = NULL;\n+\tu8 op = BPF_OP(insn-\u003ecode);\n+\n+\td_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\td_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\n+\tif (BPF_SRC(insn-\u003ecode) == BPF_X) {\n+\t\ts_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\t\tif (is_64)\n+\t\t\ts_hi = bpf_get_reg32(src[0], tmp2[0], ctx);\n+\t} else {\n+\t\ts_lo = tmp2[1];\n+\t\temit_16(ctx, 0x203c | (s_lo \u003c\u003c 9));\t\t\t/* move.l #imm, s_lo */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tif (is_64) {\n+\t\t\ts_hi = tmp2[0];\n+\t\t\temit_16(ctx, 0x203c | (s_hi \u003c\u003c 9));\t\t/* move.l #imm, s_hi */\n+\t\t\temit_32(ctx, insn-\u003eimm \u003c 0 ? 0xffffffff : 0);\n+\t\t}\n+\t}\n+\n+\tif (is_64) {\n+\t\tswitch (op) {\n+\t\tcase BPF_MUL:\n+\t\t\tfunc = (void *)jit_mul64;\n+\t\t\tbreak;\n+\t\tcase BPF_DIV:\n+\t\t\tfunc = (void *)jit_div64;\n+\t\t\tbreak;\n+\t\tcase BPF_MOD:\n+\t\t\tfunc = (void *)jit_mod64;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (BPF_CLASS(insn-\u003ecode) == BPF_ALU64 \u0026\u0026 op == BPF_DIV \u0026\u0026 insn-\u003eoff == 1)\n+\t\t\tfunc = (void *)jit_sdiv64;\n+\t\tif (BPF_CLASS(insn-\u003ecode) == BPF_ALU64 \u0026\u0026 op == BPF_MOD \u0026\u0026 insn-\u003eoff == 1)\n+\t\t\tfunc = (void *)jit_smod64;\n+\t} else {\n+\t\tswitch (op) {\n+\t\tcase BPF_MUL:\n+\t\t\tfunc = (void *)jit_mul32;\n+\t\t\tbreak;\n+\t\tcase BPF_DIV:\n+\t\t\tfunc = (void *)jit_div32;\n+\t\t\tbreak;\n+\t\tcase BPF_MOD:\n+\t\t\tfunc = (void *)jit_mod32;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (BPF_CLASS(insn-\u003ecode) == BPF_ALU \u0026\u0026 op == BPF_DIV \u0026\u0026 insn-\u003eoff == 1)\n+\t\t\tfunc = (void *)jit_sdiv32;\n+\t\tif (BPF_CLASS(insn-\u003ecode) == BPF_ALU \u0026\u0026 op == BPF_MOD \u0026\u0026 insn-\u003eoff == 1)\n+\t\t\tfunc = (void *)jit_smod32;\n+\t}\n+\n+\tif (is_64) {\n+\t\temit_16(ctx, 0x48e7);\t\t\t\t\t/* movem.l d0-d1, -(%sp) */\n+\t\temit_16(ctx, 0xc000);\n+\n+\t\temit_16(ctx, 0x2f00 | s_lo);\t\t\t\t/* move.l s_lo, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | s_hi);\t\t\t\t/* move.l s_hi, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | d_lo);\t\t\t\t/* move.l d_lo, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | d_hi);\t\t\t\t/* move.l d_hi, -(%sp) */\n+\n+\t\temit_16(ctx, 0x207c);\t\t\t\t\t/* movea.l #func, %a0 */\n+\t\temit_32(ctx, (u32)func);\n+\t\temit_16(ctx, 0x4e90);\t\t\t\t\t/* jsr (%a0) */\n+\n+\t\temit_16(ctx, 0x4fef);\t\t\t\t\t/* lea 16(%sp), %sp */\n+\t\temit_16(ctx, 16);\n+\n+\t\temit_16(ctx, 0x2601);\t\t\t\t\t/* move.l %d1, %d3 */\n+\t\temit_16(ctx, 0x2400);\t\t\t\t\t/* move.l %d0, %d2 */\n+\n+\t\temit_16(ctx, 0x4cdf);\t\t\t\t\t/* movem.l (%sp)+, d0-d1 */\n+\t\temit_16(ctx, 0x0003);\n+\t} else {\n+\t\temit_16(ctx, 0x48e7);\t\t\t\t\t/* movem.l d0-d1, -(%sp) */\n+\t\temit_16(ctx, 0xc000);\n+\n+\t\temit_16(ctx, 0x2f00 | s_lo);\t\t\t\t/* move.l s_lo, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | d_lo);\t\t\t\t/* move.l d_lo, -(%sp) */\n+\n+\t\temit_16(ctx, 0x207c);\t\t\t\t\t/* movea.l #func, %a0 */\n+\t\temit_32(ctx, (u32)func);\n+\t\temit_16(ctx, 0x4e90);\t\t\t\t\t/* jsr (%a0) */\n+\n+\t\temit_16(ctx, 0x4fef);\t\t\t\t\t/* lea 8(%sp), %sp */\n+\t\temit_16(ctx, 8);\n+\n+\t\temit_16(ctx, 0x2600);\t\t\t\t\t/* move.l %d0, %d3 */\n+\t\temit_16(ctx, 0x7400);\t\t\t\t\t/* moveq #0, %d2 */\n+\n+\t\temit_16(ctx, 0x4cdf);\t\t\t\t\t/* movem.l (%sp)+, d0-d1 */\n+\t\temit_16(ctx, 0x0003);\n+\t}\n+\n+\tbpf_put_reg32(dst[1], M68K_D3, ctx);\n+\tbpf_put_reg32(dst[0], M68K_D2, ctx);\n+}\n+\n+static void emit_ldx(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\ts8 d_lo, d_hi;\n+\tbool is_mem_sx = BPF_MODE(insn-\u003ecode) == BPF_MEMSX;\n+\n+\tif (is_stacked(src[1])) {\n+\t\temit_16(ctx, 0x206e);\t\t\t\t/* movea.l d16(%fp), %a0 */\n+\t\temit_16(ctx, (u16)src[1]);\n+\t} else {\n+\t\temit_16(ctx, 0x2040 | src[1]);\t\t\t/* movea.l src, %a0 */\n+\t}\n+\n+\td_lo = is_stacked(dst[1]) ? tmp1[1] : dst[1];\n+\td_hi = is_stacked(dst[0]) ? tmp1[0] : dst[0];\n+\n+\tswitch (BPF_SIZE(insn-\u003ecode)) {\n+\tcase BPF_B:\n+\t\tif (!is_mem_sx)\n+\t\t\temit_16(ctx, 0x7000 | (d_lo \u003c\u003c 9));\t/* moveq #0, d_lo */\n+\t\temit_16(ctx, 0x1028 | (d_lo \u003c\u003c 9));\t\t/* move.b d16(%a0), d_lo */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tif (is_mem_sx)\n+\t\t\temit_16(ctx, 0x49c0 | d_lo);\t/* extb.l d_lo */\n+\t\tbreak;\n+\tcase BPF_H:\n+\t\tif (!is_mem_sx)\n+\t\t\temit_16(ctx, 0x7000 | (d_lo \u003c\u003c 9));\t/* moveq #0, d_lo */\n+\t\temit_16(ctx, 0x3028 | (d_lo \u003c\u003c 9));\t\t/* move.w d16(%a0), d_lo */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tif (is_mem_sx)\n+\t\t\temit_16(ctx, 0x48c0 | d_lo);\t/* ext.l d_lo */\n+\t\tbreak;\n+\tcase BPF_W:\n+\t\temit_16(ctx, 0x2028 | (d_lo \u003c\u003c 9));\t\t/* move.l d16(%a0), d_lo */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_DW:\n+\t\temit_16(ctx, 0x2028 | (d_hi \u003c\u003c 9));\t\t/* move.l d16(%a0), d_hi */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\temit_16(ctx, 0x41e8);\t\t\t\t/* lea 4(%a0), %a0 */\n+\t\temit_16(ctx, 4);\n+\t\temit_16(ctx, 0x2028 | (d_lo \u003c\u003c 9));\t\t/* move.l d16(%a0), d_lo */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\t}\n+\n+\tif (BPF_SIZE(insn-\u003ecode) != BPF_DW) {\n+\t\tif (is_mem_sx) {\n+\t\t\temit_16(ctx, 0x4a80 | d_lo);\t\t\t/* tst.l d_lo */\n+\t\t\temit_16(ctx, 0x5bc0 | d_hi);\t\t\t/* smi d_hi */\n+\t\t\temit_16(ctx, 0x49c0 | d_hi);\t\t\t/* extb.l d_hi */\n+\t\t} else {\n+\t\t\temit_16(ctx, 0x7000 | (d_hi \u003c\u003c 9));\t/* moveq #0, d_hi */\n+\t\t}\n+\t}\n+\n+\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\tbpf_put_reg32(dst[0], d_hi, ctx);\n+}\n+\n+static void emit_stx(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 s_lo, s_hi;\n+\n+\tif (is_stacked(dst[1])) {\n+\t\temit_16(ctx, 0x206e);\t\t\t\t/* movea.l d16(%fp), %a0 */\n+\t\temit_16(ctx, (u16)dst[1]);\n+\t} else {\n+\t\temit_16(ctx, 0x2040 | dst[1]);\t\t\t/* movea.l dst, %a0 */\n+\t}\n+\n+\ts_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\n+\tswitch (BPF_SIZE(insn-\u003ecode)) {\n+\tcase BPF_B:\n+\t\temit_16(ctx, 0x1140 | s_lo);\t\t\t/* move.b s_lo, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_H:\n+\t\temit_16(ctx, 0x3140 | s_lo);\t\t\t/* move.w s_lo, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_W:\n+\t\temit_16(ctx, 0x2140 | s_lo);\t\t\t/* move.l s_lo, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_DW:\n+\t\ts_hi = bpf_get_reg32(src[0], tmp2[0], ctx);\n+\t\temit_16(ctx, 0x2140 | s_hi);\t\t\t/* move.l s_hi, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\temit_16(ctx, 0x41e8);\t\t\t\t/* lea 4(%a0), %a0 */\n+\t\temit_16(ctx, 4);\n+\t\temit_16(ctx, 0x2140 | s_lo);\t\t\t/* move.l s_lo, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\t}\n+}\n+\n+static void emit_st(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *tmp = bpf2m68k[TMP_REG_1];\n+\n+\tif (is_stacked(dst[1])) {\n+\t\temit_16(ctx, 0x206e);\t\t\t\t/* movea.l d16(%fp), %a0 */\n+\t\temit_16(ctx, (u16)dst[1]);\n+\t} else {\n+\t\temit_16(ctx, 0x2040 | dst[1]);\t\t\t/* movea.l dst, %a0 */\n+\t}\n+\n+\temit_16(ctx, 0x203c | (tmp[1] \u003c\u003c 9));\t\t\t/* move.l #imm, tmp */\n+\temit_32(ctx, insn-\u003eimm);\n+\n+\tswitch (BPF_SIZE(insn-\u003ecode)) {\n+\tcase BPF_B:\n+\t\temit_16(ctx, 0x1140 | tmp[1]);\t\t\t/* move.b tmp, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_H:\n+\t\temit_16(ctx, 0x3140 | tmp[1]);\t\t\t/* move.w tmp, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_W:\n+\t\temit_16(ctx, 0x2140 | tmp[1]);\t\t\t/* move.l tmp, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\tcase BPF_DW:\n+\t\temit_16(ctx, 0x203c | (tmp[0] \u003c\u003c 9));\t\t/* move.l #imm, tmp */\n+\t\temit_32(ctx, insn-\u003eimm \u003c 0 ? 0xffffffff : 0);\n+\n+\t\temit_16(ctx, 0x2140 | tmp[0]);\t\t\t/* move.l tmp, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\temit_16(ctx, 0x41e8);\t\t\t\t/* lea 4(%a0), %a0 */\n+\t\temit_16(ctx, 4);\n+\t\temit_16(ctx, 0x2140 | tmp[1]);\t\t\t/* move.l tmp, d16(%a0) */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t\tbreak;\n+\t}\n+}\n+\n+static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\n+\tif (is_stacked(dst[1])) {\n+\t\temit_16(ctx, 0x206e);\t\t\t\t/* movea.l d16(%fp), %a0 */\n+\t\temit_16(ctx, (u16)dst[1]);\n+\t} else {\n+\t\temit_16(ctx, 0x2040 | dst[1]);\t\t\t/* movea.l dst, %a0 */\n+\t}\n+\n+\tif (insn-\u003eoff) {\n+\t\temit_16(ctx, 0x41e8);\t\t\t\t/* lea d16(%a0), %a0 */\n+\t\temit_16(ctx, insn-\u003eoff);\n+\t}\n+\n+\tif (BPF_SIZE(insn-\u003ecode) == BPF_W) {\n+\t\ts8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\n+\t\tif (insn-\u003eimm != BPF_CMPXCHG) {\n+\t\t\temit_16(ctx, 0x48e7);\t\t\t/* movem.l d0-d1, -(%sp) */\n+\t\t\temit_16(ctx, 0xc000);\n+\t\t}\n+\n+\t\temit_16(ctx, 0x2f00 | M68K_D0);\t\t\t/* move.l %d0, -(%sp) */\n+\t\temit_16(ctx, 0x2f3c);\t\t\t\t/* move.l #imm, -(%sp) */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\temit_16(ctx, 0x2f00 | s_lo);\t\t\t/* move.l s_lo, -(%sp) */\n+\t\temit_16(ctx, 0x2f08);\t\t\t\t/* move.l %a0, -(%sp) */\n+\n+\t\temit_16(ctx, 0x207c);\t\t\t\t/* movea.l #func, %a0 */\n+\t\temit_32(ctx, (u32)jit_atomic32);\n+\t\temit_16(ctx, 0x4e90);\t\t\t\t/* jsr (%a0) */\n+\n+\t\temit_16(ctx, 0x4fef);\t\t\t\t/* lea 16(%sp), %sp */\n+\t\temit_16(ctx, 16);\n+\n+\t\tif (insn-\u003eimm == BPF_CMPXCHG) {\n+\t\t\temit_16(ctx, 0x7200);\t\t\t/* moveq #0, %d1 */\n+\t\t} else {\n+\t\t\tbool is_fetch = (insn-\u003eimm \u0026 BPF_FETCH) || insn-\u003eimm == BPF_XCHG;\n+\n+\t\t\tif (is_fetch)\n+\t\t\t\temit_16(ctx, 0x2600);\t\t/* move.l %d0, %d3 */\n+\n+\t\t\temit_16(ctx, 0x4cdf);\t\t\t/* movem.l (%sp)+, d0-d1 */\n+\t\t\temit_16(ctx, 0x0003);\n+\n+\t\t\tif (is_fetch) {\n+\t\t\t\tbpf_put_reg32(src[1], M68K_D3, ctx);\n+\t\t\t\temit_16(ctx, 0x7400);\t\t/* moveq #0, %d2 */\n+\t\t\t\tbpf_put_reg32(src[0], M68K_D2, ctx);\n+\t\t\t}\n+\t\t}\n+\n+\t} else if (BPF_SIZE(insn-\u003ecode) == BPF_DW) {\n+\t\ts8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\t\ts8 s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);\n+\n+\t\tif (insn-\u003eimm != BPF_CMPXCHG) {\n+\t\t\temit_16(ctx, 0x48e7);\t\t\t/* movem.l d0-d1, -(%sp) */\n+\t\t\temit_16(ctx, 0xc000);\n+\t\t}\n+\n+\t\temit_16(ctx, 0x2f00 | M68K_D0);\t\t\t/* move.l %d0, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | M68K_D1);\t\t\t/* move.l %d1, -(%sp) */\n+\t\temit_16(ctx, 0x2f3c);\t\t\t\t/* move.l #imm, -(%sp) */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\temit_16(ctx, 0x2f00 | s_lo);\t\t\t/* move.l s_lo, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | s_hi);\t\t\t/* move.l s_hi, -(%sp) */\n+\t\temit_16(ctx, 0x2f08);\t\t\t\t/* move.l %a0, -(%sp) */\n+\n+\t\temit_16(ctx, 0x207c);\t\t\t\t/* movea.l #func, %a0 */\n+\t\temit_32(ctx, (u32)jit_atomic64);\n+\t\temit_16(ctx, 0x4e90);\t\t\t\t/* jsr (%a0) */\n+\n+\t\temit_16(ctx, 0x4fef);\t\t\t\t/* lea 24(%sp), %sp */\n+\t\temit_16(ctx, 24);\n+\n+\t\tif (insn-\u003eimm == BPF_CMPXCHG) {\n+\t\t\temit_16(ctx, 0xc141);\t\t\t/* exg %d0, %d1 */\n+\t\t} else {\n+\t\t\tbool is_fetch = (insn-\u003eimm \u0026 BPF_FETCH) || insn-\u003eimm == BPF_XCHG;\n+\n+\t\t\tif (is_fetch) {\n+\t\t\t\temit_16(ctx, 0x2600);\t\t/* move.l %d0, %d3 */\n+\t\t\t\temit_16(ctx, 0x2401);\t\t/* move.l %d1, %d2 */\n+\t\t\t}\n+\n+\t\t\temit_16(ctx, 0x4cdf);\t\t\t/* movem.l (%sp)+, d0-d1 */\n+\t\t\temit_16(ctx, 0x0003);\n+\n+\t\t\tif (is_fetch) {\n+\t\t\t\tbpf_put_reg32(src[1], M68K_D2, ctx);\n+\t\t\t\tbpf_put_reg32(src[0], M68K_D3, ctx);\n+\t\t\t}\n+\t\t}\n+\t}\n+}\n+\n+static void emit_tail_call(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 *r2 = bpf2m68k[BPF_REG_2];\n+\tconst s8 *r3 = bpf2m68k[BPF_REG_3];\n+\tint jmp_out_1, jmp_out_2, jmp_out_3;\n+\n+\tif (is_stacked(r2[1])) {\n+\t\temit_16(ctx, 0x206e);\t\t\t\t/* movea.l d16(%fp), %a0 */\n+\t\temit_16(ctx, (u16)r2[1]);\n+\t} else {\n+\t\temit_16(ctx, 0x2040 | r2[1]);\t\t\t/* movea.l r2, %a0 */\n+\t}\n+\n+\tif (is_stacked(r3[1])) {\n+\t\temit_16(ctx, 0x242e);\t\t\t\t/* move.l d16(%fp), %d2 */\n+\t\temit_16(ctx, (u16)r3[1]);\n+\t} else {\n+\t\temit_16(ctx, 0x2400 | r3[1]);\t\t\t/* move.l r3, %d2 */\n+\t}\n+\n+\temit_16(ctx, 0xb4a8);\t\t\t\t\t/* cmp.l d16(%a0), %d2 */\n+\temit_16(ctx, offsetof(struct bpf_array, map.max_entries));\n+\temit_16(ctx, 0x6400);\t\t\t\t\t/* bcc.w jmp_out_1 */\n+\tjmp_out_1 = ctx-\u003eidx;\n+\temit_16(ctx, 0);\n+\n+\temit_16(ctx, 0x262e);\t\t\t\t\t/* move.l d16(%fp), %d3 */\n+\temit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));\n+\temit_16(ctx, 0x4a83);\t\t\t\t\t/* tst.l %d3 */\n+\temit_16(ctx, 0x6700);\t\t\t\t\t/* beq.w jmp_out_2 */\n+\tjmp_out_2 = ctx-\u003eidx;\n+\temit_16(ctx, 0);\n+\n+\temit_16(ctx, 0x5383);\t\t\t\t\t/* subq.l #1, %d3 */\n+\temit_16(ctx, 0x2d43);\t\t\t\t\t/* move.l %d3, d16(%fp) */\n+\temit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));\n+\n+\temit_16(ctx, 0xd482);\t\t\t\t\t/* add.l %d2, %d2 */\n+\temit_16(ctx, 0xd482);\t\t\t\t\t/* add.l %d2, %d2 */\n+\temit_16(ctx, 0x43e8);\t\t\t\t\t/* lea d16(%a0), %a1 */\n+\temit_16(ctx, offsetof(struct bpf_array, ptrs));\n+\temit_16(ctx, 0xd3c2);\t\t\t\t\t/* adda.l %d2, %a1 */\n+\n+\temit_16(ctx, 0x2051);\t\t\t\t\t/* movea.l (%a1), %a0 */\n+\n+\temit_16(ctx, 0x2408);\t\t\t\t\t/* move.l %a0, %d2 */\n+\temit_16(ctx, 0x4a82);\t\t\t\t\t/* tst.l %d2 */\n+\temit_16(ctx, 0x6700);\t\t\t\t\t/* beq.w jmp_out_3 */\n+\tjmp_out_3 = ctx-\u003eidx;\n+\temit_16(ctx, 0);\n+\n+\temit_16(ctx, 0x2068);\t\t\t\t\t/* movea.l d16(%a0), %a0 */\n+\temit_16(ctx, offsetof(struct bpf_prog, bpf_func));\n+\n+\temit_16(ctx, 0x4ee8);\t\t\t\t\t/* jmp d16(%a0) */\n+\temit_16(ctx, 44);\n+\n+\tif (ctx-\u003etarget) {\n+\t\tctx-\u003etarget[jmp_out_1] = (ctx-\u003eidx - jmp_out_1) * 2;\n+\t\tctx-\u003etarget[jmp_out_2] = (ctx-\u003eidx - jmp_out_2) * 2;\n+\t\tctx-\u003etarget[jmp_out_3] = (ctx-\u003eidx - jmp_out_3) * 2;\n+\t}\n+}\n+\n+static int emit_jmp(const struct bpf_insn *insn, struct jit_ctx *ctx, int curr_i)\n+{\n+\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\tconst s8 *src = bpf2m68k[insn-\u003esrc_reg];\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tconst s8 *tmp2 = bpf2m68k[TMP_REG_2];\n+\ts8 d_lo, d_hi = 0, s_lo, s_hi = 0;\n+\tbool is_jmp32 = BPF_CLASS(insn-\u003ecode) == BPF_JMP32;\n+\tu8 op = BPF_OP(insn-\u003ecode);\n+\tint target_insn;\n+\n+\tif (is_jmp32 \u0026\u0026 op == BPF_JA)\n+\t\ttarget_insn = curr_i + 1 + insn-\u003eimm;\n+\telse\n+\t\ttarget_insn = curr_i + 1 + insn-\u003eoff;\n+\n+\tif (target_insn \u003c 0 || target_insn \u003e ctx-\u003eprog-\u003elen)\n+\t\treturn -EOPNOTSUPP;\n+\n+\t#define EMIT_JMP32(op_base) \\\n+\t\tdo { \\\n+\t\t\tint disp = (ctx-\u003eoffsets[target_insn] - (ctx-\u003eidx + 1)) * 2; \\\n+\t\t\temit_16(ctx, (op_base) | 0x00ff); \\\n+\t\t\temit_32(ctx, disp); \\\n+\t\t} while (0)\n+\n+\tif (op == BPF_JA) {\n+\t\tEMIT_JMP32(0x6000);\t\t\t\t/* bra.l */\n+\t\treturn 0;\n+\t}\n+\n+\td_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\tif (!is_jmp32)\n+\t\td_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\n+\tif (BPF_SRC(insn-\u003ecode) == BPF_X) {\n+\t\ts_lo = bpf_get_reg32(src[1], tmp2[1], ctx);\n+\t\tif (!is_jmp32)\n+\t\t\ts_hi = bpf_get_reg32(src[0], tmp2[0], ctx);\n+\t} else {\n+\t\ts_lo = tmp2[1];\n+\t\temit_16(ctx, 0x203c | (s_lo \u003c\u003c 9));\t\t/* move.l #imm, s_lo */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\tif (!is_jmp32) {\n+\t\t\ts_hi = tmp2[0];\n+\t\t\temit_16(ctx, 0x203c | (s_hi \u003c\u003c 9));\t/* move.l #imm, s_hi */\n+\t\t\temit_32(ctx, insn-\u003eimm \u003c 0 ? 0xffffffff : 0);\n+\t\t}\n+\t}\n+\n+\tif (op == BPF_JSET) {\n+\t\temit_16(ctx, 0x2000 | (tmp1[1] \u003c\u003c 9) | d_lo);\t/* move.l d_lo, tmp1_lo */\n+\t\temit_16(ctx, 0xc080 | (tmp1[1] \u003c\u003c 9) | s_lo);\t/* and.l s_lo, tmp1_lo */\n+\n+\t\tif (!is_jmp32) {\n+\t\t\tEMIT_JMP32(0x6600);\t\t\t/* bne.l */\n+\t\t\temit_16(ctx, 0x2000 | (tmp1[0] \u003c\u003c 9) | d_hi); /* move.l d_hi, tmp1_hi */\n+\t\t\temit_16(ctx, 0xc080 | (tmp1[0] \u003c\u003c 9) | s_hi); /* and.l s_hi, tmp1_hi */\n+\t\t}\n+\t\tEMIT_JMP32(0x6600);\t\t\t\t/* bne.l */\n+\t\treturn 0;\n+\t}\n+\n+\tif (is_jmp32) {\n+\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo);\t/* cmp.l s_lo, d_lo */\n+\t\tswitch (op) {\n+\t\tcase BPF_JEQ:\n+\t\t\tEMIT_JMP32(0x6700);\t\t\t/* beq.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JNE:\n+\t\t\tEMIT_JMP32(0x6600);\t\t\t/* bne.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JGT:\n+\t\t\tEMIT_JMP32(0x6200);\t\t\t/* bhi.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JGE:\n+\t\t\tEMIT_JMP32(0x6400);\t\t\t/* bcc.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JLT:\n+\t\t\tEMIT_JMP32(0x6500);\t\t\t/* bcs.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JLE:\n+\t\t\tEMIT_JMP32(0x6300);\t\t\t/* bls.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSGT:\n+\t\t\tEMIT_JMP32(0x6e00);\t\t\t/* bgt.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSGE:\n+\t\t\tEMIT_JMP32(0x6c00);\t\t\t/* bge.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSLT:\n+\t\t\tEMIT_JMP32(0x6d00);\t\t\t/* blt.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSLE:\n+\t\t\tEMIT_JMP32(0x6f00);\t\t\t/* ble.l */\n+\t\t\tbreak;\n+\t\t}\n+\t} else {\n+\t\temit_16(ctx, 0xb080 | (d_hi \u003c\u003c 9) | s_hi);\t/* cmp.l s_hi, d_hi */\n+\n+\t\tswitch (op) {\n+\t\tcase BPF_JEQ:\n+\t\t\temit_16(ctx, 0x6608);\t\t\t/* bne.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6700);\t\t\t/* beq.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JNE:\n+\t\t\tEMIT_JMP32(0x6600);\t\t\t/* bne.l */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6600);\t\t\t/* bne.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JGT:\n+\t\t\tEMIT_JMP32(0x6200);\t\t\t/* bhi.l */\n+\t\t\temit_16(ctx, 0x6508);\t\t\t/* bcs.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6200);\t\t\t/* bhi.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JGE:\n+\t\t\tEMIT_JMP32(0x6200);\t\t\t/* bhi.l */\n+\t\t\temit_16(ctx, 0x6508);\t\t\t/* bcs.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6400);\t\t\t/* bcc.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JLT:\n+\t\t\tEMIT_JMP32(0x6500);\t\t\t/* bcs.l */\n+\t\t\temit_16(ctx, 0x6208);\t\t\t/* bhi.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6500);\t\t\t/* bcs.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JLE:\n+\t\t\tEMIT_JMP32(0x6500);\t\t\t/* bcs.l */\n+\t\t\temit_16(ctx, 0x6208);\t\t\t/* bhi.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6300);\t\t\t/* bls.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSGT:\n+\t\t\tEMIT_JMP32(0x6e00);\t\t\t/* bgt.l */\n+\t\t\temit_16(ctx, 0x6d08);\t\t\t/* blt.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6200);\t\t\t/* bhi.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSGE:\n+\t\t\tEMIT_JMP32(0x6e00);\t\t\t/* bgt.l */\n+\t\t\temit_16(ctx, 0x6d08);\t\t\t/* blt.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6400);\t\t\t/* bcc.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSLT:\n+\t\t\tEMIT_JMP32(0x6d00);\t\t\t/* blt.l */\n+\t\t\temit_16(ctx, 0x6e08);\t\t\t/* bgt.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6500);\t\t\t/* bcs.l */\n+\t\t\tbreak;\n+\t\tcase BPF_JSLE:\n+\t\t\tEMIT_JMP32(0x6d00);\t\t\t/* blt.l */\n+\t\t\temit_16(ctx, 0x6e08);\t\t\t/* bgt.s .+8 */\n+\t\t\temit_16(ctx, 0xb080 | (d_lo \u003c\u003c 9) | s_lo); /* cmp.l s_lo, d_lo */\n+\t\t\tEMIT_JMP32(0x6300);\t\t\t/* bls.l */\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\t#undef EMIT_JMP32\n+\treturn 0;\n+}\n+\n+static int emit_call(const struct bpf_insn *insn, struct jit_ctx *ctx)\n+{\n+\tconst s8 arg_regs[] = { BPF_REG_5, BPF_REG_4, BPF_REG_3, BPF_REG_2, BPF_REG_1 };\n+\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\tbool extra_pass = ctx-\u003eprog-\u003ejited;\n+\tu64 func_addr;\n+\tbool fixed;\n+\tint i, err;\n+\n+\terr = bpf_jit_get_func_addr(ctx-\u003eprog, insn, extra_pass, \u0026func_addr, \u0026fixed);\n+\tif (err)\n+\t\treturn err;\n+\n+\tfor (i = 0; i \u003c 5; i++) {\n+\t\tconst s8 *reg = bpf2m68k[arg_regs[i]];\n+\t\ts8 d_lo = bpf_get_reg32(reg[1], tmp1[1], ctx);\n+\t\ts8 d_hi = bpf_get_reg32(reg[0], tmp1[0], ctx);\n+\n+\t\temit_16(ctx, 0x2f00 | d_lo);\t\t\t/* move.l d_lo, -(%sp) */\n+\t\temit_16(ctx, 0x2f00 | d_hi);\t\t\t/* move.l d_hi, -(%sp) */\n+\t}\n+\n+\temit_16(ctx, 0x207c);\t\t\t\t\t/* movea.l #func_addr, %a0 */\n+\temit_32(ctx, (u32)func_addr);\n+\n+\temit_16(ctx, 0x4e90);\t\t\t\t\t/* jsr (%a0) */\n+\n+\temit_16(ctx, 0x4fef);\t\t\t\t\t/* lea 40(%sp), %sp */\n+\temit_16(ctx, 40);\n+\n+\tif (insn-\u003esrc_reg != BPF_PSEUDO_CALL)\n+\t\temit_16(ctx, 0xc340);\t\t\t\t\t/* exg %d0, %d1 */\n+\n+\treturn 0;\n+}\n+\n+static void build_prologue(struct jit_ctx *ctx)\n+{\n+\tint bpf_stack = MAX_BPF_STACK;\n+\tint total_stack = SCRATCH_SIZE + bpf_stack;\n+\tint i;\n+\n+\temit_16(ctx, 0x7021);\t\t\t\t\t/* moveq #33, %d0 */\n+\n+\temit_16(ctx, 0x4e56);\t\t\t\t\t/* link %a6, #-total_stack */\n+\temit_16(ctx, -total_stack);\n+\n+\temit_16(ctx, 0x48e7);\t\t\t\t\t/* movem.l d2-d5, -(%sp) */\n+\temit_16(ctx, 0x3c00);\n+\n+\temit_16(ctx, 0x2d40);\t\t\t\t\t/* move.l %d0, off(%fp) */\n+\temit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));\n+\n+\tif (ctx-\u003eprog-\u003eis_func) {\n+\t\tconst s8 arg_regs[] = { BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5 };\n+\n+\t\tfor (i = 0; i \u003c 5; i++) {\n+\t\t\tint offset = 8 + i * 8;\n+\t\t\tconst s8 *reg = bpf2m68k[arg_regs[i]];\n+\n+\t\t\temit_16(ctx, 0x202e); /* move.l offset(%fp), %d0 */\n+\t\t\temit_16(ctx, offset);\n+\t\t\tbpf_put_reg32(reg[0], M68K_D0, ctx);\n+\n+\t\t\temit_16(ctx, 0x202e); /* move.l offset+4(%fp), %d0 */\n+\t\t\temit_16(ctx, offset + 4);\n+\t\t\tbpf_put_reg32(reg[1], M68K_D0, ctx);\n+\t\t}\n+\t} else {\n+\t\temit_16(ctx, 0x202e);\t\t\t\t/* move.l 8(%fp), %d0 */\n+\t\temit_16(ctx, 8);\n+\t\tbpf_put_reg32(bpf2m68k[BPF_REG_1][1], M68K_D0, ctx);\n+\n+\t\temit_16(ctx, 0x7000 | (M68K_D0 \u003c\u003c 9));\t\t\t/* moveq #0, %d0 */\n+\t\tbpf_put_reg32(bpf2m68k[BPF_REG_1][0], M68K_D0, ctx);\n+\t}\n+\n+\temit_16(ctx, 0x41ee);\t\t\t\t\t/* lea -SCRATCH_SIZE(%fp), %a0 */\n+\temit_16(ctx, -SCRATCH_SIZE);\n+\temit_16(ctx, 0x2008);\t\t\t\t\t/* move.l %a0, %d0 */\n+\n+\tbpf_put_reg32(bpf2m68k[BPF_REG_10][1], M68K_D0, ctx);\n+\temit_16(ctx, 0x7000 | (M68K_D0 \u003c\u003c 9));\t\t\t/* moveq #0, %d0 */\n+\tbpf_put_reg32(bpf2m68k[BPF_REG_10][0], M68K_D0, ctx);\n+}\n+\n+static void build_epilogue(struct jit_ctx *ctx)\n+{\n+\temit_16(ctx, 0x4cdf);\t\t\t\t\t/* movem.l (%sp)+, d2-d5 */\n+\temit_16(ctx, 0x003c);\n+\n+\temit_16(ctx, 0x4e5e);\t\t\t\t\t/* unlk %fp */\n+\temit_16(ctx, 0x4e75);\t\t\t\t\t/* rts */\n+}\n+\n+static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, int i)\n+{\n+\tu8 code = insn-\u003ecode;\n+\n+\tswitch (code) {\n+\tcase BPF_ALU | BPF_NEG:\n+\t\temit_alu32_neg(insn, ctx);\n+\t\tbreak;\n+\tcase BPF_ALU64 | BPF_NEG:\n+\t\temit_alu64_neg(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_ALU | BPF_MOV | BPF_X:\n+\tcase BPF_ALU | BPF_ADD | BPF_X:\n+\tcase BPF_ALU | BPF_SUB | BPF_X:\n+\tcase BPF_ALU | BPF_AND | BPF_X:\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+\tcase BPF_ALU | BPF_RSH | BPF_X:\n+\tcase BPF_ALU | BPF_ARSH | BPF_X:\n+\t\temit_alu32_x(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_ALU | BPF_MOV | BPF_K:\n+\tcase BPF_ALU | BPF_ADD | BPF_K:\n+\tcase BPF_ALU | BPF_SUB | BPF_K:\n+\tcase BPF_ALU | BPF_AND | BPF_K:\n+\tcase BPF_ALU | BPF_OR  | BPF_K:\n+\tcase BPF_ALU | BPF_XOR | BPF_K:\n+\tcase BPF_ALU | BPF_LSH | BPF_K:\n+\tcase BPF_ALU | BPF_RSH | BPF_K:\n+\tcase BPF_ALU | BPF_ARSH | BPF_K:\n+\t\temit_alu32_k(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_ALU64 | BPF_MOV | BPF_X:\n+\tcase BPF_ALU64 | BPF_ADD | BPF_X:\n+\tcase BPF_ALU64 | BPF_SUB | BPF_X:\n+\tcase BPF_ALU64 | BPF_AND | BPF_X:\n+\tcase BPF_ALU64 | BPF_OR  | BPF_X:\n+\tcase BPF_ALU64 | BPF_XOR | BPF_X:\n+\t\temit_alu64_x(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_ALU64 | BPF_MOV | BPF_K:\n+\tcase BPF_ALU64 | BPF_ADD | BPF_K:\n+\tcase BPF_ALU64 | BPF_SUB | BPF_K:\n+\tcase BPF_ALU64 | BPF_AND | BPF_K:\n+\tcase BPF_ALU64 | BPF_OR  | BPF_K:\n+\tcase BPF_ALU64 | BPF_XOR | BPF_K:\n+\t\temit_alu64_k(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_ALU64 | BPF_LSH | BPF_X:\n+\tcase BPF_ALU64 | BPF_RSH | BPF_X:\n+\tcase BPF_ALU64 | BPF_ARSH | BPF_X:\n+\t\temit_alu64_shift(insn, ctx, false);\n+\t\tbreak;\n+\n+\tcase BPF_ALU64 | BPF_LSH | BPF_K:\n+\tcase BPF_ALU64 | BPF_RSH | BPF_K:\n+\tcase BPF_ALU64 | BPF_ARSH | BPF_K:\n+\t\temit_alu64_shift(insn, ctx, true);\n+\t\tbreak;\n+\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+\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\temit_math_call(insn, ctx, false);\n+\t\tbreak;\n+\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+\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\temit_math_call(insn, ctx, true);\n+\t\tbreak;\n+\n+\tcase BPF_ALU | BPF_END | BPF_TO_BE:\n+\tcase BPF_ALU | BPF_END | BPF_TO_LE:\n+\tcase BPF_ALU64 | BPF_END | BPF_TO_BE:\n+\tcase BPF_ALU64 | BPF_END | BPF_TO_LE:\n+\t\temit_bpf_end(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_LD | BPF_IMM | BPF_DW: {\n+\t\tconst struct bpf_insn *insn1 = insn + 1;\n+\t\tconst s8 *dst = bpf2m68k[insn-\u003edst_reg];\n+\t\tconst s8 *tmp1 = bpf2m68k[TMP_REG_1];\n+\t\ts8 d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);\n+\t\ts8 d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);\n+\n+\t\temit_16(ctx, 0x203c | (d_lo \u003c\u003c 9));\t\t\t/* move.l #imm, d_lo */\n+\t\temit_32(ctx, insn-\u003eimm);\n+\t\temit_16(ctx, 0x203c | (d_hi \u003c\u003c 9));\t\t\t/* move.l #imm, d_hi */\n+\t\temit_32(ctx, insn1-\u003eimm);\n+\n+\t\tbpf_put_reg32(dst[1], d_lo, ctx);\n+\t\tbpf_put_reg32(dst[0], d_hi, ctx);\n+\t\tbreak;\n+\t}\n+\n+\tcase BPF_LDX | BPF_MEM | BPF_B:\n+\tcase BPF_LDX | BPF_MEM | BPF_H:\n+\tcase BPF_LDX | BPF_MEM | BPF_W:\n+\tcase BPF_LDX | BPF_MEM | BPF_DW:\n+\tcase BPF_LDX | BPF_MEMSX | BPF_B:\n+\tcase BPF_LDX | BPF_MEMSX | BPF_H:\n+\tcase BPF_LDX | BPF_MEMSX | BPF_W:\n+\t\temit_ldx(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_STX | BPF_MEM | BPF_B:\n+\tcase BPF_STX | BPF_MEM | BPF_H:\n+\tcase BPF_STX | BPF_MEM | BPF_W:\n+\tcase BPF_STX | BPF_MEM | BPF_DW:\n+\t\temit_stx(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_ST | BPF_MEM | BPF_B:\n+\tcase BPF_ST | BPF_MEM | BPF_H:\n+\tcase BPF_ST | BPF_MEM | BPF_W:\n+\tcase BPF_ST | BPF_MEM | BPF_DW:\n+\t\temit_st(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_STX | BPF_ATOMIC | BPF_W:\n+\tcase BPF_STX | BPF_ATOMIC | BPF_DW:\n+\t\temit_atomic(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_JMP | BPF_TAIL_CALL:\n+\t\temit_tail_call(insn, ctx);\n+\t\tbreak;\n+\n+\tcase BPF_JMP | BPF_JA:\n+\tcase BPF_JMP32 | BPF_JA:\n+\tcase BPF_JMP | BPF_JEQ | BPF_X:\n+\tcase BPF_JMP | BPF_JEQ | BPF_K:\n+\tcase BPF_JMP | BPF_JNE | BPF_X:\n+\tcase BPF_JMP | BPF_JNE | BPF_K:\n+\tcase BPF_JMP | BPF_JGT | BPF_X:\n+\tcase BPF_JMP | BPF_JGT | BPF_K:\n+\tcase BPF_JMP | BPF_JGE | BPF_X:\n+\tcase BPF_JMP | BPF_JGE | BPF_K:\n+\tcase BPF_JMP | BPF_JLT | BPF_X:\n+\tcase BPF_JMP | BPF_JLT | BPF_K:\n+\tcase BPF_JMP | BPF_JLE | BPF_X:\n+\tcase BPF_JMP | BPF_JLE | BPF_K:\n+\tcase BPF_JMP | BPF_JSGT | BPF_X:\n+\tcase BPF_JMP | BPF_JSGT | BPF_K:\n+\tcase BPF_JMP | BPF_JSGE | BPF_X:\n+\tcase BPF_JMP | BPF_JSGE | BPF_K:\n+\tcase BPF_JMP | BPF_JSLT | BPF_X:\n+\tcase BPF_JMP | BPF_JSLT | BPF_K:\n+\tcase BPF_JMP | BPF_JSLE | BPF_X:\n+\tcase BPF_JMP | BPF_JSLE | BPF_K:\n+\tcase BPF_JMP | BPF_JSET | BPF_X:\n+\tcase BPF_JMP | BPF_JSET | BPF_K:\n+\tcase BPF_JMP32 | BPF_JEQ | BPF_X:\n+\tcase BPF_JMP32 | BPF_JEQ | BPF_K:\n+\tcase BPF_JMP32 | BPF_JNE | BPF_X:\n+\tcase BPF_JMP32 | BPF_JNE | BPF_K:\n+\tcase BPF_JMP32 | BPF_JGT | BPF_X:\n+\tcase BPF_JMP32 | BPF_JGT | BPF_K:\n+\tcase BPF_JMP32 | BPF_JGE | BPF_X:\n+\tcase BPF_JMP32 | BPF_JGE | BPF_K:\n+\tcase BPF_JMP32 | BPF_JLT | BPF_X:\n+\tcase BPF_JMP32 | BPF_JLT | BPF_K:\n+\tcase BPF_JMP32 | BPF_JLE | BPF_X:\n+\tcase BPF_JMP32 | BPF_JLE | BPF_K:\n+\tcase BPF_JMP32 | BPF_JSGT | BPF_X:\n+\tcase BPF_JMP32 | BPF_JSGT | BPF_K:\n+\tcase BPF_JMP32 | BPF_JSGE | BPF_X:\n+\tcase BPF_JMP32 | BPF_JSGE | BPF_K:\n+\tcase BPF_JMP32 | BPF_JSLT | BPF_X:\n+\tcase BPF_JMP32 | BPF_JSLT | BPF_K:\n+\tcase BPF_JMP32 | BPF_JSLE | BPF_X:\n+\tcase BPF_JMP32 | BPF_JSLE | BPF_K:\n+\tcase BPF_JMP32 | BPF_JSET | BPF_X:\n+\tcase BPF_JMP32 | BPF_JSET | BPF_K:\n+\t\treturn emit_jmp(insn, ctx, i);\n+\n+\tcase BPF_JMP | BPF_CALL:\n+\t\treturn emit_call(insn, ctx);\n+\n+\tcase BPF_JMP | BPF_EXIT:\n+\t\tbuild_epilogue(ctx);\n+\t\tbreak;\n+\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int build_body(struct jit_ctx *ctx)\n+{\n+\tconst struct bpf_prog *prog = ctx-\u003eprog;\n+\tint i;\n+\n+\tfor (i = 0; i \u003c prog-\u003elen; i++) {\n+\t\tconst struct bpf_insn *insn = \u0026prog-\u003einsnsi[i];\n+\t\tint ret;\n+\n+\t\tif (!ctx-\u003etarget)\n+\t\t\tctx-\u003eoffsets[i] = ctx-\u003eidx;\n+\n+\t\tret = build_insn(insn, ctx, i);\n+\t\tif (ret \u003c 0)\n+\t\t\treturn ret;\n+\n+\t\tif (insn-\u003ecode == (BPF_LD | BPF_IMM | BPF_DW)) {\n+\t\t\ti++;\n+\t\t\tif (!ctx-\u003etarget)\n+\t\t\t\tctx-\u003eoffsets[i] = ctx-\u003eidx;\n+\t\t}\n+\t}\n+\n+\tif (!ctx-\u003etarget)\n+\t\tctx-\u003eoffsets[prog-\u003elen] = ctx-\u003eidx;\n+\n+\treturn 0;\n+}\n+\n+bool bpf_jit_needs_zext(void)\n+{\n+\treturn true;\n+}\n+\n+static void jit_fill_hole(void *area, unsigned int size)\n+{\n+\tu16 *ptr;\n+\n+\tfor (ptr = area; size \u003e= 2; size -= 2)\n+\t\t*ptr++ = 0x4afc;\n+}\n+\n+struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n+{\n+\tstruct bpf_binary_header *header;\n+\tstruct jit_ctx ctx;\n+\tunsigned int image_size;\n+\tu8 *image_ptr;\n+\tbool extra_pass = prog-\u003ejited;\n+\n+\tif (!prog-\u003ejit_requested)\n+\t\treturn prog;\n+\n+\tif (prog-\u003ejited \u0026\u0026 !prog-\u003eaux-\u003efunc)\n+\t\treturn prog;\n+\n+\tmemset(\u0026ctx, 0, sizeof(ctx));\n+\tctx.prog = prog;\n+\n+\tctx.offsets = kvcalloc(prog-\u003elen + 1, sizeof(int), GFP_KERNEL);\n+\tif (!ctx.offsets)\n+\t\treturn prog;\n+\n+\tbuild_prologue(\u0026ctx);\n+\tif (build_body(\u0026ctx) \u003c 0)\n+\t\tgoto out_off;\n+\tbuild_epilogue(\u0026ctx);\n+\n+\tif (extra_pass) {\n+\t\theader = prog-\u003eaux-\u003ejit_data;\n+\t\timage_ptr = (u8 *)prog-\u003ebpf_func;\n+\t\timage_size = prog-\u003ejited_len;\n+\t} else {\n+\t\timage_size = ctx.idx * 2;\n+\t\theader = bpf_jit_binary_alloc(image_size, \u0026image_ptr, 2, jit_fill_hole);\n+\t\tif (!header)\n+\t\t\tgoto out_off;\n+\t\tprog-\u003eaux-\u003ejit_data = header;\n+\t}\n+\n+\tctx.target = (u16 *)image_ptr;\n+\tctx.idx = 0;\n+\n+\tbuild_prologue(\u0026ctx);\n+\tif (build_body(\u0026ctx) \u003c 0) {\n+\t\tbpf_jit_binary_free(header);\n+\t\tprog-\u003eaux-\u003ejit_data = NULL;\n+\t\tprog-\u003ebpf_func = NULL;\n+\t\tprog-\u003ejited = 0;\n+\t\tprog-\u003ejited_len = 0;\n+\t\tgoto out_off;\n+\t}\n+\tbuild_epilogue(\u0026ctx);\n+\n+\tflush_icache_range((u32)header, (u32)(ctx.target + ctx.idx));\n+\n+\tif (bpf_jit_enable \u003e 1)\n+\t\tbpf_jit_dump(prog-\u003elen, image_size, 2, ctx.target);\n+\n+\tif ((!prog-\u003eaux-\u003efunc || extra_pass) \u0026\u0026 bpf_jit_binary_lock_ro(header)) {\n+\t\tbpf_jit_binary_free(header);\n+\t\tprog-\u003ebpf_func = NULL;\n+\t\tprog-\u003ejited = 0;\n+\t\tprog-\u003ejited_len = 0;\n+\t\tprog-\u003eaux-\u003ejit_data = NULL;\n+\t\tgoto out_off;\n+\t}\n+\n+\tprog-\u003ebpf_func = (void *)ctx.target;\n+\tprog-\u003ejited = 1;\n+\tprog-\u003ejited_len = image_size;\n+\n+out_off:\n+\tkvfree(ctx.offsets);\n+\treturn prog;\n+}\n"
}

2/1 2026/07/30 04:50 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_int_jit_compile",
    "bpf_jit_needs_zext"
  ],
  "Reasoning": "The patch introduces a new BPF JIT compiler for the m68k architecture. The code is reachable during BPF program loading when JIT is enabled, and can be tested in QEMU.",
  "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 3c70cb6d38777d5f518f52f83411e4eabdf4d7d0
Author: syz-cluster <triage@syzkaller.com>
Date:   Thu Jul 30 04:50:06 2026 +0000

    syz-cluster: applied patch under review

diff --git a/MAINTAINERS b/MAINTAINERS
index 2fb1c75afd163..530551834c163 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4701,6 +4701,12 @@ L:	bpf@vger.kernel.org
 S:	Maintained
 F:	arch/loongarch/net/
 
+BPF JIT for M68K
+M:	Kuan-Wei Chiu <visitorckw@gmail.com>
+L:	bpf@vger.kernel.org
+S:	Maintained
+F:	arch/m68k/net/
+
 BPF JIT for MIPS (32-BIT AND 64-BIT)
 M:	Johan Almbladh <johan.almbladh@anyfinetworks.com>
 M:	Paul Burton <paulburton@kernel.org>
diff --git a/arch/m68k/Kbuild b/arch/m68k/Kbuild
index 7762af9f6defe..058ad41a728c5 100644
--- a/arch/m68k/Kbuild
+++ b/arch/m68k/Kbuild
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-y				+= kernel/ mm/
+obj-y				+= kernel/ mm/ net/
 obj-$(CONFIG_Q40)		+= q40/
 obj-$(CONFIG_AMIGA)		+= amiga/
 obj-$(CONFIG_ATARI)		+= atari/
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 11835eb59d94d..da43d6660c5ce 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -8,6 +8,7 @@ config M68K
 	select ARCH_HAS_CPU_FINALIZE_INIT if MMU
 	select ARCH_HAS_CURRENT_STACK_POINTER
 	select ARCH_HAS_DMA_PREP_COHERENT if M68K_NONCOHERENT_DMA && !COLDFIRE
+	select HAVE_EBPF_JIT if (!COLDFIRE && !M68000)
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE if M68K_NONCOHERENT_DMA
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
 	select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
diff --git a/arch/m68k/net/Makefile b/arch/m68k/net/Makefile
new file mode 100644
index 0000000000000..ec5b147633167
--- /dev/null
+++ b/arch/m68k/net/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o
diff --git a/arch/m68k/net/bpf_jit_comp.c b/arch/m68k/net/bpf_jit_comp.c
new file mode 100644
index 0000000000000..6d647bba96eb4
--- /dev/null
+++ b/arch/m68k/net/bpf_jit_comp.c
@@ -0,0 +1,1630 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * BPF JIT compiler for m68k
+ *
+ * Copyright (C) 2026 Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#include <linux/bpf.h>
+#include <linux/filter.h>
+#include <linux/irqflags.h>
+#include <linux/slab.h>
+#include <asm/cacheflush.h>
+#include <linux/math64.h>
+#include <linux/limits.h>
+
+#define STACK_OFFSET(k) (-4 - (4 * (k)))
+
+enum {
+	BPF_R1_HI, BPF_R1_LO,
+	BPF_R2_HI, BPF_R2_LO,
+	BPF_R3_HI, BPF_R3_LO,
+	BPF_R4_HI, BPF_R4_LO,
+	BPF_R5_HI, BPF_R5_LO,
+	BPF_R6_HI, BPF_R6_LO,
+	BPF_R7_HI, BPF_R7_LO,
+	BPF_R8_HI, BPF_R8_LO,
+	BPF_R9_HI, BPF_R9_LO,
+	BPF_R10_HI, BPF_R10_LO,
+	BPF_AX_HI, BPF_AX_LO,
+	BPF_TC_HI, BPF_TC_LO,
+	BPF_JIT_SCRATCH_REGS,
+};
+
+#define SCRATCH_SIZE (BPF_JIT_SCRATCH_REGS * 4)
+
+#define TMP_REG_1 14
+#define TMP_REG_2 15
+
+#define M68K_D0 0
+#define M68K_D1 1
+#define M68K_D2 2
+#define M68K_D3 3
+#define M68K_D4 4
+#define M68K_D5 5
+
+static const s8 bpf2m68k[16][2] = {
+	[BPF_REG_0]  = {M68K_D1, M68K_D0},
+	[BPF_REG_1]  = {STACK_OFFSET(BPF_R1_HI),  STACK_OFFSET(BPF_R1_LO)},
+	[BPF_REG_2]  = {STACK_OFFSET(BPF_R2_HI),  STACK_OFFSET(BPF_R2_LO)},
+	[BPF_REG_3]  = {STACK_OFFSET(BPF_R3_HI),  STACK_OFFSET(BPF_R3_LO)},
+	[BPF_REG_4]  = {STACK_OFFSET(BPF_R4_HI),  STACK_OFFSET(BPF_R4_LO)},
+	[BPF_REG_5]  = {STACK_OFFSET(BPF_R5_HI),  STACK_OFFSET(BPF_R5_LO)},
+	[BPF_REG_6]  = {STACK_OFFSET(BPF_R6_HI),  STACK_OFFSET(BPF_R6_LO)},
+	[BPF_REG_7]  = {STACK_OFFSET(BPF_R7_HI),  STACK_OFFSET(BPF_R7_LO)},
+	[BPF_REG_8]  = {STACK_OFFSET(BPF_R8_HI),  STACK_OFFSET(BPF_R8_LO)},
+	[BPF_REG_9]  = {STACK_OFFSET(BPF_R9_HI),  STACK_OFFSET(BPF_R9_LO)},
+	[BPF_REG_10] = {STACK_OFFSET(BPF_R10_HI), STACK_OFFSET(BPF_R10_LO)},
+	[BPF_REG_AX] = {STACK_OFFSET(BPF_AX_HI),  STACK_OFFSET(BPF_AX_LO)},
+	[TMP_REG_1]  = {M68K_D3, M68K_D2},
+	[TMP_REG_2]  = {M68K_D5, M68K_D4},
+};
+
+struct jit_ctx {
+	const struct bpf_prog *prog;
+	u16 *target;
+	unsigned int idx;
+	int *offsets;
+};
+
+static noinline u32 jit_mul32(u32 a, u32 b)
+{
+	return a * b;
+}
+
+static noinline u32 jit_div32(u32 a, u32 b)
+{
+	return b ? a / b : 0;
+}
+
+static noinline u32 jit_mod32(u32 a, u32 b)
+{
+	return b ? a % b : a;
+}
+
+static noinline s32 jit_sdiv32(s32 a, s32 b)
+{
+	if (b == 0)
+		return 0;
+	if (a == S32_MIN && b == -1)
+		return S32_MIN;
+	return a / b;
+}
+
+static noinline s32 jit_smod32(s32 a, s32 b)
+{
+	if (b == 0)
+		return a;
+	if (a == S32_MIN && b == -1)
+		return 0;
+	return a % b;
+}
+
+static noinline u64 jit_mul64(u64 a, u64 b)
+{
+	return a * b;
+}
+
+static noinline u64 jit_div64(u64 a, u64 b)
+{
+	return b ? div64_u64(a, b) : 0;
+}
+
+static noinline s64 jit_sdiv64(s64 a, s64 b)
+{
+	if (b == 0)
+		return 0;
+	if (a == S64_MIN && b == -1)
+		return S64_MIN;
+	return div64_s64(a, b);
+}
+
+static noinline u64 jit_mod64(u64 a, u64 b)
+{
+	u64 rem;
+
+	if (b == 0)
+		return a;
+	div64_u64_rem(a, b, &rem);
+	return rem;
+}
+
+static noinline s64 jit_smod64(s64 a, s64 b)
+{
+	if (b == 0)
+		return a;
+	if (a == S64_MIN && b == -1)
+		return 0;
+	return a - div64_s64(a, b) * b;
+}
+
+static u32 jit_atomic32(u32 *ptr, u32 val, u32 op, u32 cmp)
+{
+	unsigned long flags;
+	u32 old;
+
+	local_irq_save(flags);
+	old = *ptr;
+	switch (op) {
+	case BPF_ADD:
+	case BPF_ADD | BPF_FETCH:
+		*ptr += val;
+		break;
+	case BPF_AND:
+	case BPF_AND | BPF_FETCH:
+		*ptr &= val;
+		break;
+	case BPF_OR:
+	case BPF_OR | BPF_FETCH:
+		*ptr |= val;
+		break;
+	case BPF_XOR:
+	case BPF_XOR | BPF_FETCH:
+		*ptr ^= val;
+		break;
+	case BPF_XCHG:
+		*ptr = val;
+		break;
+	case BPF_CMPXCHG:
+		if (old == cmp)
+			*ptr = val;
+		break;
+	}
+	local_irq_restore(flags);
+
+	return old;
+}
+
+static u64 jit_atomic64(u32 *ptr, u32 val_hi, u32 val_lo, u32 op, u32 cmp_hi, u32 cmp_lo)
+{
+	unsigned long flags;
+	u64 old, val, cmp;
+	u64 *ptr64 = (u64 *)ptr;
+
+	val = ((u64)val_hi << 32) | val_lo;
+	cmp = ((u64)cmp_hi << 32) | cmp_lo;
+
+	local_irq_save(flags);
+	old = *ptr64;
+	switch (op) {
+	case BPF_ADD:
+	case BPF_ADD | BPF_FETCH:
+		*ptr64 += val;
+		break;
+	case BPF_AND:
+	case BPF_AND | BPF_FETCH:
+		*ptr64 &= val;
+		break;
+	case BPF_OR:
+	case BPF_OR | BPF_FETCH:
+		*ptr64 |= val;
+		break;
+	case BPF_XOR:
+	case BPF_XOR | BPF_FETCH:
+		*ptr64 ^= val;
+		break;
+	case BPF_XCHG:
+		*ptr64 = val;
+		break;
+	case BPF_CMPXCHG:
+		if (old == cmp)
+			*ptr64 = val;
+		break;
+	}
+	local_irq_restore(flags);
+
+	return old;
+}
+
+static inline void emit_16(struct jit_ctx *ctx, u16 inst)
+{
+	if (ctx->target)
+		ctx->target[ctx->idx] = inst;
+	ctx->idx++;
+}
+
+static inline void emit_32(struct jit_ctx *ctx, u32 val)
+{
+	emit_16(ctx, val >> 16);
+	emit_16(ctx, val & 0xffff);
+}
+
+static inline bool is_stacked(s8 reg)
+{
+	return reg < 0;
+}
+
+static s8 bpf_get_reg32(s8 bpf_reg, s8 tmp_reg, struct jit_ctx *ctx)
+{
+	if (is_stacked(bpf_reg)) {
+		emit_16(ctx, 0x202e | (tmp_reg << 9));		/* move.l d16(%fp), reg */
+		emit_16(ctx, (u16)bpf_reg);
+		return tmp_reg;
+	}
+	return bpf_reg;
+}
+
+static void bpf_put_reg32(s8 bpf_reg, s8 src_reg, struct jit_ctx *ctx)
+{
+	if (is_stacked(bpf_reg)) {
+		emit_16(ctx, 0x2d40 | src_reg);			/* move.l reg, d16(%fp) */
+		emit_16(ctx, (u16)bpf_reg);
+	} else if (bpf_reg != src_reg) {
+		emit_16(ctx, 0x2000 | (bpf_reg << 9) | src_reg); /* move.l src, dst */
+	}
+}
+
+static void emit_alu32_neg(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	s8 d_reg = bpf_get_reg32(dst[1], tmp1[1], ctx);
+
+	emit_16(ctx, 0x4480 | d_reg);				/* neg.l d_reg */
+
+	bpf_put_reg32(dst[1], d_reg, ctx);
+	emit_16(ctx, 0x7000 | (tmp1[0] << 9));			/* moveq #0, tmp1 */
+	bpf_put_reg32(dst[0], tmp1[0], ctx);
+}
+
+static void emit_alu64_neg(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	s8 d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	s8 d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+
+	emit_16(ctx, 0x4480 | d_lo);				/* neg.l d_lo */
+	emit_16(ctx, 0x4080 | d_hi);				/* negx.l d_hi */
+
+	bpf_put_reg32(dst[1], d_lo, ctx);
+	bpf_put_reg32(dst[0], d_hi, ctx);
+}
+
+static void emit_alu32_x(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_reg, s_reg;
+
+	d_reg = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	s_reg = bpf_get_reg32(src[1], tmp2[1], ctx);
+
+	switch (BPF_OP(insn->code)) {
+	case BPF_MOV:
+		if (insn->off == 8 || insn->off == 16) {
+			if (d_reg != s_reg)
+				emit_16(ctx, 0x2000 | (d_reg << 9) | s_reg); /* move.l src, dst */
+			if (insn->off == 8)
+				emit_16(ctx, 0x49c0 | d_reg);	/* extb.l d_reg */
+			else
+				emit_16(ctx, 0x48c0 | d_reg);	/* ext.l d_reg */
+		} else {
+			if (d_reg != s_reg)
+				emit_16(ctx, 0x2000 | (d_reg << 9) | s_reg); /* move.l src, dst */
+		}
+		break;
+	case BPF_ADD:
+		emit_16(ctx, 0xd080 | (d_reg << 9) | s_reg);	/* add.l src, dst */
+		break;
+	case BPF_SUB:
+		emit_16(ctx, 0x9080 | (d_reg << 9) | s_reg);	/* sub.l src, dst */
+		break;
+	case BPF_AND:
+		emit_16(ctx, 0xc080 | (d_reg << 9) | s_reg);	/* and.l src, dst */
+		break;
+	case BPF_OR:
+		emit_16(ctx, 0x8080 | (d_reg << 9) | s_reg);	/* or.l src, dst */
+		break;
+	case BPF_XOR:
+		emit_16(ctx, 0xb180 | (s_reg << 9) | d_reg);	/* eor.l src, dst */
+		break;
+	case BPF_LSH:
+	case BPF_RSH:
+	case BPF_ARSH: {
+		s8 count_reg = tmp2[1];
+
+		if (s_reg != count_reg)
+			emit_16(ctx, 0x2000 | (count_reg << 9) | s_reg); /* move.l src, count */
+
+		emit_16(ctx, 0x0280 | count_reg);		/* andi.l #imm, count */
+		emit_32(ctx, 0x1f);
+
+		if (BPF_OP(insn->code) == BPF_LSH)
+			emit_16(ctx, 0xe1a8 | (count_reg << 9) | d_reg); /* lsl.l count, dst */
+		else if (BPF_OP(insn->code) == BPF_RSH)
+			emit_16(ctx, 0xe0a8 | (count_reg << 9) | d_reg); /* lsr.l count, dst */
+		else
+			emit_16(ctx, 0xe0a0 | (count_reg << 9) | d_reg); /* asr.l count, dst */
+		break;
+	}
+	}
+
+	bpf_put_reg32(dst[1], d_reg, ctx);
+	emit_16(ctx, 0x7000 | (tmp1[0] << 9));			/* moveq #0, tmp1 */
+	bpf_put_reg32(dst[0], tmp1[0], ctx);
+}
+
+static void emit_alu32_k(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_reg;
+
+	d_reg = bpf_get_reg32(dst[1], tmp1[1], ctx);
+
+	switch (BPF_OP(insn->code)) {
+	case BPF_MOV:
+		emit_16(ctx, 0x203c | (d_reg << 9));		/* move.l #imm, dst */
+		emit_32(ctx, insn->imm);
+		break;
+	case BPF_ADD:
+		emit_16(ctx, 0x0680 | d_reg);			/* addi.l #imm, dst */
+		emit_32(ctx, insn->imm);
+		break;
+	case BPF_SUB:
+		emit_16(ctx, 0x0480 | d_reg);			/* subi.l #imm, dst */
+		emit_32(ctx, insn->imm);
+		break;
+	case BPF_AND:
+		emit_16(ctx, 0x0280 | d_reg);			/* andi.l #imm, dst */
+		emit_32(ctx, insn->imm);
+		break;
+	case BPF_OR:
+		emit_16(ctx, 0x0080 | d_reg);			/* ori.l #imm, dst */
+		emit_32(ctx, insn->imm);
+		break;
+	case BPF_XOR:
+		emit_16(ctx, 0x0a80 | d_reg);			/* eori.l #imm, dst */
+		emit_32(ctx, insn->imm);
+		break;
+	case BPF_LSH:
+	case BPF_RSH:
+	case BPF_ARSH:
+		emit_16(ctx, 0x203c | (tmp2[1] << 9));		/* move.l #imm, count */
+		emit_32(ctx, insn->imm & 0x1f);
+
+		if (BPF_OP(insn->code) == BPF_LSH)
+			emit_16(ctx, 0xe1a8 | (tmp2[1] << 9) | d_reg);	/* lsl.l count, dst */
+		else if (BPF_OP(insn->code) == BPF_RSH)
+			emit_16(ctx, 0xe0a8 | (tmp2[1] << 9) | d_reg);	/* lsr.l count, dst */
+		else
+			emit_16(ctx, 0xe0a0 | (tmp2[1] << 9) | d_reg);	/* asr.l count, dst */
+		break;
+	}
+
+	bpf_put_reg32(dst[1], d_reg, ctx);
+	emit_16(ctx, 0x7000 | (tmp1[0] << 9));			/* moveq #0, tmp1 */
+	bpf_put_reg32(dst[0], tmp1[0], ctx);
+}
+
+static void emit_alu64_x(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_lo, d_hi, s_lo, s_hi;
+
+	d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+	s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+	s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);
+
+	switch (BPF_OP(insn->code)) {
+	case BPF_MOV:
+		if (insn->off == 8 || insn->off == 16 || insn->off == 32) {
+			if (d_lo != s_lo)
+				emit_16(ctx, 0x2000 | (d_lo << 9) | s_lo); /* move.l src, dst */
+
+			if (insn->off == 8)
+				emit_16(ctx, 0x49c0 | d_lo);		/* extb.l d_lo */
+			else if (insn->off == 16)
+				emit_16(ctx, 0x48c0 | d_lo);		/* ext.l d_lo */
+
+			emit_16(ctx, 0x4a80 | d_lo);			/* tst.l d_lo */
+			emit_16(ctx, 0x5bc0 | d_hi);			/* smi d_hi */
+			emit_16(ctx, 0x49c0 | d_hi);			/* extb.l d_hi */
+		} else {
+			if (d_lo != s_lo)
+				emit_16(ctx, 0x2000 | (d_lo << 9) | s_lo); /* move.l s_lo, d_lo */
+			if (d_hi != s_hi)
+				emit_16(ctx, 0x2000 | (d_hi << 9) | s_hi); /* move.l s_hi, d_hi */
+		}
+		break;
+	case BPF_ADD:
+		emit_16(ctx, 0xd080 | (d_lo << 9) | s_lo);		/* add.l s_lo, d_lo */
+		emit_16(ctx, 0xd180 | (d_hi << 9) | s_hi);		/* addx.l s_hi, d_hi */
+		break;
+	case BPF_SUB:
+		emit_16(ctx, 0x9080 | (d_lo << 9) | s_lo);		/* sub.l s_lo, d_lo */
+		emit_16(ctx, 0x9180 | (d_hi << 9) | s_hi);		/* subx.l s_hi, d_hi */
+		break;
+	case BPF_AND:
+		emit_16(ctx, 0xc080 | (d_lo << 9) | s_lo);		/* and.l s_lo, d_lo */
+		emit_16(ctx, 0xc080 | (d_hi << 9) | s_hi);		/* and.l s_hi, d_hi */
+		break;
+	case BPF_OR:
+		emit_16(ctx, 0x8080 | (d_lo << 9) | s_lo);		/* or.l s_lo, d_lo */
+		emit_16(ctx, 0x8080 | (d_hi << 9) | s_hi);		/* or.l s_hi, d_hi */
+		break;
+	case BPF_XOR:
+		emit_16(ctx, 0xb180 | (s_lo << 9) | d_lo);		/* eor.l s_lo, d_lo */
+		emit_16(ctx, 0xb180 | (s_hi << 9) | d_hi);		/* eor.l s_hi, d_hi */
+		break;
+	}
+
+	bpf_put_reg32(dst[1], d_lo, ctx);
+	bpf_put_reg32(dst[0], d_hi, ctx);
+}
+
+static void emit_alu64_k(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_lo, d_hi, s_lo, s_hi;
+	u32 imm_lo = insn->imm;
+	u32 imm_hi = insn->imm < 0 ? 0xffffffff : 0;
+
+	d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+
+	if (BPF_OP(insn->code) == BPF_MOV) {
+		emit_16(ctx, 0x203c | (d_lo << 9));			/* move.l #imm, d_lo */
+		emit_32(ctx, imm_lo);
+		emit_16(ctx, 0x203c | (d_hi << 9));			/* move.l #imm, d_hi */
+		emit_32(ctx, imm_hi);
+		bpf_put_reg32(dst[1], d_lo, ctx);
+		bpf_put_reg32(dst[0], d_hi, ctx);
+		return;
+	}
+
+	s_lo = tmp2[1];
+	s_hi = tmp2[0];
+
+	emit_16(ctx, 0x203c | (s_lo << 9));				/* move.l #imm, s_lo */
+	emit_32(ctx, imm_lo);
+	emit_16(ctx, 0x203c | (s_hi << 9));				/* move.l #imm, s_hi */
+	emit_32(ctx, imm_hi);
+
+	switch (BPF_OP(insn->code)) {
+	case BPF_ADD:
+		emit_16(ctx, 0xd080 | (d_lo << 9) | s_lo);		/* add.l s_lo, d_lo */
+		emit_16(ctx, 0xd180 | (d_hi << 9) | s_hi);		/* addx.l s_hi, d_hi */
+		break;
+	case BPF_SUB:
+		emit_16(ctx, 0x9080 | (d_lo << 9) | s_lo);		/* sub.l s_lo, d_lo */
+		emit_16(ctx, 0x9180 | (d_hi << 9) | s_hi);		/* subx.l s_hi, d_hi */
+		break;
+	case BPF_AND:
+		emit_16(ctx, 0xc080 | (d_lo << 9) | s_lo);		/* and.l s_lo, d_lo */
+		emit_16(ctx, 0xc080 | (d_hi << 9) | s_hi);		/* and.l s_hi, d_hi */
+		break;
+	case BPF_OR:
+		emit_16(ctx, 0x8080 | (d_lo << 9) | s_lo);		/* or.l s_lo, d_lo */
+		emit_16(ctx, 0x8080 | (d_hi << 9) | s_hi);		/* or.l s_hi, d_hi */
+		break;
+	case BPF_XOR:
+		emit_16(ctx, 0xb180 | (s_lo << 9) | d_lo);		/* eor.l s_lo, d_lo */
+		emit_16(ctx, 0xb180 | (s_hi << 9) | d_hi);		/* eor.l s_hi, d_hi */
+		break;
+	}
+
+	bpf_put_reg32(dst[1], d_lo, ctx);
+	bpf_put_reg32(dst[0], d_hi, ctx);
+}
+
+static void emit_alu64_shift(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_imm)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_lo, d_hi, count_reg;
+	int loop_start, done_idx;
+
+	d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+	count_reg = tmp2[1];
+
+	if (is_imm) {
+		emit_16(ctx, 0x203c | (count_reg << 9));		/* move.l #imm, count_reg */
+		emit_32(ctx, insn->imm);
+	} else {
+		const s8 *src = bpf2m68k[insn->src_reg];
+		s8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+
+		if (count_reg != s_lo)
+			emit_16(ctx, 0x2000 | (count_reg << 9) | s_lo);	/* move.l s_lo, count_reg */
+	}
+
+	emit_16(ctx, 0x0280 | count_reg);			/* andi.l #0x3f, count_reg */
+	emit_32(ctx, 0x3f);
+
+	emit_16(ctx, 0x4a80 | count_reg);				/* tst.l count_reg */
+	emit_16(ctx, 0x6700);						/* beq.w done_idx */
+	done_idx = ctx->idx;
+	emit_16(ctx, 0);
+
+	loop_start = ctx->idx;
+
+	if (BPF_OP(insn->code) == BPF_LSH) {
+		emit_16(ctx, 0xe388 | d_lo);				/* lsll #1, d_lo */
+		emit_16(ctx, 0xe390 | d_hi);				/* roxl.l #1, d_hi */
+	} else if (BPF_OP(insn->code) == BPF_RSH) {
+		emit_16(ctx, 0xe288 | d_hi);				/* lsrl #1, d_hi */
+		emit_16(ctx, 0xe290 | d_lo);				/* roxr.l #1, d_lo */
+	} else if (BPF_OP(insn->code) == BPF_ARSH) {
+		emit_16(ctx, 0xe280 | d_hi);				/* asrl #1, d_hi */
+		emit_16(ctx, 0xe290 | d_lo);				/* roxr.l #1, d_lo */
+	}
+
+	emit_16(ctx, 0x5380 | count_reg);				/* subq.l #1, count_reg */
+	emit_16(ctx, 0x6600);						/* bne.w loop_start */
+	emit_16(ctx, (loop_start - (int)ctx->idx) * 2);
+
+	if (ctx->target)
+		ctx->target[done_idx] = (ctx->idx - done_idx) * 2;
+
+	bpf_put_reg32(dst[1], d_lo, ctx);
+	bpf_put_reg32(dst[0], d_hi, ctx);
+}
+
+static void emit_bpf_end(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	s8 d_lo, d_hi;
+	bool to_le = BPF_SRC(insn->code) == BPF_TO_LE;
+	int imm = insn->imm;
+
+	d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+
+	if (to_le) {
+		switch (imm) {
+		case 16:
+			emit_16(ctx, 0x0280 | d_lo);			/* andi.l #0xffff, d_lo */
+			emit_32(ctx, 0xffff);
+			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
+			emit_16(ctx, 0x7000 | (d_hi << 9));		/* moveq #0, d_hi */
+			break;
+		case 32:
+			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
+			emit_16(ctx, 0x4840 | d_lo);			/* swap d_lo */
+			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
+			emit_16(ctx, 0x7000 | (d_hi << 9));		/* moveq #0, d_hi */
+			break;
+		case 64:
+			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
+			emit_16(ctx, 0x4840 | d_lo);			/* swap d_lo */
+			emit_16(ctx, 0xe058 | d_lo);			/* ror.w #8, d_lo */
+
+			emit_16(ctx, 0xe058 | d_hi);			/* ror.w #8, d_hi */
+			emit_16(ctx, 0x4840 | d_hi);			/* swap d_hi */
+			emit_16(ctx, 0xe058 | d_hi);			/* ror.w #8, d_hi */
+
+			emit_16(ctx, 0xc140 | (d_hi << 9) | d_lo);	/* exg d_lo, d_hi */
+			break;
+		}
+	} else {
+		switch (imm) {
+		case 16:
+			emit_16(ctx, 0x0280 | d_lo);			/* andi.l #0xffff, d_lo */
+			emit_32(ctx, 0xffff);
+			emit_16(ctx, 0x7000 | (d_hi << 9));		/* moveq #0, d_hi */
+			break;
+		case 32:
+			emit_16(ctx, 0x7000 | (d_hi << 9));		/* moveq #0, d_hi */
+			break;
+		case 64:
+			break;
+		}
+	}
+
+	bpf_put_reg32(dst[1], d_lo, ctx);
+	bpf_put_reg32(dst[0], d_hi, ctx);
+}
+
+static void emit_math_call(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_64)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_lo, d_hi, s_lo, s_hi = 0;
+	void *func = NULL;
+	u8 op = BPF_OP(insn->code);
+
+	d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+
+	if (BPF_SRC(insn->code) == BPF_X) {
+		s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+		if (is_64)
+			s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);
+	} else {
+		s_lo = tmp2[1];
+		emit_16(ctx, 0x203c | (s_lo << 9));			/* move.l #imm, s_lo */
+		emit_32(ctx, insn->imm);
+		if (is_64) {
+			s_hi = tmp2[0];
+			emit_16(ctx, 0x203c | (s_hi << 9));		/* move.l #imm, s_hi */
+			emit_32(ctx, insn->imm < 0 ? 0xffffffff : 0);
+		}
+	}
+
+	if (is_64) {
+		switch (op) {
+		case BPF_MUL:
+			func = (void *)jit_mul64;
+			break;
+		case BPF_DIV:
+			func = (void *)jit_div64;
+			break;
+		case BPF_MOD:
+			func = (void *)jit_mod64;
+			break;
+		}
+		if (BPF_CLASS(insn->code) == BPF_ALU64 && op == BPF_DIV && insn->off == 1)
+			func = (void *)jit_sdiv64;
+		if (BPF_CLASS(insn->code) == BPF_ALU64 && op == BPF_MOD && insn->off == 1)
+			func = (void *)jit_smod64;
+	} else {
+		switch (op) {
+		case BPF_MUL:
+			func = (void *)jit_mul32;
+			break;
+		case BPF_DIV:
+			func = (void *)jit_div32;
+			break;
+		case BPF_MOD:
+			func = (void *)jit_mod32;
+			break;
+		}
+		if (BPF_CLASS(insn->code) == BPF_ALU && op == BPF_DIV && insn->off == 1)
+			func = (void *)jit_sdiv32;
+		if (BPF_CLASS(insn->code) == BPF_ALU && op == BPF_MOD && insn->off == 1)
+			func = (void *)jit_smod32;
+	}
+
+	if (is_64) {
+		emit_16(ctx, 0x48e7);					/* movem.l d0-d1, -(%sp) */
+		emit_16(ctx, 0xc000);
+
+		emit_16(ctx, 0x2f00 | s_lo);				/* move.l s_lo, -(%sp) */
+		emit_16(ctx, 0x2f00 | s_hi);				/* move.l s_hi, -(%sp) */
+		emit_16(ctx, 0x2f00 | d_lo);				/* move.l d_lo, -(%sp) */
+		emit_16(ctx, 0x2f00 | d_hi);				/* move.l d_hi, -(%sp) */
+
+		emit_16(ctx, 0x207c);					/* movea.l #func, %a0 */
+		emit_32(ctx, (u32)func);
+		emit_16(ctx, 0x4e90);					/* jsr (%a0) */
+
+		emit_16(ctx, 0x4fef);					/* lea 16(%sp), %sp */
+		emit_16(ctx, 16);
+
+		emit_16(ctx, 0x2601);					/* move.l %d1, %d3 */
+		emit_16(ctx, 0x2400);					/* move.l %d0, %d2 */
+
+		emit_16(ctx, 0x4cdf);					/* movem.l (%sp)+, d0-d1 */
+		emit_16(ctx, 0x0003);
+	} else {
+		emit_16(ctx, 0x48e7);					/* movem.l d0-d1, -(%sp) */
+		emit_16(ctx, 0xc000);
+
+		emit_16(ctx, 0x2f00 | s_lo);				/* move.l s_lo, -(%sp) */
+		emit_16(ctx, 0x2f00 | d_lo);				/* move.l d_lo, -(%sp) */
+
+		emit_16(ctx, 0x207c);					/* movea.l #func, %a0 */
+		emit_32(ctx, (u32)func);
+		emit_16(ctx, 0x4e90);					/* jsr (%a0) */
+
+		emit_16(ctx, 0x4fef);					/* lea 8(%sp), %sp */
+		emit_16(ctx, 8);
+
+		emit_16(ctx, 0x2600);					/* move.l %d0, %d3 */
+		emit_16(ctx, 0x7400);					/* moveq #0, %d2 */
+
+		emit_16(ctx, 0x4cdf);					/* movem.l (%sp)+, d0-d1 */
+		emit_16(ctx, 0x0003);
+	}
+
+	bpf_put_reg32(dst[1], M68K_D3, ctx);
+	bpf_put_reg32(dst[0], M68K_D2, ctx);
+}
+
+static void emit_ldx(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	s8 d_lo, d_hi;
+	bool is_mem_sx = BPF_MODE(insn->code) == BPF_MEMSX;
+
+	if (is_stacked(src[1])) {
+		emit_16(ctx, 0x206e);				/* movea.l d16(%fp), %a0 */
+		emit_16(ctx, (u16)src[1]);
+	} else {
+		emit_16(ctx, 0x2040 | src[1]);			/* movea.l src, %a0 */
+	}
+
+	d_lo = is_stacked(dst[1]) ? tmp1[1] : dst[1];
+	d_hi = is_stacked(dst[0]) ? tmp1[0] : dst[0];
+
+	switch (BPF_SIZE(insn->code)) {
+	case BPF_B:
+		if (!is_mem_sx)
+			emit_16(ctx, 0x7000 | (d_lo << 9));	/* moveq #0, d_lo */
+		emit_16(ctx, 0x1028 | (d_lo << 9));		/* move.b d16(%a0), d_lo */
+		emit_16(ctx, insn->off);
+		if (is_mem_sx)
+			emit_16(ctx, 0x49c0 | d_lo);	/* extb.l d_lo */
+		break;
+	case BPF_H:
+		if (!is_mem_sx)
+			emit_16(ctx, 0x7000 | (d_lo << 9));	/* moveq #0, d_lo */
+		emit_16(ctx, 0x3028 | (d_lo << 9));		/* move.w d16(%a0), d_lo */
+		emit_16(ctx, insn->off);
+		if (is_mem_sx)
+			emit_16(ctx, 0x48c0 | d_lo);	/* ext.l d_lo */
+		break;
+	case BPF_W:
+		emit_16(ctx, 0x2028 | (d_lo << 9));		/* move.l d16(%a0), d_lo */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_DW:
+		emit_16(ctx, 0x2028 | (d_hi << 9));		/* move.l d16(%a0), d_hi */
+		emit_16(ctx, insn->off);
+		emit_16(ctx, 0x41e8);				/* lea 4(%a0), %a0 */
+		emit_16(ctx, 4);
+		emit_16(ctx, 0x2028 | (d_lo << 9));		/* move.l d16(%a0), d_lo */
+		emit_16(ctx, insn->off);
+		break;
+	}
+
+	if (BPF_SIZE(insn->code) != BPF_DW) {
+		if (is_mem_sx) {
+			emit_16(ctx, 0x4a80 | d_lo);			/* tst.l d_lo */
+			emit_16(ctx, 0x5bc0 | d_hi);			/* smi d_hi */
+			emit_16(ctx, 0x49c0 | d_hi);			/* extb.l d_hi */
+		} else {
+			emit_16(ctx, 0x7000 | (d_hi << 9));	/* moveq #0, d_hi */
+		}
+	}
+
+	bpf_put_reg32(dst[1], d_lo, ctx);
+	bpf_put_reg32(dst[0], d_hi, ctx);
+}
+
+static void emit_stx(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 s_lo, s_hi;
+
+	if (is_stacked(dst[1])) {
+		emit_16(ctx, 0x206e);				/* movea.l d16(%fp), %a0 */
+		emit_16(ctx, (u16)dst[1]);
+	} else {
+		emit_16(ctx, 0x2040 | dst[1]);			/* movea.l dst, %a0 */
+	}
+
+	s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+
+	switch (BPF_SIZE(insn->code)) {
+	case BPF_B:
+		emit_16(ctx, 0x1140 | s_lo);			/* move.b s_lo, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_H:
+		emit_16(ctx, 0x3140 | s_lo);			/* move.w s_lo, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_W:
+		emit_16(ctx, 0x2140 | s_lo);			/* move.l s_lo, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_DW:
+		s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);
+		emit_16(ctx, 0x2140 | s_hi);			/* move.l s_hi, d16(%a0) */
+		emit_16(ctx, insn->off);
+		emit_16(ctx, 0x41e8);				/* lea 4(%a0), %a0 */
+		emit_16(ctx, 4);
+		emit_16(ctx, 0x2140 | s_lo);			/* move.l s_lo, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	}
+}
+
+static void emit_st(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *tmp = bpf2m68k[TMP_REG_1];
+
+	if (is_stacked(dst[1])) {
+		emit_16(ctx, 0x206e);				/* movea.l d16(%fp), %a0 */
+		emit_16(ctx, (u16)dst[1]);
+	} else {
+		emit_16(ctx, 0x2040 | dst[1]);			/* movea.l dst, %a0 */
+	}
+
+	emit_16(ctx, 0x203c | (tmp[1] << 9));			/* move.l #imm, tmp */
+	emit_32(ctx, insn->imm);
+
+	switch (BPF_SIZE(insn->code)) {
+	case BPF_B:
+		emit_16(ctx, 0x1140 | tmp[1]);			/* move.b tmp, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_H:
+		emit_16(ctx, 0x3140 | tmp[1]);			/* move.w tmp, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_W:
+		emit_16(ctx, 0x2140 | tmp[1]);			/* move.l tmp, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	case BPF_DW:
+		emit_16(ctx, 0x203c | (tmp[0] << 9));		/* move.l #imm, tmp */
+		emit_32(ctx, insn->imm < 0 ? 0xffffffff : 0);
+
+		emit_16(ctx, 0x2140 | tmp[0]);			/* move.l tmp, d16(%a0) */
+		emit_16(ctx, insn->off);
+		emit_16(ctx, 0x41e8);				/* lea 4(%a0), %a0 */
+		emit_16(ctx, 4);
+		emit_16(ctx, 0x2140 | tmp[1]);			/* move.l tmp, d16(%a0) */
+		emit_16(ctx, insn->off);
+		break;
+	}
+}
+
+static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+
+	if (is_stacked(dst[1])) {
+		emit_16(ctx, 0x206e);				/* movea.l d16(%fp), %a0 */
+		emit_16(ctx, (u16)dst[1]);
+	} else {
+		emit_16(ctx, 0x2040 | dst[1]);			/* movea.l dst, %a0 */
+	}
+
+	if (insn->off) {
+		emit_16(ctx, 0x41e8);				/* lea d16(%a0), %a0 */
+		emit_16(ctx, insn->off);
+	}
+
+	if (BPF_SIZE(insn->code) == BPF_W) {
+		s8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+
+		if (insn->imm != BPF_CMPXCHG) {
+			emit_16(ctx, 0x48e7);			/* movem.l d0-d1, -(%sp) */
+			emit_16(ctx, 0xc000);
+		}
+
+		emit_16(ctx, 0x2f00 | M68K_D0);			/* move.l %d0, -(%sp) */
+		emit_16(ctx, 0x2f3c);				/* move.l #imm, -(%sp) */
+		emit_32(ctx, insn->imm);
+		emit_16(ctx, 0x2f00 | s_lo);			/* move.l s_lo, -(%sp) */
+		emit_16(ctx, 0x2f08);				/* move.l %a0, -(%sp) */
+
+		emit_16(ctx, 0x207c);				/* movea.l #func, %a0 */
+		emit_32(ctx, (u32)jit_atomic32);
+		emit_16(ctx, 0x4e90);				/* jsr (%a0) */
+
+		emit_16(ctx, 0x4fef);				/* lea 16(%sp), %sp */
+		emit_16(ctx, 16);
+
+		if (insn->imm == BPF_CMPXCHG) {
+			emit_16(ctx, 0x7200);			/* moveq #0, %d1 */
+		} else {
+			bool is_fetch = (insn->imm & BPF_FETCH) || insn->imm == BPF_XCHG;
+
+			if (is_fetch)
+				emit_16(ctx, 0x2600);		/* move.l %d0, %d3 */
+
+			emit_16(ctx, 0x4cdf);			/* movem.l (%sp)+, d0-d1 */
+			emit_16(ctx, 0x0003);
+
+			if (is_fetch) {
+				bpf_put_reg32(src[1], M68K_D3, ctx);
+				emit_16(ctx, 0x7400);		/* moveq #0, %d2 */
+				bpf_put_reg32(src[0], M68K_D2, ctx);
+			}
+		}
+
+	} else if (BPF_SIZE(insn->code) == BPF_DW) {
+		s8 s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+		s8 s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);
+
+		if (insn->imm != BPF_CMPXCHG) {
+			emit_16(ctx, 0x48e7);			/* movem.l d0-d1, -(%sp) */
+			emit_16(ctx, 0xc000);
+		}
+
+		emit_16(ctx, 0x2f00 | M68K_D0);			/* move.l %d0, -(%sp) */
+		emit_16(ctx, 0x2f00 | M68K_D1);			/* move.l %d1, -(%sp) */
+		emit_16(ctx, 0x2f3c);				/* move.l #imm, -(%sp) */
+		emit_32(ctx, insn->imm);
+		emit_16(ctx, 0x2f00 | s_lo);			/* move.l s_lo, -(%sp) */
+		emit_16(ctx, 0x2f00 | s_hi);			/* move.l s_hi, -(%sp) */
+		emit_16(ctx, 0x2f08);				/* move.l %a0, -(%sp) */
+
+		emit_16(ctx, 0x207c);				/* movea.l #func, %a0 */
+		emit_32(ctx, (u32)jit_atomic64);
+		emit_16(ctx, 0x4e90);				/* jsr (%a0) */
+
+		emit_16(ctx, 0x4fef);				/* lea 24(%sp), %sp */
+		emit_16(ctx, 24);
+
+		if (insn->imm == BPF_CMPXCHG) {
+			emit_16(ctx, 0xc141);			/* exg %d0, %d1 */
+		} else {
+			bool is_fetch = (insn->imm & BPF_FETCH) || insn->imm == BPF_XCHG;
+
+			if (is_fetch) {
+				emit_16(ctx, 0x2600);		/* move.l %d0, %d3 */
+				emit_16(ctx, 0x2401);		/* move.l %d1, %d2 */
+			}
+
+			emit_16(ctx, 0x4cdf);			/* movem.l (%sp)+, d0-d1 */
+			emit_16(ctx, 0x0003);
+
+			if (is_fetch) {
+				bpf_put_reg32(src[1], M68K_D2, ctx);
+				bpf_put_reg32(src[0], M68K_D3, ctx);
+			}
+		}
+	}
+}
+
+static void emit_tail_call(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 *r2 = bpf2m68k[BPF_REG_2];
+	const s8 *r3 = bpf2m68k[BPF_REG_3];
+	int jmp_out_1, jmp_out_2, jmp_out_3;
+
+	if (is_stacked(r2[1])) {
+		emit_16(ctx, 0x206e);				/* movea.l d16(%fp), %a0 */
+		emit_16(ctx, (u16)r2[1]);
+	} else {
+		emit_16(ctx, 0x2040 | r2[1]);			/* movea.l r2, %a0 */
+	}
+
+	if (is_stacked(r3[1])) {
+		emit_16(ctx, 0x242e);				/* move.l d16(%fp), %d2 */
+		emit_16(ctx, (u16)r3[1]);
+	} else {
+		emit_16(ctx, 0x2400 | r3[1]);			/* move.l r3, %d2 */
+	}
+
+	emit_16(ctx, 0xb4a8);					/* cmp.l d16(%a0), %d2 */
+	emit_16(ctx, offsetof(struct bpf_array, map.max_entries));
+	emit_16(ctx, 0x6400);					/* bcc.w jmp_out_1 */
+	jmp_out_1 = ctx->idx;
+	emit_16(ctx, 0);
+
+	emit_16(ctx, 0x262e);					/* move.l d16(%fp), %d3 */
+	emit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));
+	emit_16(ctx, 0x4a83);					/* tst.l %d3 */
+	emit_16(ctx, 0x6700);					/* beq.w jmp_out_2 */
+	jmp_out_2 = ctx->idx;
+	emit_16(ctx, 0);
+
+	emit_16(ctx, 0x5383);					/* subq.l #1, %d3 */
+	emit_16(ctx, 0x2d43);					/* move.l %d3, d16(%fp) */
+	emit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));
+
+	emit_16(ctx, 0xd482);					/* add.l %d2, %d2 */
+	emit_16(ctx, 0xd482);					/* add.l %d2, %d2 */
+	emit_16(ctx, 0x43e8);					/* lea d16(%a0), %a1 */
+	emit_16(ctx, offsetof(struct bpf_array, ptrs));
+	emit_16(ctx, 0xd3c2);					/* adda.l %d2, %a1 */
+
+	emit_16(ctx, 0x2051);					/* movea.l (%a1), %a0 */
+
+	emit_16(ctx, 0x2408);					/* move.l %a0, %d2 */
+	emit_16(ctx, 0x4a82);					/* tst.l %d2 */
+	emit_16(ctx, 0x6700);					/* beq.w jmp_out_3 */
+	jmp_out_3 = ctx->idx;
+	emit_16(ctx, 0);
+
+	emit_16(ctx, 0x2068);					/* movea.l d16(%a0), %a0 */
+	emit_16(ctx, offsetof(struct bpf_prog, bpf_func));
+
+	emit_16(ctx, 0x4ee8);					/* jmp d16(%a0) */
+	emit_16(ctx, 44);
+
+	if (ctx->target) {
+		ctx->target[jmp_out_1] = (ctx->idx - jmp_out_1) * 2;
+		ctx->target[jmp_out_2] = (ctx->idx - jmp_out_2) * 2;
+		ctx->target[jmp_out_3] = (ctx->idx - jmp_out_3) * 2;
+	}
+}
+
+static int emit_jmp(const struct bpf_insn *insn, struct jit_ctx *ctx, int curr_i)
+{
+	const s8 *dst = bpf2m68k[insn->dst_reg];
+	const s8 *src = bpf2m68k[insn->src_reg];
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	const s8 *tmp2 = bpf2m68k[TMP_REG_2];
+	s8 d_lo, d_hi = 0, s_lo, s_hi = 0;
+	bool is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
+	u8 op = BPF_OP(insn->code);
+	int target_insn;
+
+	if (is_jmp32 && op == BPF_JA)
+		target_insn = curr_i + 1 + insn->imm;
+	else
+		target_insn = curr_i + 1 + insn->off;
+
+	if (target_insn < 0 || target_insn > ctx->prog->len)
+		return -EOPNOTSUPP;
+
+	#define EMIT_JMP32(op_base) \
+		do { \
+			int disp = (ctx->offsets[target_insn] - (ctx->idx + 1)) * 2; \
+			emit_16(ctx, (op_base) | 0x00ff); \
+			emit_32(ctx, disp); \
+		} while (0)
+
+	if (op == BPF_JA) {
+		EMIT_JMP32(0x6000);				/* bra.l */
+		return 0;
+	}
+
+	d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+	if (!is_jmp32)
+		d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+
+	if (BPF_SRC(insn->code) == BPF_X) {
+		s_lo = bpf_get_reg32(src[1], tmp2[1], ctx);
+		if (!is_jmp32)
+			s_hi = bpf_get_reg32(src[0], tmp2[0], ctx);
+	} else {
+		s_lo = tmp2[1];
+		emit_16(ctx, 0x203c | (s_lo << 9));		/* move.l #imm, s_lo */
+		emit_32(ctx, insn->imm);
+		if (!is_jmp32) {
+			s_hi = tmp2[0];
+			emit_16(ctx, 0x203c | (s_hi << 9));	/* move.l #imm, s_hi */
+			emit_32(ctx, insn->imm < 0 ? 0xffffffff : 0);
+		}
+	}
+
+	if (op == BPF_JSET) {
+		emit_16(ctx, 0x2000 | (tmp1[1] << 9) | d_lo);	/* move.l d_lo, tmp1_lo */
+		emit_16(ctx, 0xc080 | (tmp1[1] << 9) | s_lo);	/* and.l s_lo, tmp1_lo */
+
+		if (!is_jmp32) {
+			EMIT_JMP32(0x6600);			/* bne.l */
+			emit_16(ctx, 0x2000 | (tmp1[0] << 9) | d_hi); /* move.l d_hi, tmp1_hi */
+			emit_16(ctx, 0xc080 | (tmp1[0] << 9) | s_hi); /* and.l s_hi, tmp1_hi */
+		}
+		EMIT_JMP32(0x6600);				/* bne.l */
+		return 0;
+	}
+
+	if (is_jmp32) {
+		emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo);	/* cmp.l s_lo, d_lo */
+		switch (op) {
+		case BPF_JEQ:
+			EMIT_JMP32(0x6700);			/* beq.l */
+			break;
+		case BPF_JNE:
+			EMIT_JMP32(0x6600);			/* bne.l */
+			break;
+		case BPF_JGT:
+			EMIT_JMP32(0x6200);			/* bhi.l */
+			break;
+		case BPF_JGE:
+			EMIT_JMP32(0x6400);			/* bcc.l */
+			break;
+		case BPF_JLT:
+			EMIT_JMP32(0x6500);			/* bcs.l */
+			break;
+		case BPF_JLE:
+			EMIT_JMP32(0x6300);			/* bls.l */
+			break;
+		case BPF_JSGT:
+			EMIT_JMP32(0x6e00);			/* bgt.l */
+			break;
+		case BPF_JSGE:
+			EMIT_JMP32(0x6c00);			/* bge.l */
+			break;
+		case BPF_JSLT:
+			EMIT_JMP32(0x6d00);			/* blt.l */
+			break;
+		case BPF_JSLE:
+			EMIT_JMP32(0x6f00);			/* ble.l */
+			break;
+		}
+	} else {
+		emit_16(ctx, 0xb080 | (d_hi << 9) | s_hi);	/* cmp.l s_hi, d_hi */
+
+		switch (op) {
+		case BPF_JEQ:
+			emit_16(ctx, 0x6608);			/* bne.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6700);			/* beq.l */
+			break;
+		case BPF_JNE:
+			EMIT_JMP32(0x6600);			/* bne.l */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6600);			/* bne.l */
+			break;
+		case BPF_JGT:
+			EMIT_JMP32(0x6200);			/* bhi.l */
+			emit_16(ctx, 0x6508);			/* bcs.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6200);			/* bhi.l */
+			break;
+		case BPF_JGE:
+			EMIT_JMP32(0x6200);			/* bhi.l */
+			emit_16(ctx, 0x6508);			/* bcs.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6400);			/* bcc.l */
+			break;
+		case BPF_JLT:
+			EMIT_JMP32(0x6500);			/* bcs.l */
+			emit_16(ctx, 0x6208);			/* bhi.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6500);			/* bcs.l */
+			break;
+		case BPF_JLE:
+			EMIT_JMP32(0x6500);			/* bcs.l */
+			emit_16(ctx, 0x6208);			/* bhi.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6300);			/* bls.l */
+			break;
+		case BPF_JSGT:
+			EMIT_JMP32(0x6e00);			/* bgt.l */
+			emit_16(ctx, 0x6d08);			/* blt.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6200);			/* bhi.l */
+			break;
+		case BPF_JSGE:
+			EMIT_JMP32(0x6e00);			/* bgt.l */
+			emit_16(ctx, 0x6d08);			/* blt.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6400);			/* bcc.l */
+			break;
+		case BPF_JSLT:
+			EMIT_JMP32(0x6d00);			/* blt.l */
+			emit_16(ctx, 0x6e08);			/* bgt.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6500);			/* bcs.l */
+			break;
+		case BPF_JSLE:
+			EMIT_JMP32(0x6d00);			/* blt.l */
+			emit_16(ctx, 0x6e08);			/* bgt.s .+8 */
+			emit_16(ctx, 0xb080 | (d_lo << 9) | s_lo); /* cmp.l s_lo, d_lo */
+			EMIT_JMP32(0x6300);			/* bls.l */
+			break;
+		}
+	}
+	#undef EMIT_JMP32
+	return 0;
+}
+
+static int emit_call(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const s8 arg_regs[] = { BPF_REG_5, BPF_REG_4, BPF_REG_3, BPF_REG_2, BPF_REG_1 };
+	const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+	bool extra_pass = ctx->prog->jited;
+	u64 func_addr;
+	bool fixed;
+	int i, err;
+
+	err = bpf_jit_get_func_addr(ctx->prog, insn, extra_pass, &func_addr, &fixed);
+	if (err)
+		return err;
+
+	for (i = 0; i < 5; i++) {
+		const s8 *reg = bpf2m68k[arg_regs[i]];
+		s8 d_lo = bpf_get_reg32(reg[1], tmp1[1], ctx);
+		s8 d_hi = bpf_get_reg32(reg[0], tmp1[0], ctx);
+
+		emit_16(ctx, 0x2f00 | d_lo);			/* move.l d_lo, -(%sp) */
+		emit_16(ctx, 0x2f00 | d_hi);			/* move.l d_hi, -(%sp) */
+	}
+
+	emit_16(ctx, 0x207c);					/* movea.l #func_addr, %a0 */
+	emit_32(ctx, (u32)func_addr);
+
+	emit_16(ctx, 0x4e90);					/* jsr (%a0) */
+
+	emit_16(ctx, 0x4fef);					/* lea 40(%sp), %sp */
+	emit_16(ctx, 40);
+
+	if (insn->src_reg != BPF_PSEUDO_CALL)
+		emit_16(ctx, 0xc340);					/* exg %d0, %d1 */
+
+	return 0;
+}
+
+static void build_prologue(struct jit_ctx *ctx)
+{
+	int bpf_stack = MAX_BPF_STACK;
+	int total_stack = SCRATCH_SIZE + bpf_stack;
+	int i;
+
+	emit_16(ctx, 0x7021);					/* moveq #33, %d0 */
+
+	emit_16(ctx, 0x4e56);					/* link %a6, #-total_stack */
+	emit_16(ctx, -total_stack);
+
+	emit_16(ctx, 0x48e7);					/* movem.l d2-d5, -(%sp) */
+	emit_16(ctx, 0x3c00);
+
+	emit_16(ctx, 0x2d40);					/* move.l %d0, off(%fp) */
+	emit_16(ctx, (u16)STACK_OFFSET(BPF_TC_LO));
+
+	if (ctx->prog->is_func) {
+		const s8 arg_regs[] = { BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5 };
+
+		for (i = 0; i < 5; i++) {
+			int offset = 8 + i * 8;
+			const s8 *reg = bpf2m68k[arg_regs[i]];
+
+			emit_16(ctx, 0x202e); /* move.l offset(%fp), %d0 */
+			emit_16(ctx, offset);
+			bpf_put_reg32(reg[0], M68K_D0, ctx);
+
+			emit_16(ctx, 0x202e); /* move.l offset+4(%fp), %d0 */
+			emit_16(ctx, offset + 4);
+			bpf_put_reg32(reg[1], M68K_D0, ctx);
+		}
+	} else {
+		emit_16(ctx, 0x202e);				/* move.l 8(%fp), %d0 */
+		emit_16(ctx, 8);
+		bpf_put_reg32(bpf2m68k[BPF_REG_1][1], M68K_D0, ctx);
+
+		emit_16(ctx, 0x7000 | (M68K_D0 << 9));			/* moveq #0, %d0 */
+		bpf_put_reg32(bpf2m68k[BPF_REG_1][0], M68K_D0, ctx);
+	}
+
+	emit_16(ctx, 0x41ee);					/* lea -SCRATCH_SIZE(%fp), %a0 */
+	emit_16(ctx, -SCRATCH_SIZE);
+	emit_16(ctx, 0x2008);					/* move.l %a0, %d0 */
+
+	bpf_put_reg32(bpf2m68k[BPF_REG_10][1], M68K_D0, ctx);
+	emit_16(ctx, 0x7000 | (M68K_D0 << 9));			/* moveq #0, %d0 */
+	bpf_put_reg32(bpf2m68k[BPF_REG_10][0], M68K_D0, ctx);
+}
+
+static void build_epilogue(struct jit_ctx *ctx)
+{
+	emit_16(ctx, 0x4cdf);					/* movem.l (%sp)+, d2-d5 */
+	emit_16(ctx, 0x003c);
+
+	emit_16(ctx, 0x4e5e);					/* unlk %fp */
+	emit_16(ctx, 0x4e75);					/* rts */
+}
+
+static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, int i)
+{
+	u8 code = insn->code;
+
+	switch (code) {
+	case BPF_ALU | BPF_NEG:
+		emit_alu32_neg(insn, ctx);
+		break;
+	case BPF_ALU64 | BPF_NEG:
+		emit_alu64_neg(insn, ctx);
+		break;
+
+	case BPF_ALU | BPF_MOV | BPF_X:
+	case BPF_ALU | BPF_ADD | BPF_X:
+	case BPF_ALU | BPF_SUB | BPF_X:
+	case BPF_ALU | BPF_AND | BPF_X:
+	case BPF_ALU | BPF_OR  | BPF_X:
+	case BPF_ALU | BPF_XOR | BPF_X:
+	case BPF_ALU | BPF_LSH | BPF_X:
+	case BPF_ALU | BPF_RSH | BPF_X:
+	case BPF_ALU | BPF_ARSH | BPF_X:
+		emit_alu32_x(insn, ctx);
+		break;
+
+	case BPF_ALU | BPF_MOV | BPF_K:
+	case BPF_ALU | BPF_ADD | BPF_K:
+	case BPF_ALU | BPF_SUB | BPF_K:
+	case BPF_ALU | BPF_AND | BPF_K:
+	case BPF_ALU | BPF_OR  | BPF_K:
+	case BPF_ALU | BPF_XOR | BPF_K:
+	case BPF_ALU | BPF_LSH | BPF_K:
+	case BPF_ALU | BPF_RSH | BPF_K:
+	case BPF_ALU | BPF_ARSH | BPF_K:
+		emit_alu32_k(insn, ctx);
+		break;
+
+	case BPF_ALU64 | BPF_MOV | BPF_X:
+	case BPF_ALU64 | BPF_ADD | BPF_X:
+	case BPF_ALU64 | BPF_SUB | BPF_X:
+	case BPF_ALU64 | BPF_AND | BPF_X:
+	case BPF_ALU64 | BPF_OR  | BPF_X:
+	case BPF_ALU64 | BPF_XOR | BPF_X:
+		emit_alu64_x(insn, ctx);
+		break;
+
+	case BPF_ALU64 | BPF_MOV | BPF_K:
+	case BPF_ALU64 | BPF_ADD | BPF_K:
+	case BPF_ALU64 | BPF_SUB | BPF_K:
+	case BPF_ALU64 | BPF_AND | BPF_K:
+	case BPF_ALU64 | BPF_OR  | BPF_K:
+	case BPF_ALU64 | BPF_XOR | BPF_K:
+		emit_alu64_k(insn, ctx);
+		break;
+
+	case BPF_ALU64 | BPF_LSH | BPF_X:
+	case BPF_ALU64 | BPF_RSH | BPF_X:
+	case BPF_ALU64 | BPF_ARSH | BPF_X:
+		emit_alu64_shift(insn, ctx, false);
+		break;
+
+	case BPF_ALU64 | BPF_LSH | BPF_K:
+	case BPF_ALU64 | BPF_RSH | BPF_K:
+	case BPF_ALU64 | BPF_ARSH | BPF_K:
+		emit_alu64_shift(insn, ctx, true);
+		break;
+
+	case BPF_ALU | BPF_MUL | BPF_X:
+	case BPF_ALU | BPF_DIV | BPF_X:
+	case BPF_ALU | BPF_MOD | BPF_X:
+	case BPF_ALU | BPF_MUL | BPF_K:
+	case BPF_ALU | BPF_DIV | BPF_K:
+	case BPF_ALU | BPF_MOD | BPF_K:
+		emit_math_call(insn, ctx, false);
+		break;
+
+	case BPF_ALU64 | BPF_MUL | BPF_X:
+	case BPF_ALU64 | BPF_DIV | BPF_X:
+	case BPF_ALU64 | BPF_MOD | BPF_X:
+	case BPF_ALU64 | BPF_MUL | BPF_K:
+	case BPF_ALU64 | BPF_DIV | BPF_K:
+	case BPF_ALU64 | BPF_MOD | BPF_K:
+		emit_math_call(insn, ctx, true);
+		break;
+
+	case BPF_ALU | BPF_END | BPF_TO_BE:
+	case BPF_ALU | BPF_END | BPF_TO_LE:
+	case BPF_ALU64 | BPF_END | BPF_TO_BE:
+	case BPF_ALU64 | BPF_END | BPF_TO_LE:
+		emit_bpf_end(insn, ctx);
+		break;
+
+	case BPF_LD | BPF_IMM | BPF_DW: {
+		const struct bpf_insn *insn1 = insn + 1;
+		const s8 *dst = bpf2m68k[insn->dst_reg];
+		const s8 *tmp1 = bpf2m68k[TMP_REG_1];
+		s8 d_lo = bpf_get_reg32(dst[1], tmp1[1], ctx);
+		s8 d_hi = bpf_get_reg32(dst[0], tmp1[0], ctx);
+
+		emit_16(ctx, 0x203c | (d_lo << 9));			/* move.l #imm, d_lo */
+		emit_32(ctx, insn->imm);
+		emit_16(ctx, 0x203c | (d_hi << 9));			/* move.l #imm, d_hi */
+		emit_32(ctx, insn1->imm);
+
+		bpf_put_reg32(dst[1], d_lo, ctx);
+		bpf_put_reg32(dst[0], d_hi, ctx);
+		break;
+	}
+
+	case BPF_LDX | BPF_MEM | BPF_B:
+	case BPF_LDX | BPF_MEM | BPF_H:
+	case BPF_LDX | BPF_MEM | BPF_W:
+	case BPF_LDX | BPF_MEM | BPF_DW:
+	case BPF_LDX | BPF_MEMSX | BPF_B:
+	case BPF_LDX | BPF_MEMSX | BPF_H:
+	case BPF_LDX | BPF_MEMSX | BPF_W:
+		emit_ldx(insn, ctx);
+		break;
+
+	case BPF_STX | BPF_MEM | BPF_B:
+	case BPF_STX | BPF_MEM | BPF_H:
+	case BPF_STX | BPF_MEM | BPF_W:
+	case BPF_STX | BPF_MEM | BPF_DW:
+		emit_stx(insn, ctx);
+		break;
+
+	case BPF_ST | BPF_MEM | BPF_B:
+	case BPF_ST | BPF_MEM | BPF_H:
+	case BPF_ST | BPF_MEM | BPF_W:
+	case BPF_ST | BPF_MEM | BPF_DW:
+		emit_st(insn, ctx);
+		break;
+
+	case BPF_STX | BPF_ATOMIC | BPF_W:
+	case BPF_STX | BPF_ATOMIC | BPF_DW:
+		emit_atomic(insn, ctx);
+		break;
+
+	case BPF_JMP | BPF_TAIL_CALL:
+		emit_tail_call(insn, ctx);
+		break;
+
+	case BPF_JMP | BPF_JA:
+	case BPF_JMP32 | BPF_JA:
+	case BPF_JMP | BPF_JEQ | BPF_X:
+	case BPF_JMP | BPF_JEQ | BPF_K:
+	case BPF_JMP | BPF_JNE | BPF_X:
+	case BPF_JMP | BPF_JNE | BPF_K:
+	case BPF_JMP | BPF_JGT | BPF_X:
+	case BPF_JMP | BPF_JGT | BPF_K:
+	case BPF_JMP | BPF_JGE | BPF_X:
+	case BPF_JMP | BPF_JGE | BPF_K:
+	case BPF_JMP | BPF_JLT | BPF_X:
+	case BPF_JMP | BPF_JLT | BPF_K:
+	case BPF_JMP | BPF_JLE | BPF_X:
+	case BPF_JMP | BPF_JLE | BPF_K:
+	case BPF_JMP | BPF_JSGT | BPF_X:
+	case BPF_JMP | BPF_JSGT | BPF_K:
+	case BPF_JMP | BPF_JSGE | BPF_X:
+	case BPF_JMP | BPF_JSGE | BPF_K:
+	case BPF_JMP | BPF_JSLT | BPF_X:
+	case BPF_JMP | BPF_JSLT | BPF_K:
+	case BPF_JMP | BPF_JSLE | BPF_X:
+	case BPF_JMP | BPF_JSLE | BPF_K:
+	case BPF_JMP | BPF_JSET | BPF_X:
+	case BPF_JMP | BPF_JSET | BPF_K:
+	case BPF_JMP32 | BPF_JEQ | BPF_X:
+	case BPF_JMP32 | BPF_JEQ | BPF_K:
+	case BPF_JMP32 | BPF_JNE | BPF_X:
+	case BPF_JMP32 | BPF_JNE | BPF_K:
+	case BPF_JMP32 | BPF_JGT | BPF_X:
+	case BPF_JMP32 | BPF_JGT | BPF_K:
+	case BPF_JMP32 | BPF_JGE | BPF_X:
+	case BPF_JMP32 | BPF_JGE | BPF_K:
+	case BPF_JMP32 | BPF_JLT | BPF_X:
+	case BPF_JMP32 | BPF_JLT | BPF_K:
+	case BPF_JMP32 | BPF_JLE | BPF_X:
+	case BPF_JMP32 | BPF_JLE | BPF_K:
+	case BPF_JMP32 | BPF_JSGT | BPF_X:
+	case BPF_JMP32 | BPF_JSGT | BPF_K:
+	case BPF_JMP32 | BPF_JSGE | BPF_X:
+	case BPF_JMP32 | BPF_JSGE | BPF_K:
+	case BPF_JMP32 | BPF_JSLT | BPF_X:
+	case BPF_JMP32 | BPF_JSLT | BPF_K:
+	case BPF_JMP32 | BPF_JSLE | BPF_X:
+	case BPF_JMP32 | BPF_JSLE | BPF_K:
+	case BPF_JMP32 | BPF_JSET | BPF_X:
+	case BPF_JMP32 | BPF_JSET | BPF_K:
+		return emit_jmp(insn, ctx, i);
+
+	case BPF_JMP | BPF_CALL:
+		return emit_call(insn, ctx);
+
+	case BPF_JMP | BPF_EXIT:
+		build_epilogue(ctx);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static int build_body(struct jit_ctx *ctx)
+{
+	const struct bpf_prog *prog = ctx->prog;
+	int i;
+
+	for (i = 0; i < prog->len; i++) {
+		const struct bpf_insn *insn = &prog->insnsi[i];
+		int ret;
+
+		if (!ctx->target)
+			ctx->offsets[i] = ctx->idx;
+
+		ret = build_insn(insn, ctx, i);
+		if (ret < 0)
+			return ret;
+
+		if (insn->code == (BPF_LD | BPF_IMM | BPF_DW)) {
+			i++;
+			if (!ctx->target)
+				ctx->offsets[i] = ctx->idx;
+		}
+	}
+
+	if (!ctx->target)
+		ctx->offsets[prog->len] = ctx->idx;
+
+	return 0;
+}
+
+bool bpf_jit_needs_zext(void)
+{
+	return true;
+}
+
+static void jit_fill_hole(void *area, unsigned int size)
+{
+	u16 *ptr;
+
+	for (ptr = area; size >= 2; size -= 2)
+		*ptr++ = 0x4afc;
+}
+
+struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)
+{
+	struct bpf_binary_header *header;
+	struct jit_ctx ctx;
+	unsigned int image_size;
+	u8 *image_ptr;
+	bool extra_pass = prog->jited;
+
+	if (!prog->jit_requested)
+		return prog;
+
+	if (prog->jited && !prog->aux->func)
+		return prog;
+
+	memset(&ctx, 0, sizeof(ctx));
+	ctx.prog = prog;
+
+	ctx.offsets = kvcalloc(prog->len + 1, sizeof(int), GFP_KERNEL);
+	if (!ctx.offsets)
+		return prog;
+
+	build_prologue(&ctx);
+	if (build_body(&ctx) < 0)
+		goto out_off;
+	build_epilogue(&ctx);
+
+	if (extra_pass) {
+		header = prog->aux->jit_data;
+		image_ptr = (u8 *)prog->bpf_func;
+		image_size = prog->jited_len;
+	} else {
+		image_size = ctx.idx * 2;
+		header = bpf_jit_binary_alloc(image_size, &image_ptr, 2, jit_fill_hole);
+		if (!header)
+			goto out_off;
+		prog->aux->jit_data = header;
+	}
+
+	ctx.target = (u16 *)image_ptr;
+	ctx.idx = 0;
+
+	build_prologue(&ctx);
+	if (build_body(&ctx) < 0) {
+		bpf_jit_binary_free(header);
+		prog->aux->jit_data = NULL;
+		prog->bpf_func = NULL;
+		prog->jited = 0;
+		prog->jited_len = 0;
+		goto out_off;
+	}
+	build_epilogue(&ctx);
+
+	flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx));
+
+	if (bpf_jit_enable > 1)
+		bpf_jit_dump(prog->len, image_size, 2, ctx.target);
+
+	if ((!prog->aux->func || extra_pass) && bpf_jit_binary_lock_ro(header)) {
+		bpf_jit_binary_free(header);
+		prog->bpf_func = NULL;
+		prog->jited = 0;
+		prog->jited_len = 0;
+		prog->aux->jit_data = NULL;
+		goto out_off;
+	}
+
+	prog->bpf_func = (void *)ctx.target;
+	prog->jited = 1;
+	prog->jited_len = image_size;
+
+out_off:
+	kvfree(ctx.offsets);
+	return prog;
+}

3/2 2026/07/30 04:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 28850
							output: 45
							thoughts: 1195
						

Thoughts:
**Fuzzing Feasibility of m68k BPF JIT Compiler Patch**

Okay, so we have a patch introducing a BPF JIT compiler specifically for the m68k architecture. My initial thought is, "Can we even fuzz this?" My knowledge tells me that m68k isn't a *standard* target for fuzzing within the usual syzkaller setups, which lean towards architectures like x86_64, arm64, etc. However, let's not jump to conclusions. The prompt specifically excludes things that can't be reached in QEMU, and QEMU *does* support m68k. That's a key point.

The patch modifies `MAINTAINERS`, `Kbuild`, `Kconfig`, `Makefile`, and introduces `bpf_jit_comp.c`, which is the core implementation. This new file implements the actual BPF JIT compiler for m68k. Now, is this code reachable? The important thing is: *Is it possible to reach the patched code?*

Looking at the code, it implements `bpf_int_jit_compile`.  That's the entry point; the prompt says to look for functions that are not static. The `Makefile` confirms that `CONFIG_BPF_JIT` is necessary. Now I need to confirm `bpf_int_jit_compile` is an API entry point, so I'm sure of what to enable. This function is part of the core BPF subsystem. When a BPF program is loaded and JIT is enabled, it's called. This means that, assuming the config is enabled, it should be possible to trigger the new code.

The prompt guides me toward a "WorthFuzzing" decision.  Since it's m68k-specific, and m68k *is* emulable in QEMU, the code *should* be reachable under a virtualized environment. This suggests fuzzing is *possible*. The instructions say "if the code is reachable in QEMU, return WorthFuzzing=true". It's not excluded and is an architecture-specific feature in an architecture supported by QEMU.

So, let me extract the config requirements. The `Makefile` shows `CONFIG_BPF_JIT` is needed. `HAVE_EBPF_JIT` is also selected if not `COLDFIRE` or `M68000`, based on the `Kconfig`. Therefore, I must enable `BPF_JIT`.

I confirm `bpf_int_jit_compile` is the entry point, and that `bpf_jit_needs_zext` is the only function not static, apart from `bpf_int_jit_compile`.

The conclusion is, it is feasible to fuzz, and I would now move on to confirming the configuration options and running through the relevant tests.



4/2 2026/07/30 04:50 tool grepper
0m Args:
{
  "Expression": "bpf_int_jit_compile",
  "PathPrefix": "arch/m68k/net/bpf_jit_comp.c"
}

Results:
{
  "Output": "arch/m68k/net/bpf_jit_comp.c=1549=static void jit_fill_hole(void *area, unsigned int size)\n--\narch/m68k/net/bpf_jit_comp.c-1556-\narch/m68k/net/bpf_jit_comp.c:1557:struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\narch/m68k/net/bpf_jit_comp.c-1558-{\n"
}

5/2 2026/07/30 04:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 30873
							output: 46
							thoughts: 32
						

Thoughts:
Okay, here's my take on those thoughts, framed as an expert's internal monologue:

**Investigating BPF JIT Compiler Symbols**

Alright, so `bpf_int_jit_compile` isn't static. That's good to know, confirming my initial hunch. But now, the real question is, what about `bpf_jit_needs_zext`? Is that static or not? The answer to that will have implications for the JIT compiler implementation and how modular things are. I need to understand the visibility of that symbol to ensure proper linking and potential integration with other BPF components. It's a key piece in the puzzle, and I need to solidify my understanding of its scope.



6/2 2026/07/30 04:50 tool grepper
0m Args:
{
  "Expression": "bpf_jit_needs_zext",
  "PathPrefix": "arch/m68k/net/bpf_jit_comp.c"
}

Results:
{
  "Output": "arch/m68k/net/bpf_jit_comp.c=1515=static int build_body(struct jit_ctx *ctx)\n--\narch/m68k/net/bpf_jit_comp.c-1543-\narch/m68k/net/bpf_jit_comp.c:1544:bool bpf_jit_needs_zext(void)\narch/m68k/net/bpf_jit_comp.c-1545-{\n"
}

7/2 2026/07/30 04:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 31240
							output: 81
							thoughts: 29
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Investigating Function Scope in BPF JIT**

Right, so I'm revisiting the BPF JIT code and taking a closer look at function scope. I see that `bpf_jit_needs_zext` is *also* declared non-static. That's a key observation, worth noting. Now, the question that immediately pops into my head is: are there *any* other functions within this code base that aren't declared as static? It’s a good practice to declare functions static when possible, to avoid inadvertent external linkage and reduce the chances of name collisions in larger projects. Identifying *all* such non-static functions is critical for understanding the overall architecture and potential areas of concern, or those areas where external linkage might be intentional. I need to make a thorough pass through the source.



8/2 2026/07/30 04:50 tool grepper
0m Args:
{
  "Expression": "^[a-zA-Z_][a-zA-Z0-9_]*\\s+\\**[a-zA-Z_][a-zA-Z0-9_]*\\s*\\(",
  "PathPrefix": "arch/m68k/net/bpf_jit_comp.c"
}

Results:
{
  "Output": "arch/m68k/net/bpf_jit_comp.c=1515=static int build_body(struct jit_ctx *ctx)\n--\narch/m68k/net/bpf_jit_comp.c-1543-\narch/m68k/net/bpf_jit_comp.c:1544:bool bpf_jit_needs_zext(void)\narch/m68k/net/bpf_jit_comp.c-1545-{\n"
}

9/2 2026/07/30 04:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 31676
							output: 47
							thoughts: 45
						

Thoughts:
Okay, here's my take on those thoughts, summarizing them from a first-person perspective, assuming I'm already deep in this code:

**Regex Snafu and a Quick Fix**

Right, damn it! I just realized my initial regex didn't flag `bpf_int_jit_compile`. It's got that `struct bpf_prog *` return type, which my previous pattern completely missed. I was so focused on the function name itself, I overlooked that detail in the signature. Okay, no problem, I can adapt. Thinking I'll just broaden the search. I can use something simple like `^struct .*` to match any line that starts with `struct` followed by anything. That should grab the ones I need without getting too specific. Need to keep this moving!



10/2 2026/07/30 04:50 tool grepper
0m Args:
{
  "Expression": "^[a-zA-Z_].*\\(",
  "PathPrefix": "arch/m68k/net/bpf_jit_comp.c"
}

Results:
{
  "Output": "arch/m68k/net/bpf_jit_comp.c=63=struct jit_ctx {\n--\narch/m68k/net/bpf_jit_comp.c-69-\narch/m68k/net/bpf_jit_comp.c:70:static noinline u32 jit_mul32(u32 a, u32 b)\narch/m68k/net/bpf_jit_comp.c-71-{\n--\narch/m68k/net/bpf_jit_comp.c-74-\narch/m68k/net/bpf_jit_comp.c:75:static noinline u32 jit_div32(u32 a, u32 b)\narch/m68k/net/bpf_jit_comp.c-76-{\n--\narch/m68k/net/bpf_jit_comp.c-79-\narch/m68k/net/bpf_jit_comp.c:80:static noinline u32 jit_mod32(u32 a, u32 b)\narch/m68k/net/bpf_jit_comp.c-81-{\n--\narch/m68k/net/bpf_jit_comp.c-84-\narch/m68k/net/bpf_jit_comp.c:85:static noinline s32 jit_sdiv32(s32 a, s32 b)\narch/m68k/net/bpf_jit_comp.c-86-{\n--\narch/m68k/net/bpf_jit_comp.c-93-\narch/m68k/net/bpf_jit_comp.c:94:static noinline s32 jit_smod32(s32 a, s32 b)\narch/m68k/net/bpf_jit_comp.c-95-{\n--\narch/m68k/net/bpf_jit_comp.c-102-\narch/m68k/net/bpf_jit_comp.c:103:static noinline u64 jit_mul64(u64 a, u64 b)\narch/m68k/net/bpf_jit_comp.c-104-{\n--\narch/m68k/net/bpf_jit_comp.c-107-\narch/m68k/net/bpf_jit_comp.c:108:static noinline u64 jit_div64(u64 a, u64 b)\narch/m68k/net/bpf_jit_comp.c-109-{\n--\narch/m68k/net/bpf_jit_comp.c-112-\narch/m68k/net/bpf_jit_comp.c:113:static noinline s64 jit_sdiv64(s64 a, s64 b)\narch/m68k/net/bpf_jit_comp.c-114-{\n--\narch/m68k/net/bpf_jit_comp.c-121-\narch/m68k/net/bpf_jit_comp.c:122:static noinline u64 jit_mod64(u64 a, u64 b)\narch/m68k/net/bpf_jit_comp.c-123-{\n--\narch/m68k/net/bpf_jit_comp.c-131-\narch/m68k/net/bpf_jit_comp.c:132:static noinline s64 jit_smod64(s64 a, s64 b)\narch/m68k/net/bpf_jit_comp.c-133-{\n--\narch/m68k/net/bpf_jit_comp.c-140-\narch/m68k/net/bpf_jit_comp.c:141:static u32 jit_atomic32(u32 *ptr, u32 val, u32 op, u32 cmp)\narch/m68k/net/bpf_jit_comp.c-142-{\n--\narch/m68k/net/bpf_jit_comp.c-177-\narch/m68k/net/bpf_jit_comp.c:178:static u64 jit_atomic64(u32 *ptr, u32 val_hi, u32 val_lo, u32 op, u32 cmp_hi, u32 cmp_lo)\narch/m68k/net/bpf_jit_comp.c-179-{\n--\narch/m68k/net/bpf_jit_comp.c-218-\narch/m68k/net/bpf_jit_comp.c:219:static inline void emit_16(struct jit_ctx *ctx, u16 inst)\narch/m68k/net/bpf_jit_comp.c-220-{\n--\narch/m68k/net/bpf_jit_comp.c-225-\narch/m68k/net/bpf_jit_comp.c:226:static inline void emit_32(struct jit_ctx *ctx, u32 val)\narch/m68k/net/bpf_jit_comp.c-227-{\n--\narch/m68k/net/bpf_jit_comp.c-231-\narch/m68k/net/bpf_jit_comp.c:232:static inline bool is_stacked(s8 reg)\narch/m68k/net/bpf_jit_comp.c-233-{\n--\narch/m68k/net/bpf_jit_comp.c-236-\narch/m68k/net/bpf_jit_comp.c:237:static s8 bpf_get_reg32(s8 bpf_reg, s8 tmp_reg, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-238-{\n--\narch/m68k/net/bpf_jit_comp.c-246-\narch/m68k/net/bpf_jit_comp.c:247:static void bpf_put_reg32(s8 bpf_reg, s8 src_reg, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-248-{\n--\narch/m68k/net/bpf_jit_comp.c-256-\narch/m68k/net/bpf_jit_comp.c:257:static void emit_alu32_neg(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-258-{\n--\narch/m68k/net/bpf_jit_comp.c-269-\narch/m68k/net/bpf_jit_comp.c:270:static void emit_alu64_neg(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-271-{\n--\narch/m68k/net/bpf_jit_comp.c-283-\narch/m68k/net/bpf_jit_comp.c:284:static void emit_alu32_x(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-285-{\n--\narch/m68k/net/bpf_jit_comp.c-349-\narch/m68k/net/bpf_jit_comp.c:350:static void emit_alu32_k(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-351-{\n--\narch/m68k/net/bpf_jit_comp.c-403-\narch/m68k/net/bpf_jit_comp.c:404:static void emit_alu64_x(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-405-{\n--\narch/m68k/net/bpf_jit_comp.c-463-\narch/m68k/net/bpf_jit_comp.c:464:static void emit_alu64_k(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-465-{\n--\narch/m68k/net/bpf_jit_comp.c-520-\narch/m68k/net/bpf_jit_comp.c:521:static void emit_alu64_shift(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_imm)\narch/m68k/net/bpf_jit_comp.c-522-{\n--\narch/m68k/net/bpf_jit_comp.c-575-\narch/m68k/net/bpf_jit_comp.c:576:static void emit_bpf_end(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-577-{\n--\narch/m68k/net/bpf_jit_comp.c-631-\narch/m68k/net/bpf_jit_comp.c:632:static void emit_math_call(const struct bpf_insn *insn, struct jit_ctx *ctx, bool is_64)\narch/m68k/net/bpf_jit_comp.c-633-{\n--\narch/m68k/net/bpf_jit_comp.c-739-\narch/m68k/net/bpf_jit_comp.c:740:static void emit_ldx(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-741-{\n--\narch/m68k/net/bpf_jit_comp.c-802-\narch/m68k/net/bpf_jit_comp.c:803:static void emit_stx(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-804-{\n--\narch/m68k/net/bpf_jit_comp.c-843-\narch/m68k/net/bpf_jit_comp.c:844:static void emit_st(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-845-{\n--\narch/m68k/net/bpf_jit_comp.c-885-\narch/m68k/net/bpf_jit_comp.c:886:static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-887-{\n--\narch/m68k/net/bpf_jit_comp.c-987-\narch/m68k/net/bpf_jit_comp.c:988:static void emit_tail_call(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-989-{\n--\narch/m68k/net/bpf_jit_comp.c-1051-\narch/m68k/net/bpf_jit_comp.c:1052:static int emit_jmp(const struct bpf_insn *insn, struct jit_ctx *ctx, int curr_i)\narch/m68k/net/bpf_jit_comp.c-1053-{\n--\narch/m68k/net/bpf_jit_comp.c-1216-\narch/m68k/net/bpf_jit_comp.c:1217:static int emit_call(const struct bpf_insn *insn, struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-1218-{\n--\narch/m68k/net/bpf_jit_comp.c-1252-\narch/m68k/net/bpf_jit_comp.c:1253:static void build_prologue(struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-1254-{\n--\narch/m68k/net/bpf_jit_comp.c-1302-\narch/m68k/net/bpf_jit_comp.c:1303:static void build_epilogue(struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-1304-{\n--\narch/m68k/net/bpf_jit_comp.c-1311-\narch/m68k/net/bpf_jit_comp.c:1312:static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, int i)\narch/m68k/net/bpf_jit_comp.c-1313-{\n--\narch/m68k/net/bpf_jit_comp.c-1514-\narch/m68k/net/bpf_jit_comp.c:1515:static int build_body(struct jit_ctx *ctx)\narch/m68k/net/bpf_jit_comp.c-1516-{\n--\narch/m68k/net/bpf_jit_comp.c-1543-\narch/m68k/net/bpf_jit_comp.c:1544:bool bpf_jit_needs_zext(void)\narch/m68k/net/bpf_jit_comp.c-1545-{\n--\narch/m68k/net/bpf_jit_comp.c-1548-\narch/m68k/net/bpf_jit_comp.c:1549:static void jit_fill_hole(void *area, unsigned int size)\narch/m68k/net/bpf_jit_comp.c-1550-{\n--\narch/m68k/net/bpf_jit_comp.c-1556-\narch/m68k/net/bpf_jit_comp.c:1557:struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\narch/m68k/net/bpf_jit_comp.c-1558-{\n"
}

11/2 2026/07/30 04:50 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 35815
							output: 102
							thoughts: 869
						

Thoughts:
**Analysis of the BPF JIT Compiler Patch for m68k Architecture**

Alright, let's break this down. My initial observation is that `bpf_int_jit_compile` and `bpf_jit_needs_zext` are the two key non-static functions in this patch.  `bpf_int_jit_compile` looks like the main entry point for the JIT compiler itself, which is crucial.  `bpf_jit_needs_zext` is also an important entry point called from the core BPF code.

Now, checking the kernel configuration options, `arch/m68k/Kconfig` reveals that `CONFIG_BPF_JIT` is the critical option here.  The code selects `HAVE_EBPF_JIT` if we're *not* dealing with COLDFIRE or M68000 processors.

The prompt stipulates that we need to determine if this change is "WorthFuzzing." Considering the criteria, the m68k architecture is a factor.  While Syzkaller doesn't typically focus on m68k, QEMU does support it, which makes me think it's fuzzable.  This patch is introducing a BPF JIT compiler for a new architecture.

My strategy is to define the "WorthFuzzing" parameter. Since this change introduces new functionality within the kernel (a JIT compiler for a new architecture), I'll set this to true.

To support this decision, I need to provide `FocusSymbols` and `EnableConfigs`.  The core functionality revolves around `bpf_int_jit_compile` and `bpf_jit_needs_zext`.  So my `FocusSymbols` will be `["bpf_int_jit_compile", "bpf_jit_needs_zext"]`.  The relevant config, and verified by `arch/m68k/net/Makefile`, is `BPF_JIT`, so my `EnableConfigs` list will be `["BPF_JIT"]`.

I've also confirmed that `BPF_JIT` usually depends on `HAVE_EBPF_JIT`, which, in this case, is indeed selected based on the Kconfig file. I will also make sure to specify a good reason in the final response.

Finally, neither of these functions are hot-path functions. This is because `bpf_int_jit_compile` is called when a BPF program is loaded and `bpf_jit_needs_zext` is called during program loading or verification. This implies that they will be called during control-path operation and are therefore testable.

So the final set will be:
WorthFuzzing: true
FocusSymbols: ["bpf_int_jit_compile", "bpf_jit_needs_zext"]
EnableConfigs: ["BPF_JIT"]
Reasoning: "The patch introduces a new BPF JIT compiler for the m68k architecture. The code is reachable during BPF program loading when JIT is enabled, and can be tested in QEMU."



12/2 2026/07/30 04:50 tool set-results
0m Args:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_int_jit_compile",
    "bpf_jit_needs_zext"
  ],
  "Reasoning": "The patch introduces a new BPF JIT compiler for the m68k architecture. The code is reachable during BPF program loading when JIT is enabled, and can be tested in QEMU.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_int_jit_compile",
    "bpf_jit_needs_zext"
  ],
  "Reasoning": "The patch introduces a new BPF JIT compiler for the m68k architecture. The code is reachable during BPF program loading when JIT is enabled, and can be tested in QEMU.",
  "WorthFuzzing": true
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)