AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/07/24 10:02 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_supports_timed_may_goto"
  ],
  "Reasoning": "The patch implements the BPF timed may_goto instruction for the RISC-V BPF JIT compiler. This modifies the core BPF JIT logic on RISC-V and is reachable when loading BPF programs.",
  "WorthFuzzing": true
}

1/1 2026/07/24 10:02 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 87875331c009e41c5a9dfdf96dd01d72df759beb\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Fri Jul 24 10:02:05 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/arch/riscv/net/Makefile b/arch/riscv/net/Makefile\nindex 9a1e5f0a94e559..6458d4d51990a7 100644\n--- a/arch/riscv/net/Makefile\n+++ b/arch/riscv/net/Makefile\n@@ -3,7 +3,7 @@\n obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o\n \n ifeq ($(CONFIG_ARCH_RV64I),y)\n-\tobj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o\n+\tobj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o bpf_timed_may_goto.o\n else\n \tobj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o\n endif\ndiff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c\nindex ad089a9a4ea9ac..8fe8969fb8a0f8 100644\n--- a/arch/riscv/net/bpf_jit_comp64.c\n+++ b/arch/riscv/net/bpf_jit_comp64.c\n@@ -1841,7 +1841,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\n \t\tif (aux-\u003etail_call_reachable \u0026\u0026 insn-\u003esrc_reg == BPF_PSEUDO_CALL)\n \t\t\temit_sd(RV_REG_SP, ctx-\u003etcc_offset, RV_REG_TCC, ctx);\n \n-\t\tif (insn-\u003esrc_reg != BPF_PSEUDO_CALL)\n+\t\t/*\n+\t\t * arch_bpf_timed_may_goto() is emitted by the verifier and\n+\t\t * returns its result in BPF_REG_AX instead of BPF_REG_0, so\n+\t\t * skip the normal \"move return register into R0\".\n+\t\t */\n+\t\tif (insn-\u003esrc_reg != BPF_PSEUDO_CALL \u0026\u0026 addr != (u64)arch_bpf_timed_may_goto)\n \t\t\temit_mv(bpf_to_rv_reg(BPF_REG_0, ctx), RV_REG_A0, ctx);\n \t\tbreak;\n \t}\n@@ -2161,3 +2166,8 @@ bool bpf_jit_supports_subprog_tailcalls(void)\n {\n \treturn true;\n }\n+\n+bool bpf_jit_supports_timed_may_goto(void)\n+{\n+\treturn true;\n+}\ndiff --git a/arch/riscv/net/bpf_timed_may_goto.S b/arch/riscv/net/bpf_timed_may_goto.S\nnew file mode 100644\nindex 00000000000000..02c637d874205a\n--- /dev/null\n+++ b/arch/riscv/net/bpf_timed_may_goto.S\n@@ -0,0 +1,47 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/* Copyright (c) 2026 Feng Jiang \u003cjiangfeng@kylinos.cn\u003e */\n+\n+#include \u003clinux/linkage.h\u003e\n+#include \u003casm/asm.h\u003e\n+\n+/*\n+ * Trampoline for the BPF timed may_goto loop bound. Custom calling convention:\n+ *\t- input:  stack offset in BPF_REG_AX (t0)\n+ *\t- output: updated count in BPF_REG_AX (t0)\n+ *\n+ * Calls bpf_check_timed_may_goto(ptr) with the standard RISC-V ABI, where\n+ * ptr = BPF_REG_FP (s5) + BPF_REG_AX (t0). BPF R0-R5 (a5, a0-a4) are saved\n+ * across the call; BPF_REG_FP (s5) is callee-saved and needs no saving.\n+ */\n+\n+SYM_FUNC_START(arch_bpf_timed_may_goto)\n+\taddi\tsp, sp, -(8*SZREG)\n+\tREG_S\tra, 7*SZREG(sp)\n+\tREG_S\ts0, 6*SZREG(sp)\n+\taddi\ts0, sp, 8*SZREG\n+\n+\t/* Save BPF registers R0-R5 (a5, a0-a4) */\n+\tREG_S\ta5, 5*SZREG(sp)\n+\tREG_S\ta0, 4*SZREG(sp)\n+\tREG_S\ta1, 3*SZREG(sp)\n+\tREG_S\ta2, 2*SZREG(sp)\n+\tREG_S\ta3, 1*SZREG(sp)\n+\tREG_S\ta4, 0*SZREG(sp)\n+\n+\tadd\ta0, t0, s5\n+\tcall\tbpf_check_timed_may_goto\n+\tmv\tt0, a0\n+\n+\t/* Restore BPF registers R0-R5 */\n+\tREG_L\ta4, 0*SZREG(sp)\n+\tREG_L\ta3, 1*SZREG(sp)\n+\tREG_L\ta2, 2*SZREG(sp)\n+\tREG_L\ta1, 3*SZREG(sp)\n+\tREG_L\ta0, 4*SZREG(sp)\n+\tREG_L\ta5, 5*SZREG(sp)\n+\n+\tREG_L\ts0, 6*SZREG(sp)\n+\tREG_L\tra, 7*SZREG(sp)\n+\taddi\tsp, sp, 8*SZREG\n+\tret\n+SYM_FUNC_END(arch_bpf_timed_may_goto)\ndiff --git a/tools/testing/selftests/bpf/progs/stream.c b/tools/testing/selftests/bpf/progs/stream.c\nindex 92ba1d72e0ece4..8d8e53d37266cd 100644\n--- a/tools/testing/selftests/bpf/progs/stream.c\n+++ b/tools/testing/selftests/bpf/progs/stream.c\n@@ -64,6 +64,7 @@ SEC(\"syscall\")\n __arch_x86_64\n __arch_arm64\n __arch_s390x\n+__arch_riscv64\n __success __retval(0)\n __stderr(\"ERROR: Timeout detected for may_goto instruction\")\n __stderr(\"CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}\")\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c b/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c\nindex 8d7ff38e4c0697..83707faea04994 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c\n@@ -660,6 +660,7 @@ __naked void may_goto_interaction_x86_64(void)\n \n SEC(\"raw_tp\")\n __arch_arm64\n+__arch_riscv64\n __log_level(4) __msg(\"stack depth 24\")\n /* may_goto counter at -24 */\n __xlated(\"0: *(u64 *)(r10 -24) =\")\n@@ -679,7 +680,7 @@ __xlated(\"10: *(u64 *)(r10 -24) = r12\")\n __xlated(\"11: *(u64 *)(r10 -8) = r1\")\n __xlated(\"12: exit\")\n __success\n-__naked void may_goto_interaction_arm64(void)\n+__naked void may_goto_interaction(void)\n {\n \tasm volatile (\n \t\"r1 = 1;\"\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c b/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c\nindex 4bdf4256a41e51..0e211f030d0d7a 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c\n@@ -11,6 +11,7 @@ __description(\"may_goto 0\")\n __arch_x86_64\n __arch_s390x\n __arch_arm64\n+__arch_riscv64\n __xlated(\"0: r0 = 1\")\n __xlated(\"1: exit\")\n __success\n@@ -31,6 +32,7 @@ __description(\"batch 2 of may_goto 0\")\n __arch_x86_64\n __arch_s390x\n __arch_arm64\n+__arch_riscv64\n __xlated(\"0: r0 = 1\")\n __xlated(\"1: exit\")\n __success\n@@ -53,6 +55,7 @@ __description(\"may_goto batch with offsets 2/1/0\")\n __arch_x86_64\n __arch_s390x\n __arch_arm64\n+__arch_riscv64\n __xlated(\"0: r0 = 1\")\n __xlated(\"1: exit\")\n __success\n@@ -79,6 +82,7 @@ __description(\"may_goto batch with offsets 2/0\")\n __arch_x86_64\n __arch_s390x\n __arch_arm64\n+__arch_riscv64\n __xlated(\"0: *(u64 *)(r10 -16) = 65535\")\n __xlated(\"1: *(u64 *)(r10 -8) = 0\")\n __xlated(\"2: r12 = *(u64 *)(r10 -16)\")\n@@ -106,4 +110,62 @@ __naked void may_goto_batch_2(void)\n \t: __clobber_all);\n }\n \n+/*\n+ * Use bpf_get_prandom_u32() to prevent DCE from removing the checks.\n+ * retval: 0=all ok, 1-6=R0-R5 clobbered.\n+ */\n+SEC(\"syscall\")\n+__description(\"timed may_goto preserves R0-R5\")\n+__arch_x86_64\n+__arch_s390x\n+__arch_arm64\n+__arch_riscv64\n+__success\n+__retval(0)\n+__naked void timed_may_goto_preserves_regs(void)\n+{\n+\tasm volatile (\n+\t\"call %[bpf_get_prandom_u32];\"\n+\t\"r6 = r0;\"\n+\t\"r0 = 0x1111;\"\n+\t\"r0 += r6;\"\n+\t\"r1 = 0x2222;\"\n+\t\"r1 += r6;\"\n+\t\"r2 = 0x3333;\"\n+\t\"r2 += r6;\"\n+\t\"r3 = 0x4444;\"\n+\t\"r3 += r6;\"\n+\t\"r4 = 0x5555;\"\n+\t\"r4 += r6;\"\n+\t\"r5 = 0x6666;\"\n+\t\"r5 += r6;\"\n+\t\".8byte %[may_goto];\"\n+\t\".8byte %[loop];\"\n+\t\"r0 -= r6;\"\n+\t\"r1 -= r6;\"\n+\t\"r2 -= r6;\"\n+\t\"r3 -= r6;\"\n+\t\"r4 -= r6;\"\n+\t\"r5 -= r6;\"\n+\t\"if r0 != 0x1111 goto 1f;\"\n+\t\"if r1 != 0x2222 goto 2f;\"\n+\t\"if r2 != 0x3333 goto 3f;\"\n+\t\"if r3 != 0x4444 goto 4f;\"\n+\t\"if r4 != 0x5555 goto 5f;\"\n+\t\"if r5 != 0x6666 goto 6f;\"\n+\t\"r0 = 0;\"\n+\t\"exit;\"\n+\t\"1: r0 = 1; exit;\"\n+\t\"2: r0 = 2; exit;\"\n+\t\"3: r0 = 3; exit;\"\n+\t\"4: r0 = 4; exit;\"\n+\t\"5: r0 = 5; exit;\"\n+\t\"6: r0 = 6; exit;\"\n+\t:\n+\t: __imm(bpf_get_prandom_u32),\n+\t  __imm_insn(may_goto, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 1, 0)),\n+\t  __imm_insn(loop, BPF_RAW_INSN(BPF_JMP | BPF_JA, 0, 0, -2, 0))\n+\t: __clobber_all);\n+}\n+\n char _license[] SEC(\"license\") = \"GPL\";\n"
}

2/1 2026/07/24 10:02 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_supports_timed_may_goto"
  ],
  "Reasoning": "The patch implements the BPF timed may_goto instruction for the RISC-V BPF JIT compiler. This modifies the core BPF JIT logic on RISC-V and is reachable when loading BPF programs.",
  "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).

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.
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.
   Do not list too generic configs (we already have them enabled). Only list those that
   specifically cover the modified code. 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 87875331c009e41c5a9dfdf96dd01d72df759beb
Author: syz-cluster <triage@syzkaller.com>
Date:   Fri Jul 24 10:02:05 2026 +0000

    syz-cluster: applied patch under review

diff --git a/arch/riscv/net/Makefile b/arch/riscv/net/Makefile
index 9a1e5f0a94e559..6458d4d51990a7 100644
--- a/arch/riscv/net/Makefile
+++ b/arch/riscv/net/Makefile
@@ -3,7 +3,7 @@
 obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o
 
 ifeq ($(CONFIG_ARCH_RV64I),y)
-	obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
+	obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o bpf_timed_may_goto.o
 else
 	obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
 endif
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index ad089a9a4ea9ac..8fe8969fb8a0f8 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -1841,7 +1841,12 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 		if (aux->tail_call_reachable && insn->src_reg == BPF_PSEUDO_CALL)
 			emit_sd(RV_REG_SP, ctx->tcc_offset, RV_REG_TCC, ctx);
 
-		if (insn->src_reg != BPF_PSEUDO_CALL)
+		/*
+		 * arch_bpf_timed_may_goto() is emitted by the verifier and
+		 * returns its result in BPF_REG_AX instead of BPF_REG_0, so
+		 * skip the normal "move return register into R0".
+		 */
+		if (insn->src_reg != BPF_PSEUDO_CALL && addr != (u64)arch_bpf_timed_may_goto)
 			emit_mv(bpf_to_rv_reg(BPF_REG_0, ctx), RV_REG_A0, ctx);
 		break;
 	}
@@ -2161,3 +2166,8 @@ bool bpf_jit_supports_subprog_tailcalls(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_timed_may_goto(void)
+{
+	return true;
+}
diff --git a/arch/riscv/net/bpf_timed_may_goto.S b/arch/riscv/net/bpf_timed_may_goto.S
new file mode 100644
index 00000000000000..02c637d874205a
--- /dev/null
+++ b/arch/riscv/net/bpf_timed_may_goto.S
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2026 Feng Jiang <jiangfeng@kylinos.cn> */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/*
+ * Trampoline for the BPF timed may_goto loop bound. Custom calling convention:
+ *	- input:  stack offset in BPF_REG_AX (t0)
+ *	- output: updated count in BPF_REG_AX (t0)
+ *
+ * Calls bpf_check_timed_may_goto(ptr) with the standard RISC-V ABI, where
+ * ptr = BPF_REG_FP (s5) + BPF_REG_AX (t0). BPF R0-R5 (a5, a0-a4) are saved
+ * across the call; BPF_REG_FP (s5) is callee-saved and needs no saving.
+ */
+
+SYM_FUNC_START(arch_bpf_timed_may_goto)
+	addi	sp, sp, -(8*SZREG)
+	REG_S	ra, 7*SZREG(sp)
+	REG_S	s0, 6*SZREG(sp)
+	addi	s0, sp, 8*SZREG
+
+	/* Save BPF registers R0-R5 (a5, a0-a4) */
+	REG_S	a5, 5*SZREG(sp)
+	REG_S	a0, 4*SZREG(sp)
+	REG_S	a1, 3*SZREG(sp)
+	REG_S	a2, 2*SZREG(sp)
+	REG_S	a3, 1*SZREG(sp)
+	REG_S	a4, 0*SZREG(sp)
+
+	add	a0, t0, s5
+	call	bpf_check_timed_may_goto
+	mv	t0, a0
+
+	/* Restore BPF registers R0-R5 */
+	REG_L	a4, 0*SZREG(sp)
+	REG_L	a3, 1*SZREG(sp)
+	REG_L	a2, 2*SZREG(sp)
+	REG_L	a1, 3*SZREG(sp)
+	REG_L	a0, 4*SZREG(sp)
+	REG_L	a5, 5*SZREG(sp)
+
+	REG_L	s0, 6*SZREG(sp)
+	REG_L	ra, 7*SZREG(sp)
+	addi	sp, sp, 8*SZREG
+	ret
+SYM_FUNC_END(arch_bpf_timed_may_goto)
diff --git a/tools/testing/selftests/bpf/progs/stream.c b/tools/testing/selftests/bpf/progs/stream.c
index 92ba1d72e0ece4..8d8e53d37266cd 100644
--- a/tools/testing/selftests/bpf/progs/stream.c
+++ b/tools/testing/selftests/bpf/progs/stream.c
@@ -64,6 +64,7 @@ SEC("syscall")
 __arch_x86_64
 __arch_arm64
 __arch_s390x
+__arch_riscv64
 __success __retval(0)
 __stderr("ERROR: Timeout detected for may_goto instruction")
 __stderr("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}")
diff --git a/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c b/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c
index 8d7ff38e4c0697..83707faea04994 100644
--- a/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c
+++ b/tools/testing/selftests/bpf/progs/verifier_bpf_fastcall.c
@@ -660,6 +660,7 @@ __naked void may_goto_interaction_x86_64(void)
 
 SEC("raw_tp")
 __arch_arm64
+__arch_riscv64
 __log_level(4) __msg("stack depth 24")
 /* may_goto counter at -24 */
 __xlated("0: *(u64 *)(r10 -24) =")
@@ -679,7 +680,7 @@ __xlated("10: *(u64 *)(r10 -24) = r12")
 __xlated("11: *(u64 *)(r10 -8) = r1")
 __xlated("12: exit")
 __success
-__naked void may_goto_interaction_arm64(void)
+__naked void may_goto_interaction(void)
 {
 	asm volatile (
 	"r1 = 1;"
diff --git a/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c b/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c
index 4bdf4256a41e51..0e211f030d0d7a 100644
--- a/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c
+++ b/tools/testing/selftests/bpf/progs/verifier_may_goto_1.c
@@ -11,6 +11,7 @@ __description("may_goto 0")
 __arch_x86_64
 __arch_s390x
 __arch_arm64
+__arch_riscv64
 __xlated("0: r0 = 1")
 __xlated("1: exit")
 __success
@@ -31,6 +32,7 @@ __description("batch 2 of may_goto 0")
 __arch_x86_64
 __arch_s390x
 __arch_arm64
+__arch_riscv64
 __xlated("0: r0 = 1")
 __xlated("1: exit")
 __success
@@ -53,6 +55,7 @@ __description("may_goto batch with offsets 2/1/0")
 __arch_x86_64
 __arch_s390x
 __arch_arm64
+__arch_riscv64
 __xlated("0: r0 = 1")
 __xlated("1: exit")
 __success
@@ -79,6 +82,7 @@ __description("may_goto batch with offsets 2/0")
 __arch_x86_64
 __arch_s390x
 __arch_arm64
+__arch_riscv64
 __xlated("0: *(u64 *)(r10 -16) = 65535")
 __xlated("1: *(u64 *)(r10 -8) = 0")
 __xlated("2: r12 = *(u64 *)(r10 -16)")
@@ -106,4 +110,62 @@ __naked void may_goto_batch_2(void)
 	: __clobber_all);
 }
 
+/*
+ * Use bpf_get_prandom_u32() to prevent DCE from removing the checks.
+ * retval: 0=all ok, 1-6=R0-R5 clobbered.
+ */
+SEC("syscall")
+__description("timed may_goto preserves R0-R5")
+__arch_x86_64
+__arch_s390x
+__arch_arm64
+__arch_riscv64
+__success
+__retval(0)
+__naked void timed_may_goto_preserves_regs(void)
+{
+	asm volatile (
+	"call %[bpf_get_prandom_u32];"
+	"r6 = r0;"
+	"r0 = 0x1111;"
+	"r0 += r6;"
+	"r1 = 0x2222;"
+	"r1 += r6;"
+	"r2 = 0x3333;"
+	"r2 += r6;"
+	"r3 = 0x4444;"
+	"r3 += r6;"
+	"r4 = 0x5555;"
+	"r4 += r6;"
+	"r5 = 0x6666;"
+	"r5 += r6;"
+	".8byte %[may_goto];"
+	".8byte %[loop];"
+	"r0 -= r6;"
+	"r1 -= r6;"
+	"r2 -= r6;"
+	"r3 -= r6;"
+	"r4 -= r6;"
+	"r5 -= r6;"
+	"if r0 != 0x1111 goto 1f;"
+	"if r1 != 0x2222 goto 2f;"
+	"if r2 != 0x3333 goto 3f;"
+	"if r3 != 0x4444 goto 4f;"
+	"if r4 != 0x5555 goto 5f;"
+	"if r5 != 0x6666 goto 6f;"
+	"r0 = 0;"
+	"exit;"
+	"1: r0 = 1; exit;"
+	"2: r0 = 2; exit;"
+	"3: r0 = 3; exit;"
+	"4: r0 = 4; exit;"
+	"5: r0 = 5; exit;"
+	"6: r0 = 6; exit;"
+	:
+	: __imm(bpf_get_prandom_u32),
+	  __imm_insn(may_goto, BPF_RAW_INSN(BPF_JMP | BPF_JCOND, 0, 0, 1, 0)),
+	  __imm_insn(loop, BPF_RAW_INSN(BPF_JMP | BPF_JA, 0, 0, -2, 0))
+	: __clobber_all);
+}
+
 char _license[] SEC("license") = "GPL";

3/2 2026/07/24 10:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 5149
							output: 46
							thoughts: 390
						

Thoughts:
**Analyzing the RISC-V BPF Timed May-Goto Patch**

Okay, so we've got a patch here that's adding support for `BPF timed_may_goto` on RISC-V. That's interesting, a good performance enhancement. Let's see what's changed. Looks like we have modifications to the makefile and some core BPF JIT compilation and testing files. Specifically, we have changes to `arch/riscv/net/Makefile`, `arch/riscv/net/bpf_jit_comp64.c`, `arch/riscv/net/bpf_timed_may_goto.S`, and some selftests.

This patch is essentially implementing `arch_bpf_timed_may_goto` in assembly for RISC-V and hooking it into the BPF JIT compiler. That's a direct architectural modification, so we need to be careful. It’s modifying the RISC-V BPF JIT compiler; this is functional code, and therefore needs to be carefully scrutinized.

Alright, let's drill down into `arch/riscv/net/bpf_jit_comp64.c` specifically. I see that the patch modifies `bpf_jit_emit_insn`. Also, the introduction of a new function, `bpf_jit_supports_timed_may_goto`, and of course the assembly function `arch_bpf_timed_may_goto`. That assembly function is key.

Now, the prompt specifically calls out that if a patch modifies reachable core kernel logic, drivers, or architectures, we need to verify the code can be executed. Considering it is architecture code, let's use the code search tools to examine `bpf_jit_emit_insn` and `arch_bpf_timed_may_goto`. This is the point to determine whether this change is worth fuzzing.



4/2 2026/07/24 10:02 tool grepper
0m Args:
{
  "Expression": "bpf_jit_emit_insn",
  "PathPrefix": "arch/riscv/net/bpf_jit_comp64.c"
}

Results:
{
  "Output": "arch/riscv/net/bpf_jit_comp64.c=1324=int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *ro_image,\n--\narch/riscv/net/bpf_jit_comp64.c-1360-\narch/riscv/net/bpf_jit_comp64.c:1361:int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\narch/riscv/net/bpf_jit_comp64.c-1362-\t\t      bool extra_pass)\n"
}

5/2 2026/07/24 10:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6170
							output: 26
							thoughts: 185
						

Thoughts:
**Examining the Kernel Configuration for BPF JIT Support on RISC-V**

Okay, let's dive into this configuration situation. My initial thought is to pinpoint the necessary kernel config options for the BPF JIT compiler on RISC-V. First, `CONFIG_BPF_JIT` seems like a given, a standard requirement for enabling the BPF JIT in any architecture. Then I need to figure out which RISC-V architecture options are needed. It seems like either `CONFIG_ARCH_RV64I` or `CONFIG_RISCV` should do it. But let's verify.

Ah, here is a clue! The patch modifies `arch/riscv/net/Makefile`. I will verify.

```makefile
ifeq ($(CONFIG_ARCH_RV64I),y)
	obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o bpf_timed_may_goto.o
```

So, the dependency is clear: I need *both* `CONFIG_BPF_JIT` and `CONFIG_ARCH_RV64I`. I was right, but it's good to confirm. But that is the *only* dependency. Wait, I'm thinking of this the wrong way; it's `CONFIG_BPF_JIT` that's the more general flag.

I wonder if there are any other related configurations. I should probably scan `arch/riscv/Kconfig` and `net/bpf/Kconfig` to ensure I haven't missed anything crucial. Just a quick check to see if there are any subtle interdependencies.



6/2 2026/07/24 10:02 tool grepper
0m Args:
{
  "Expression": "config BPF_JIT",
  "PathPrefix": ""
}

Results:
{
  "Output": "kernel/bpf/Kconfig=27=config BPF_SYSCALL\n--\nkernel/bpf/Kconfig-41-\nkernel/bpf/Kconfig:42:config BPF_JIT\nkernel/bpf/Kconfig-43-\tbool \"Enable BPF Just In Time compiler\"\n--\nkernel/bpf/Kconfig-57-\nkernel/bpf/Kconfig:58:config BPF_JIT_ALWAYS_ON\nkernel/bpf/Kconfig-59-\tbool \"Permanently enable BPF JIT and remove BPF interpreter\"\n--\nkernel/bpf/Kconfig-68-\nkernel/bpf/Kconfig:69:config BPF_JIT_DEFAULT_ON\nkernel/bpf/Kconfig-70-\tdef_bool ARCH_WANT_DEFAULT_BPF_JIT || BPF_JIT_ALWAYS_ON\n"
}

7/2 2026/07/24 10:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6960
							output: 37
							thoughts: 236
						

Thoughts:
**My BPF JIT Fuzzing Strategy**

Okay, so this patch adds `bpf_timed_may_goto` support to the RISC-V BPF JIT, which is great. It's definitely functional, and I know that means it needs some serious fuzzing. My initial thought is to focus on `bpf_jit_emit_insn` and `arch_bpf_timed_may_goto`. Wait, `arch_bpf_timed_may_goto` is assembly, huh? Syzkaller doesn't usually hook assembly directly. But `bpf_jit_emit_insn` is a C function, that's what I want.

Let me think… is `bpf_jit_emit_insn` really a good target? It's the main instruction emission function for the JIT, so it might be heavily used during BPF program load. Ah, but it's *specific* to the BPF JIT. That makes it good for fuzzing since it’s in the critical path.

Actually, I’m realizing `bpf_jit_emit_insn` is called for every single BPF instruction during JIT compilation. *That's* a juicy target for BPF fuzzing. Every instruction will go through that path. Great. I also need to make a note of `bpf_jit_supports_timed_may_goto`. I should probably check if there are other functions involved here too, just to be sure.



8/2 2026/07/24 10:02 tool grepper
0m Args:
{
  "Expression": "arch_bpf_timed_may_goto",
  "PathPrefix": "arch/riscv/net/"
}

Results:
{
  "Output": "arch/riscv/net/bpf_jit_comp64.c=1361=int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\n--\narch/riscv/net/bpf_jit_comp64.c-1844-\t\t/*\narch/riscv/net/bpf_jit_comp64.c:1845:\t\t * arch_bpf_timed_may_goto() is emitted by the verifier and\narch/riscv/net/bpf_jit_comp64.c-1846-\t\t * returns its result in BPF_REG_AX instead of BPF_REG_0, so\n--\narch/riscv/net/bpf_jit_comp64.c-1848-\t\t */\narch/riscv/net/bpf_jit_comp64.c:1849:\t\tif (insn-\u003esrc_reg != BPF_PSEUDO_CALL \u0026\u0026 addr != (u64)arch_bpf_timed_may_goto)\narch/riscv/net/bpf_jit_comp64.c-1850-\t\t\temit_mv(bpf_to_rv_reg(BPF_REG_0, ctx), RV_REG_A0, ctx);\n--\narch/riscv/net/bpf_timed_may_goto.S-16-\narch/riscv/net/bpf_timed_may_goto.S:17:SYM_FUNC_START(arch_bpf_timed_may_goto)\narch/riscv/net/bpf_timed_may_goto.S-18-\taddi\tsp, sp, -(8*SZREG)\n--\narch/riscv/net/bpf_timed_may_goto.S-46-\tret\narch/riscv/net/bpf_timed_may_goto.S:47:SYM_FUNC_END(arch_bpf_timed_may_goto)\n"
}

9/2 2026/07/24 10:02 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8048
							output: 110
							thoughts: 249
						

Thoughts:
**My Assessment of the RISC-V BPF JIT Patch**

Okay, so this patch introduces `bpf_timed_may_goto.S`, containing `arch_bpf_timed_may_goto`. That's the architecture-specific implementation. Then, looking at the C code in `bpf_jit_comp64.c`, the core JIT compiler logic is being modified. `bpf_jit_emit_insn` is the key function being updated, and a new function, `bpf_jit_supports_timed_may_goto`, is being added, which is essential to determine whether we can use the time control functionality.

Now, for the configuration, it seems like we just need `BPF_JIT`. That makes sense; it's the core JIT compiler we're targeting. I saw `ARCH_RV64I` mentioned, but that's the standard for 64-bit RISC-V, so we don't have to specify that. Oh, wait, we also need to have `BPF_SYSCALL` enabled as that will be necessary for a full end-to-end load of BPF programs.

Right, time to use the `set-results` tool. The key here is the `WorthFuzzing: true`. That's a good sign; the patch author considers this code path fuzzer-worthy. The `FocusSymbols` are clearly the important functions: `bpf_jit_emit_insn` and `bpf_jit_supports_timed_may_goto`. Those are the two functions that need to be tested thoroughly. The relevant `EnableConfigs` is just `BPF_JIT`.

The reasoning is sound: this patch adds a critical new feature, timed `may_goto`, to the RISC-V BPF JIT. This touches core BPF JIT logic and is therefore reachable when loading BPF programs, a classic attack surface. We should definitely be fuzzing this!



10/2 2026/07/24 10:02 tool set-results
0m Args:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_supports_timed_may_goto"
  ],
  "Reasoning": "The patch implements the BPF timed may_goto instruction for the RISC-V BPF JIT compiler. This modifies the core BPF JIT logic on RISC-V and is reachable when loading BPF programs.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "BPF_JIT"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_supports_timed_may_goto"
  ],
  "Reasoning": "The patch implements the BPF timed may_goto instruction for the RISC-V BPF JIT compiler. This modifies the core BPF JIT logic on RISC-V and is reachable when loading BPF programs.",
  "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)