AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/08/14 01:36 flow patch-triage
0m Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_JIT",
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_build_prologue"
  ],
  "KMSANReasoning": "The patch implements BPF stack arguments support for the RISC-V 64-bit JIT compiler. It modifies the translation of BPF instructions to RISC-V machine code, specifically handling stack offsets for function arguments. The changes do not introduce new kernel structures copied to user space, nor do they add complex C data structures or conditional logic dependent on uninitialized memory in the kernel's C code. Any bugs in the JIT compiler would result in incorrect code generation (e.g., crashes, out-of-bounds accesses, or register corruption), which are effectively caught by BPF selftests and standard KASAN. Furthermore, KMSAN is not currently supported on the RISC-V architecture, making a KMSAN run inapplicable for this architecture-specific patch.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch implements support for BPF stack arguments in the RISC-V 64-bit BPF JIT compiler, modifying core JIT functions like bpf_jit_emit_insn and bpf_jit_build_prologue.",
  "WorthFuzzing": true
}

1/1 2026/08/14 01:36 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit 8c03b531cdc62d7bf31a0c21191d0d4e46205dc8\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Fri Aug 14 01:36:29 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h\nindex 419b9d795f2a7..9eb4e149505d5 100644\n--- a/arch/riscv/net/bpf_jit.h\n+++ b/arch/riscv/net/bpf_jit.h\n@@ -82,6 +82,7 @@ struct rv_jit_context {\n \tunsigned long flags;\n \tint stack_size;\n \tint tcc_offset;\n+\tu16 stack_arg_size;\n \tu64 arena_vm_start;\n \tu64 user_vm_start;\n };\ndiff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c\nindex 6b9972b07c1b0..58cb3e5ff6b4d 100644\n--- a/arch/riscv/net/bpf_jit_comp64.c\n+++ b/arch/riscv/net/bpf_jit_comp64.c\n@@ -1815,18 +1815,43 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\n \n \t\tif (insn-\u003esrc_reg == BPF_PSEUDO_KFUNC_CALL) {\n \t\t\tconst struct btf_func_model *fm;\n-\t\t\tint idx;\n+\t\t\tint idx, nargs;\n \n \t\t\tfm = bpf_jit_find_kfunc_model(ctx-\u003eprog, insn);\n \t\t\tif (!fm)\n \t\t\t\treturn -EINVAL;\n \n-\t\t\tfor (idx = 0; idx \u003c fm-\u003enr_args; idx++) {\n+\t\t\tnargs = min_t(int, fm-\u003enr_args, MAX_BPF_FUNC_REG_ARGS);\n+\t\t\tfor (idx = 0; idx \u003c nargs; idx++) {\n \t\t\t\tu8 reg = bpf_to_rv_reg(BPF_REG_1 + idx, ctx);\n \n \t\t\t\tif (fm-\u003earg_size[idx] == sizeof(int))\n \t\t\t\t\temit_sextw(reg, reg, ctx);\n \t\t\t}\n+\n+\t\t\t/* BPF stack args -\u003e RISC-V ABI: args 6-8 in A5-A7, 9+ at SP+0 */\n+\t\t\tif (fm-\u003enr_args \u003e MAX_BPF_FUNC_REG_ARGS) {\n+\t\t\t\tint n_stack = fm-\u003enr_args - MAX_BPF_FUNC_REG_ARGS;\n+\t\t\t\tint n_reg = min_t(int, n_stack,\n+\t\t\t\t\t\t  RV_MAX_REG_ARGS - MAX_BPF_FUNC_REG_ARGS);\n+\n+\t\t\t\tfor (idx = 0; idx \u003c n_reg; idx++) {\n+\t\t\t\t\tint sz = fm-\u003earg_size[MAX_BPF_FUNC_REG_ARGS + idx];\n+\n+\t\t\t\t\temit_ld(RV_REG_A5 + idx, idx * 8, RV_REG_SP, ctx);\n+\t\t\t\t\tif (sz == sizeof(int))\n+\t\t\t\t\t\temit_sextw(RV_REG_A5 + idx, RV_REG_A5 + idx, ctx);\n+\t\t\t\t}\n+\n+\t\t\t\tfor (idx = n_reg; idx \u003c n_stack; idx++) {\n+\t\t\t\t\tint sz = fm-\u003earg_size[MAX_BPF_FUNC_REG_ARGS + idx];\n+\n+\t\t\t\t\temit_ld(RV_REG_T1, idx * 8, RV_REG_SP, ctx);\n+\t\t\t\t\tif (sz == sizeof(int))\n+\t\t\t\t\t\temit_sextw(RV_REG_T1, RV_REG_T1, ctx);\n+\t\t\t\t\temit_sd(RV_REG_SP, (idx - n_reg) * 8, RV_REG_T1, ctx);\n+\t\t\t\t}\n+\t\t\t}\n \t\t}\n \n \t\t/* restore TCC to RV_REG_TCC before bpf2bpf call */\n@@ -1891,6 +1916,21 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\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+\t\tif (insn-\u003esrc_reg == BPF_REG_PARAMS) {\n+\t\t\tint idx = off / 8 - 1;\n+\n+\t\t\tif (is_12b_int(idx * 8)) {\n+\t\t\t\temit_ldx_insn(rd, idx * 8, RV_REG_FP, BPF_SIZE(code), false, ctx);\n+\t\t\t} else {\n+\t\t\t\temit_imm(RV_REG_T1, idx * 8, ctx);\n+\t\t\t\temit_add(RV_REG_T1, RV_REG_T1, RV_REG_FP, ctx);\n+\t\t\t\temit_ldx_insn(rd, 0, RV_REG_T1, BPF_SIZE(code), false, ctx);\n+\t\t\t}\n+\t\t\tif (BPF_SIZE(code) != BPF_DW \u0026\u0026 insn_is_zext(\u0026insn[1]))\n+\t\t\t\treturn 1;\n+\t\t\tbreak;\n+\t\t}\n+\t\tfallthrough;\n \tcase BPF_LDX | BPF_PROBE_MEM | BPF_B:\n \tcase BPF_LDX | BPF_PROBE_MEM | BPF_H:\n \tcase BPF_LDX | BPF_PROBE_MEM | BPF_W:\n@@ -1938,6 +1978,20 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\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\tif (insn-\u003edst_reg == BPF_REG_PARAMS) {\n+\t\t\tint idx = -off / 8 - 1;\n+\n+\t\t\temit_imm(RV_REG_T1, imm, ctx);\n+\t\t\tif (is_12b_int(idx * 8)) {\n+\t\t\t\temit_stx_insn(RV_REG_SP, idx * 8, RV_REG_T1, BPF_SIZE(code), ctx);\n+\t\t\t} else {\n+\t\t\t\temit_imm(RV_REG_T2, idx * 8, ctx);\n+\t\t\t\temit_add(RV_REG_T2, RV_REG_SP, RV_REG_T2, ctx);\n+\t\t\t\temit_stx_insn(RV_REG_T2, 0, RV_REG_T1, BPF_SIZE(code), ctx);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tfallthrough;\n \t/* ST | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = imm */\n \tcase BPF_ST | BPF_PROBE_MEM32 | BPF_B:\n \tcase BPF_ST | BPF_PROBE_MEM32 | BPF_H:\n@@ -1960,6 +2014,19 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\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\tif (insn-\u003edst_reg == BPF_REG_PARAMS) {\n+\t\t\tint idx = -off / 8 - 1;\n+\n+\t\t\tif (is_12b_int(idx * 8)) {\n+\t\t\t\temit_stx_insn(RV_REG_SP, idx * 8, rs, BPF_SIZE(code), ctx);\n+\t\t\t} else {\n+\t\t\t\temit_imm(RV_REG_T1, idx * 8, ctx);\n+\t\t\t\temit_add(RV_REG_T1, RV_REG_SP, RV_REG_T1, ctx);\n+\t\t\t\temit_stx_insn(RV_REG_T1, 0, rs, BPF_SIZE(code), ctx);\n+\t\t\t}\n+\t\t\tbreak;\n+\t\t}\n+\t\tfallthrough;\n \t/* STX | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = src */\n \tcase BPF_STX | BPF_PROBE_MEM32 | BPF_B:\n \tcase BPF_STX | BPF_PROBE_MEM32 | BPF_H:\n@@ -2036,6 +2103,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)\n \n \tstack_adjust = round_up(stack_adjust, STACK_ALIGN);\n \tstack_adjust += bpf_stack_adjust;\n+\tstack_adjust += ctx-\u003estack_arg_size;\n \n \tstore_offset = stack_adjust - 8;\n \n@@ -2093,7 +2161,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)\n \temit_addi(RV_REG_FP, RV_REG_SP, stack_adjust, ctx);\n \n \tif (bpf_stack_adjust)\n-\t\temit_addi(RV_REG_S5, RV_REG_SP, bpf_stack_adjust, ctx);\n+\t\temit_addi(RV_REG_S5, RV_REG_SP, ctx-\u003estack_arg_size + bpf_stack_adjust, ctx);\n \n \tctx-\u003estack_size = stack_adjust;\n \n@@ -2171,3 +2239,8 @@ bool bpf_jit_supports_timed_may_goto(void)\n {\n \treturn true;\n }\n+\n+bool bpf_jit_supports_stack_args(void)\n+{\n+\treturn true;\n+}\ndiff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c\nindex cbfcd287ea166..844a0f3e0fa90 100644\n--- a/arch/riscv/net/bpf_jit_core.c\n+++ b/arch/riscv/net/bpf_jit_core.c\n@@ -72,6 +72,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr\n \tctx-\u003earena_vm_start = bpf_arena_get_kern_vm_start(prog-\u003eaux-\u003earena);\n \tctx-\u003euser_vm_start = bpf_arena_get_user_vm_start(prog-\u003eaux-\u003earena);\n \tctx-\u003eprog = prog;\n+\n+\tctx-\u003estack_arg_size = round_up(bpf_out_stack_arg_cnt(env, prog) *\n+\t\t\t\t       sizeof(u64), STACK_ALIGN);\n+\n \tctx-\u003eoffset = kvzalloc_objs(int, prog-\u003elen);\n \tif (!ctx-\u003eoffset)\n \t\tgoto out_offset;\ndiff --git a/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c b/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c\nindex 8d38aafe66a28..ab12397a9b52a 100644\n--- a/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c\n+++ b/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c\n@@ -4,7 +4,8 @@\n #include \u003cbpf/bpf_helpers.h\u003e\n #include \"../test_kmods/bpf_testmod_kfunc.h\"\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n long subprog_call_mem_kfunc(long a, long b, long c, long d, long e, long size)\ndiff --git a/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c b/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c\nindex 99bc115f8380a..a980a3a399d3f 100644\n--- a/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c\n+++ b/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c\n@@ -3,7 +3,8 @@\n #include \u003cvmlinux.h\u003e\n #include \u003cbpf/bpf_helpers.h\u003e\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n int subprog_bad_order_6args(int a, int b, int c, int d, int e, int f)\ndiff --git a/tools/testing/selftests/bpf/progs/stack_arg.c b/tools/testing/selftests/bpf/progs/stack_arg.c\nindex 944e3bb603e7e..3e9ed37c57bb9 100644\n--- a/tools/testing/selftests/bpf/progs/stack_arg.c\n+++ b/tools/testing/selftests/bpf/progs/stack_arg.c\n@@ -21,7 +21,8 @@ struct {\n \n int timer_result;\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n const volatile bool has_stack_arg = true;\ndiff --git a/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c b/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c\nindex 345f2da2e361b..b6b1a8aa7f44a 100644\n--- a/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c\n+++ b/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c\n@@ -6,7 +6,8 @@\n #include \"bpf_kfuncs.h\"\n #include \"../test_kmods/bpf_testmod_kfunc.h\"\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n const volatile bool has_stack_arg = true;\ndiff --git a/tools/testing/selftests/bpf/progs/stack_arg_precision.c b/tools/testing/selftests/bpf/progs/stack_arg_precision.c\nindex bee2eeec021d7..6eebafe7f2f87 100644\n--- a/tools/testing/selftests/bpf/progs/stack_arg_precision.c\n+++ b/tools/testing/selftests/bpf/progs/stack_arg_precision.c\n@@ -6,7 +6,8 @@\n #include \"../test_kmods/bpf_testmod_kfunc.h\"\n #include \"bpf_misc.h\"\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n /* Force kfunc extern BTF generation for inline asm call below.\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_stack_arg.c b/tools/testing/selftests/bpf/progs/verifier_stack_arg.c\nindex 7e0ce5db28a0d..e8cd296fe7631 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_stack_arg.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_stack_arg.c\n@@ -12,7 +12,8 @@ struct {\n \t__type(value, long long);\n } map_hash_8b SEC(\".maps\");\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n __noinline __used\ndiff --git a/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c b/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c\nindex c9fe4857da3f5..562e8319ffc22 100644\n--- a/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c\n+++ b/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c\n@@ -5,7 +5,8 @@\n #include \u003cbpf/bpf_helpers.h\u003e\n #include \"bpf_misc.h\"\n \n-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) \u0026\u0026 \\\n+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \\\n+\t(defined(__TARGET_ARCH_riscv) \u0026\u0026 __riscv_xlen == 64)) \u0026\u0026 \\\n \tdefined(__BPF_FEATURE_STACK_ARGUMENT)\n \n __noinline __used __naked\n"
}

2/1 2026/08/14 01:36 agent patch-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "EnableConfigs": [
    "BPF_JIT",
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_build_prologue"
  ],
  "Reasoning": "The patch implements support for BPF stack arguments in the RISC-V 64-bit BPF JIT compiler, modifying core JIT functions like bpf_jit_emit_insn and bpf_jit_build_prologue.",
  "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 8c03b531cdc62d7bf31a0c21191d0d4e46205dc8
Author: syz-cluster <triage@syzkaller.com>
Date:   Fri Aug 14 01:36:29 2026 +0000

    syz-cluster: applied patch under review

diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
index 419b9d795f2a7..9eb4e149505d5 100644
--- a/arch/riscv/net/bpf_jit.h
+++ b/arch/riscv/net/bpf_jit.h
@@ -82,6 +82,7 @@ struct rv_jit_context {
 	unsigned long flags;
 	int stack_size;
 	int tcc_offset;
+	u16 stack_arg_size;
 	u64 arena_vm_start;
 	u64 user_vm_start;
 };
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index 6b9972b07c1b0..58cb3e5ff6b4d 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -1815,18 +1815,43 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 
 		if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
 			const struct btf_func_model *fm;
-			int idx;
+			int idx, nargs;
 
 			fm = bpf_jit_find_kfunc_model(ctx->prog, insn);
 			if (!fm)
 				return -EINVAL;
 
-			for (idx = 0; idx < fm->nr_args; idx++) {
+			nargs = min_t(int, fm->nr_args, MAX_BPF_FUNC_REG_ARGS);
+			for (idx = 0; idx < nargs; idx++) {
 				u8 reg = bpf_to_rv_reg(BPF_REG_1 + idx, ctx);
 
 				if (fm->arg_size[idx] == sizeof(int))
 					emit_sextw(reg, reg, ctx);
 			}
+
+			/* BPF stack args -> RISC-V ABI: args 6-8 in A5-A7, 9+ at SP+0 */
+			if (fm->nr_args > MAX_BPF_FUNC_REG_ARGS) {
+				int n_stack = fm->nr_args - MAX_BPF_FUNC_REG_ARGS;
+				int n_reg = min_t(int, n_stack,
+						  RV_MAX_REG_ARGS - MAX_BPF_FUNC_REG_ARGS);
+
+				for (idx = 0; idx < n_reg; idx++) {
+					int sz = fm->arg_size[MAX_BPF_FUNC_REG_ARGS + idx];
+
+					emit_ld(RV_REG_A5 + idx, idx * 8, RV_REG_SP, ctx);
+					if (sz == sizeof(int))
+						emit_sextw(RV_REG_A5 + idx, RV_REG_A5 + idx, ctx);
+				}
+
+				for (idx = n_reg; idx < n_stack; idx++) {
+					int sz = fm->arg_size[MAX_BPF_FUNC_REG_ARGS + idx];
+
+					emit_ld(RV_REG_T1, idx * 8, RV_REG_SP, ctx);
+					if (sz == sizeof(int))
+						emit_sextw(RV_REG_T1, RV_REG_T1, ctx);
+					emit_sd(RV_REG_SP, (idx - n_reg) * 8, RV_REG_T1, ctx);
+				}
+			}
 		}
 
 		/* restore TCC to RV_REG_TCC before bpf2bpf call */
@@ -1891,6 +1916,21 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_LDX | BPF_MEM | BPF_H:
 	case BPF_LDX | BPF_MEM | BPF_W:
 	case BPF_LDX | BPF_MEM | BPF_DW:
+		if (insn->src_reg == BPF_REG_PARAMS) {
+			int idx = off / 8 - 1;
+
+			if (is_12b_int(idx * 8)) {
+				emit_ldx_insn(rd, idx * 8, RV_REG_FP, BPF_SIZE(code), false, ctx);
+			} else {
+				emit_imm(RV_REG_T1, idx * 8, ctx);
+				emit_add(RV_REG_T1, RV_REG_T1, RV_REG_FP, ctx);
+				emit_ldx_insn(rd, 0, RV_REG_T1, BPF_SIZE(code), false, ctx);
+			}
+			if (BPF_SIZE(code) != BPF_DW && insn_is_zext(&insn[1]))
+				return 1;
+			break;
+		}
+		fallthrough;
 	case BPF_LDX | BPF_PROBE_MEM | BPF_B:
 	case BPF_LDX | BPF_PROBE_MEM | BPF_H:
 	case BPF_LDX | BPF_PROBE_MEM | BPF_W:
@@ -1938,6 +1978,20 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_ST | BPF_MEM | BPF_H:
 	case BPF_ST | BPF_MEM | BPF_W:
 	case BPF_ST | BPF_MEM | BPF_DW:
+		if (insn->dst_reg == BPF_REG_PARAMS) {
+			int idx = -off / 8 - 1;
+
+			emit_imm(RV_REG_T1, imm, ctx);
+			if (is_12b_int(idx * 8)) {
+				emit_stx_insn(RV_REG_SP, idx * 8, RV_REG_T1, BPF_SIZE(code), ctx);
+			} else {
+				emit_imm(RV_REG_T2, idx * 8, ctx);
+				emit_add(RV_REG_T2, RV_REG_SP, RV_REG_T2, ctx);
+				emit_stx_insn(RV_REG_T2, 0, RV_REG_T1, BPF_SIZE(code), ctx);
+			}
+			break;
+		}
+		fallthrough;
 	/* ST | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = imm */
 	case BPF_ST | BPF_PROBE_MEM32 | BPF_B:
 	case BPF_ST | BPF_PROBE_MEM32 | BPF_H:
@@ -1960,6 +2014,19 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_STX | BPF_MEM | BPF_H:
 	case BPF_STX | BPF_MEM | BPF_W:
 	case BPF_STX | BPF_MEM | BPF_DW:
+		if (insn->dst_reg == BPF_REG_PARAMS) {
+			int idx = -off / 8 - 1;
+
+			if (is_12b_int(idx * 8)) {
+				emit_stx_insn(RV_REG_SP, idx * 8, rs, BPF_SIZE(code), ctx);
+			} else {
+				emit_imm(RV_REG_T1, idx * 8, ctx);
+				emit_add(RV_REG_T1, RV_REG_SP, RV_REG_T1, ctx);
+				emit_stx_insn(RV_REG_T1, 0, rs, BPF_SIZE(code), ctx);
+			}
+			break;
+		}
+		fallthrough;
 	/* STX | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = src */
 	case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
 	case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
@@ -2036,6 +2103,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
 
 	stack_adjust = round_up(stack_adjust, STACK_ALIGN);
 	stack_adjust += bpf_stack_adjust;
+	stack_adjust += ctx->stack_arg_size;
 
 	store_offset = stack_adjust - 8;
 
@@ -2093,7 +2161,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
 	emit_addi(RV_REG_FP, RV_REG_SP, stack_adjust, ctx);
 
 	if (bpf_stack_adjust)
-		emit_addi(RV_REG_S5, RV_REG_SP, bpf_stack_adjust, ctx);
+		emit_addi(RV_REG_S5, RV_REG_SP, ctx->stack_arg_size + bpf_stack_adjust, ctx);
 
 	ctx->stack_size = stack_adjust;
 
@@ -2171,3 +2239,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_stack_args(void)
+{
+	return true;
+}
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index cbfcd287ea166..844a0f3e0fa90 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -72,6 +72,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 	ctx->arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena);
 	ctx->user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena);
 	ctx->prog = prog;
+
+	ctx->stack_arg_size = round_up(bpf_out_stack_arg_cnt(env, prog) *
+				       sizeof(u64), STACK_ALIGN);
+
 	ctx->offset = kvzalloc_objs(int, prog->len);
 	if (!ctx->offset)
 		goto out_offset;
diff --git a/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c b/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c
index 8d38aafe66a28..ab12397a9b52a 100644
--- a/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c
+++ b/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c
@@ -4,7 +4,8 @@
 #include <bpf/bpf_helpers.h>
 #include "../test_kmods/bpf_testmod_kfunc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 long subprog_call_mem_kfunc(long a, long b, long c, long d, long e, long size)
diff --git a/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c b/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c
index 99bc115f8380a..a980a3a399d3f 100644
--- a/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c
+++ b/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c
@@ -3,7 +3,8 @@
 #include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 int subprog_bad_order_6args(int a, int b, int c, int d, int e, int f)
diff --git a/tools/testing/selftests/bpf/progs/stack_arg.c b/tools/testing/selftests/bpf/progs/stack_arg.c
index 944e3bb603e7e..3e9ed37c57bb9 100644
--- a/tools/testing/selftests/bpf/progs/stack_arg.c
+++ b/tools/testing/selftests/bpf/progs/stack_arg.c
@@ -21,7 +21,8 @@ struct {
 
 int timer_result;
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 const volatile bool has_stack_arg = true;
diff --git a/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c b/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c
index 345f2da2e361b..b6b1a8aa7f44a 100644
--- a/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c
+++ b/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c
@@ -6,7 +6,8 @@
 #include "bpf_kfuncs.h"
 #include "../test_kmods/bpf_testmod_kfunc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 const volatile bool has_stack_arg = true;
diff --git a/tools/testing/selftests/bpf/progs/stack_arg_precision.c b/tools/testing/selftests/bpf/progs/stack_arg_precision.c
index bee2eeec021d7..6eebafe7f2f87 100644
--- a/tools/testing/selftests/bpf/progs/stack_arg_precision.c
+++ b/tools/testing/selftests/bpf/progs/stack_arg_precision.c
@@ -6,7 +6,8 @@
 #include "../test_kmods/bpf_testmod_kfunc.h"
 #include "bpf_misc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 /* Force kfunc extern BTF generation for inline asm call below.
diff --git a/tools/testing/selftests/bpf/progs/verifier_stack_arg.c b/tools/testing/selftests/bpf/progs/verifier_stack_arg.c
index 7e0ce5db28a0d..e8cd296fe7631 100644
--- a/tools/testing/selftests/bpf/progs/verifier_stack_arg.c
+++ b/tools/testing/selftests/bpf/progs/verifier_stack_arg.c
@@ -12,7 +12,8 @@ struct {
 	__type(value, long long);
 } map_hash_8b SEC(".maps");
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 __noinline __used
diff --git a/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c b/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
index c9fe4857da3f5..562e8319ffc22 100644
--- a/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
+++ b/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
@@ -5,7 +5,8 @@
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 __noinline __used __naked

3/2 2026/08/14 01:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6702
							output: 36
							thoughts: 302
						

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

Okay, so we've got a patch here that's making some pretty fundamental changes to the RISC-V BPF JIT compiler – namely, adding support for stack arguments in BPF functions. This is significant, it touches core kernel functionality, and immediately triggers some thoughts about how to validate it.

I see the modified files: `bpf_jit.h`, `bpf_jit_comp64.c`, `bpf_jit_core.c`, and some BPF selftests. That's a good sign, selftests are crucial for this kind of low-level change. Definitely need to run those and any other relevant tests we have. Fuzzing is a must – this is a prime target for potential exploits.

Let's dive into the code. `bpf_jit_comp64.c` looks interesting. The key functions I'll examine are `bpf_jit_emit_insn`, `bpf_jit_build_prologue`, and the new `bpf_jit_supports_stack_args`. Those should illuminate how they're handling the stack operations and argument passing.

Now, in `bpf_jit_core.c`, I see `bpf_int_jit_compile`. Wait a minute... that's an *entry point* for the JIT compiler, a critical API function. That's a *major* focus for testing. We need to meticulously analyze how stack arguments are handled here, especially around any potential boundary conditions or error handling.

`bpf_jit_emit_insn` also jumps out; I should check if it's external or static, and whether it's called from other places besides `bpf_int_jit_compile` and how. We'll need to know which parts of the patch have external dependencies.



4/2 2026/08/14 01:36 tool grepper
0m Args:
{
  "Expression": "bpf_jit_emit_insn",
  "PathPrefix": "arch/riscv/net/"
}

Results:
{
  "Output": "arch/riscv/net/bpf_jit.h=1327=void bpf_jit_build_epilogue(struct rv_jit_context *ctx);\narch/riscv/net/bpf_jit.h-1328-\narch/riscv/net/bpf_jit.h:1329:int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\narch/riscv/net/bpf_jit.h-1330-\t\t      bool extra_pass);\n--\narch/riscv/net/bpf_jit_comp32.c=992=static void emit_zext64(const s8 *dst, struct rv_jit_context *ctx)\n--\narch/riscv/net/bpf_jit_comp32.c-1001-\narch/riscv/net/bpf_jit_comp32.c:1002:int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\narch/riscv/net/bpf_jit_comp32.c-1003-\t\t      bool extra_pass)\n--\narch/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--\narch/riscv/net/bpf_jit_core.c=19=static int build_body(struct rv_jit_context *ctx, bool extra_pass, int *offset)\n--\narch/riscv/net/bpf_jit_core.c-27-\narch/riscv/net/bpf_jit_core.c:28:\t\tret = bpf_jit_emit_insn(insn, ctx, extra_pass);\narch/riscv/net/bpf_jit_core.c-29-\t\tif (ret \u003e 0)\n"
}

5/2 2026/08/14 01:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8062
							output: 35
							thoughts: 85
						

Thoughts:
**My Initial BPF JIT Compilation Thoughts**

Okay, so I'm diving into this BPF JIT compilation flow. The function `bpf_jit_emit_insn` isn't static, it's declared in `bpf_jit.h`. That's good, it's visible. But the code flow is interesting: I see that it's called from `build_body`, and `build_body` is, in turn, called from `bpf_int_jit_compile`.  `bpf_int_jit_compile` seems to be the central entry point here, the big kahuna.

Right, so that's where the compilation really kicks off. Let's dig deeper into `bpf_int_jit_compile` and see what's happening at the core. That's where I need to focus my analysis.



6/2 2026/08/14 01:36 tool grepper
0m Args:
{
  "Expression": "bpf_int_jit_compile",
  "PathPrefix": "arch/riscv/net/"
}

Results:
{
  "Output": "arch/riscv/net/bpf_jit_core.c=39=bool bpf_jit_needs_zext(void)\n--\narch/riscv/net/bpf_jit_core.c-43-\narch/riscv/net/bpf_jit_core.c:44:struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\narch/riscv/net/bpf_jit_core.c-45-{\n"
}

7/2 2026/08/14 01:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8510
							output: 37
							thoughts: 70
						

Thoughts:
**BPF JIT Compilation Configuration on RISC-V**

Okay, so I'm looking at how BPF JIT compilation works on RISC-V. My go-to is always the `bpf_int_jit_compile` function; that's the standard entry point. Now, what specific configurations are we talking about here? I need to figure out what's enabled. `CONFIG_BPF_JIT` is the obvious one, and since we're on RISC-V, `CONFIG_RISCV` is certainly relevant. Where can I find the details on the interaction of these configurations? My first thought is to check the architecture-specific Kconfig and Makefiles. I'll start with `arch/riscv/Kconfig` to see if there are any specific options defined, and if that doesn't hold the info, I'll move on to `arch/riscv/net/Makefile` - sometimes those net-specific details have more configuration options. I'm after the interplay between BPF, JIT, and RISC-V.



8/2 2026/08/14 01:36 tool grepper
0m Args:
{
  "Expression": "bpf_jit_comp64.o",
  "PathPrefix": "arch/riscv/net/"
}

Results:
{
  "Output": "arch/riscv/net/Makefile=5=ifeq ($(CONFIG_ARCH_RV64I),y)\narch/riscv/net/Makefile:6:\tobj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o bpf_timed_may_goto.o\narch/riscv/net/Makefile-7-else\n"
}

9/2 2026/08/14 01:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 8942
							output: 37
							thoughts: 90
						

Thoughts:
Okay, here's my thought process on this, distilled into a first-person account as requested.

**BPF JIT Compilation Exploration**

Alright, first things first, I see that we need `CONFIG_BPF_JIT` enabled. That's the foundation. Now, I'm thinking about the BPF JIT compilation process itself, and specifically, the key functions involved. My mind immediately jumps to `bpf_int_jit_compile`. It's a pretty generic name, which suggests it’s likely a critical hot-path function for BPF JIT execution. I wonder if there are any other supporting functions that are worth investigating alongside it? Let me take a moment to refresh my memory and think through the process. Ah, yes, there are a few other ones that immediately come to mind - `bpf_jit_build_prologue` and `bpf_jit_supports_stack_args`...

Since I am thinking about function support, I should probably check out `bpf_jit_build_prologue` next. That's a good place to begin.



10/2 2026/08/14 01:36 tool grepper
0m Args:
{
  "Expression": "bpf_jit_build_prologue",
  "PathPrefix": "arch/riscv/net/"
}

Results:
{
  "Output": "arch/riscv/net/bpf_jit.h=1295=static inline void emit_cmpxchg(u8 rd, u8 rs, u8 r0, bool is64, struct rv_jit_context *ctx)\n--\narch/riscv/net/bpf_jit.h-1325-\narch/riscv/net/bpf_jit.h:1326:void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog);\narch/riscv/net/bpf_jit.h-1327-void bpf_jit_build_epilogue(struct rv_jit_context *ctx);\n--\narch/riscv/net/bpf_jit_comp32.c=1002=int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,\n--\narch/riscv/net/bpf_jit_comp32.c-1381-\narch/riscv/net/bpf_jit_comp32.c:1382:void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)\narch/riscv/net/bpf_jit_comp32.c-1383-{\n--\narch/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-2078-\narch/riscv/net/bpf_jit_comp64.c:2079:void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)\narch/riscv/net/bpf_jit_comp64.c-2080-{\n--\narch/riscv/net/bpf_jit_core.c=44=struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog)\n--\narch/riscv/net/bpf_jit_core.c-94-\narch/riscv/net/bpf_jit_core.c:95:\t\tbpf_jit_build_prologue(ctx, bpf_is_subprog(prog));\narch/riscv/net/bpf_jit_core.c-96-\t\tctx-\u003eprologue_len = ctx-\u003eninsns;\n--\narch/riscv/net/bpf_jit_core.c-150-\narch/riscv/net/bpf_jit_core.c:151:\tbpf_jit_build_prologue(ctx, bpf_is_subprog(prog));\narch/riscv/net/bpf_jit_core.c-152-\tif (build_body(ctx, extra_pass, NULL))\n"
}

11/2 2026/08/14 01:36 llm patch-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 10059
							output: 124
							thoughts: 625
						

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

Okay, so this patch is clearly focused on bringing stack argument support to the RISC-V 64-bit BPF JIT compiler. I see that `bpf_jit_emit_insn` and `bpf_jit_build_prologue` are the key functions being modified. They're definitely good targets to start with, especially since the patch modifies them to handle `BPF_PSEUDO_KFUNC_CALL`, `BPF_REG_PARAMS` in the context of `BPF_LDX` and `BPF_STX`. I noticed that `bpf_int_jit_compile` also is changed.

Looking at the code, it looks like `bpf_jit_build_prologue` is the one allocating space for stack arguments. And `bpf_int_jit_compile` calculates `ctx->stack_arg_size`. Since `bpf_int_jit_compile` seems to be that hot path entry function, that's important to include too.

The code changes are limited to the RISC-V specific code, so `arch/riscv/net/bpf_jit_comp64.c` and `arch/riscv/net/bpf_jit_core.c` are where the action is. I verified that those functions are not static, which means that they are directly callable.

The key configuration option here is `BPF_JIT`, since we are dealing with JIT. Of course, `CONFIG_BPF_SYSCALL` is a prerequisite, so let's make sure that's included.

Therefore, my plan is:

*   **WorthFuzzing: true** - Definitely worth fuzzing, this is an important area.
*   **FocusSymbols: ["bpf_jit_emit_insn", "bpf_jit_build_prologue", "bpf_int_jit_compile"]** - Those functions are the core of the changes.
*   **EnableConfigs: ["BPF_JIT", "BPF_SYSCALL"]** - These are the required configs.
*   **Reasoning: "The patch implements support for BPF stack arguments in the RISC-V 64-bit BPF JIT compiler, modifying core JIT functions like bpf_jit_emit_insn, bpf_jit_build_prologue, and bpf_int_jit_compile."** - This explains my selection.



12/2 2026/08/14 01:36 tool set-results
0m Args:
{
  "EnableConfigs": [
    "BPF_JIT",
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_build_prologue"
  ],
  "Reasoning": "The patch implements support for BPF stack arguments in the RISC-V 64-bit BPF JIT compiler, modifying core JIT functions like bpf_jit_emit_insn and bpf_jit_build_prologue.",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "BPF_JIT",
    "BPF_SYSCALL"
  ],
  "FocusSymbols": [
    "bpf_jit_emit_insn",
    "bpf_jit_build_prologue"
  ],
  "Reasoning": "The patch implements support for BPF stack arguments in the RISC-V 64-bit BPF JIT compiler, modifying core JIT functions like bpf_jit_emit_insn and bpf_jit_build_prologue.",
  "WorthFuzzing": true
}

13/1 2026/08/14 01:36 action If
0m Args:
{
  "WorthFuzzing": true
}

Results:
null

14/2 2026/08/14 01:36 agent kmsan-evaluator
0m Model:
best-expensive

Args:
null

Results:
{
  "KMSANReasoning": "The patch implements BPF stack arguments support for the RISC-V 64-bit JIT compiler. It modifies the translation of BPF instructions to RISC-V machine code, specifically handling stack offsets for function arguments. The changes do not introduce new kernel structures copied to user space, nor do they add complex C data structures or conditional logic dependent on uninitialized memory in the kernel's C code. Any bugs in the JIT compiler would result in incorrect code generation (e.g., crashes, out-of-bounds accesses, or register corruption), which are effectively caught by BPF selftests and standard KASAN. Furthermore, KMSAN is not currently supported on the RISC-V architecture, making a KMSAN run inapplicable for this architecture-specific patch.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
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 8c03b531cdc62d7bf31a0c21191d0d4e46205dc8
Author: syz-cluster <triage@syzkaller.com>
Date:   Fri Aug 14 01:36:29 2026 +0000

    syz-cluster: applied patch under review

diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h
index 419b9d795f2a7..9eb4e149505d5 100644
--- a/arch/riscv/net/bpf_jit.h
+++ b/arch/riscv/net/bpf_jit.h
@@ -82,6 +82,7 @@ struct rv_jit_context {
 	unsigned long flags;
 	int stack_size;
 	int tcc_offset;
+	u16 stack_arg_size;
 	u64 arena_vm_start;
 	u64 user_vm_start;
 };
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index 6b9972b07c1b0..58cb3e5ff6b4d 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -1815,18 +1815,43 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 
 		if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
 			const struct btf_func_model *fm;
-			int idx;
+			int idx, nargs;
 
 			fm = bpf_jit_find_kfunc_model(ctx->prog, insn);
 			if (!fm)
 				return -EINVAL;
 
-			for (idx = 0; idx < fm->nr_args; idx++) {
+			nargs = min_t(int, fm->nr_args, MAX_BPF_FUNC_REG_ARGS);
+			for (idx = 0; idx < nargs; idx++) {
 				u8 reg = bpf_to_rv_reg(BPF_REG_1 + idx, ctx);
 
 				if (fm->arg_size[idx] == sizeof(int))
 					emit_sextw(reg, reg, ctx);
 			}
+
+			/* BPF stack args -> RISC-V ABI: args 6-8 in A5-A7, 9+ at SP+0 */
+			if (fm->nr_args > MAX_BPF_FUNC_REG_ARGS) {
+				int n_stack = fm->nr_args - MAX_BPF_FUNC_REG_ARGS;
+				int n_reg = min_t(int, n_stack,
+						  RV_MAX_REG_ARGS - MAX_BPF_FUNC_REG_ARGS);
+
+				for (idx = 0; idx < n_reg; idx++) {
+					int sz = fm->arg_size[MAX_BPF_FUNC_REG_ARGS + idx];
+
+					emit_ld(RV_REG_A5 + idx, idx * 8, RV_REG_SP, ctx);
+					if (sz == sizeof(int))
+						emit_sextw(RV_REG_A5 + idx, RV_REG_A5 + idx, ctx);
+				}
+
+				for (idx = n_reg; idx < n_stack; idx++) {
+					int sz = fm->arg_size[MAX_BPF_FUNC_REG_ARGS + idx];
+
+					emit_ld(RV_REG_T1, idx * 8, RV_REG_SP, ctx);
+					if (sz == sizeof(int))
+						emit_sextw(RV_REG_T1, RV_REG_T1, ctx);
+					emit_sd(RV_REG_SP, (idx - n_reg) * 8, RV_REG_T1, ctx);
+				}
+			}
 		}
 
 		/* restore TCC to RV_REG_TCC before bpf2bpf call */
@@ -1891,6 +1916,21 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_LDX | BPF_MEM | BPF_H:
 	case BPF_LDX | BPF_MEM | BPF_W:
 	case BPF_LDX | BPF_MEM | BPF_DW:
+		if (insn->src_reg == BPF_REG_PARAMS) {
+			int idx = off / 8 - 1;
+
+			if (is_12b_int(idx * 8)) {
+				emit_ldx_insn(rd, idx * 8, RV_REG_FP, BPF_SIZE(code), false, ctx);
+			} else {
+				emit_imm(RV_REG_T1, idx * 8, ctx);
+				emit_add(RV_REG_T1, RV_REG_T1, RV_REG_FP, ctx);
+				emit_ldx_insn(rd, 0, RV_REG_T1, BPF_SIZE(code), false, ctx);
+			}
+			if (BPF_SIZE(code) != BPF_DW && insn_is_zext(&insn[1]))
+				return 1;
+			break;
+		}
+		fallthrough;
 	case BPF_LDX | BPF_PROBE_MEM | BPF_B:
 	case BPF_LDX | BPF_PROBE_MEM | BPF_H:
 	case BPF_LDX | BPF_PROBE_MEM | BPF_W:
@@ -1938,6 +1978,20 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_ST | BPF_MEM | BPF_H:
 	case BPF_ST | BPF_MEM | BPF_W:
 	case BPF_ST | BPF_MEM | BPF_DW:
+		if (insn->dst_reg == BPF_REG_PARAMS) {
+			int idx = -off / 8 - 1;
+
+			emit_imm(RV_REG_T1, imm, ctx);
+			if (is_12b_int(idx * 8)) {
+				emit_stx_insn(RV_REG_SP, idx * 8, RV_REG_T1, BPF_SIZE(code), ctx);
+			} else {
+				emit_imm(RV_REG_T2, idx * 8, ctx);
+				emit_add(RV_REG_T2, RV_REG_SP, RV_REG_T2, ctx);
+				emit_stx_insn(RV_REG_T2, 0, RV_REG_T1, BPF_SIZE(code), ctx);
+			}
+			break;
+		}
+		fallthrough;
 	/* ST | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = imm */
 	case BPF_ST | BPF_PROBE_MEM32 | BPF_B:
 	case BPF_ST | BPF_PROBE_MEM32 | BPF_H:
@@ -1960,6 +2014,19 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
 	case BPF_STX | BPF_MEM | BPF_H:
 	case BPF_STX | BPF_MEM | BPF_W:
 	case BPF_STX | BPF_MEM | BPF_DW:
+		if (insn->dst_reg == BPF_REG_PARAMS) {
+			int idx = -off / 8 - 1;
+
+			if (is_12b_int(idx * 8)) {
+				emit_stx_insn(RV_REG_SP, idx * 8, rs, BPF_SIZE(code), ctx);
+			} else {
+				emit_imm(RV_REG_T1, idx * 8, ctx);
+				emit_add(RV_REG_T1, RV_REG_SP, RV_REG_T1, ctx);
+				emit_stx_insn(RV_REG_T1, 0, rs, BPF_SIZE(code), ctx);
+			}
+			break;
+		}
+		fallthrough;
 	/* STX | PROBE_MEM32: *(size *)(dst + RV_REG_ARENA + off) = src */
 	case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
 	case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
@@ -2036,6 +2103,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
 
 	stack_adjust = round_up(stack_adjust, STACK_ALIGN);
 	stack_adjust += bpf_stack_adjust;
+	stack_adjust += ctx->stack_arg_size;
 
 	store_offset = stack_adjust - 8;
 
@@ -2093,7 +2161,7 @@ void bpf_jit_build_prologue(struct rv_jit_context *ctx, bool is_subprog)
 	emit_addi(RV_REG_FP, RV_REG_SP, stack_adjust, ctx);
 
 	if (bpf_stack_adjust)
-		emit_addi(RV_REG_S5, RV_REG_SP, bpf_stack_adjust, ctx);
+		emit_addi(RV_REG_S5, RV_REG_SP, ctx->stack_arg_size + bpf_stack_adjust, ctx);
 
 	ctx->stack_size = stack_adjust;
 
@@ -2171,3 +2239,8 @@ bool bpf_jit_supports_timed_may_goto(void)
 {
 	return true;
 }
+
+bool bpf_jit_supports_stack_args(void)
+{
+	return true;
+}
diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c
index cbfcd287ea166..844a0f3e0fa90 100644
--- a/arch/riscv/net/bpf_jit_core.c
+++ b/arch/riscv/net/bpf_jit_core.c
@@ -72,6 +72,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 	ctx->arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena);
 	ctx->user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena);
 	ctx->prog = prog;
+
+	ctx->stack_arg_size = round_up(bpf_out_stack_arg_cnt(env, prog) *
+				       sizeof(u64), STACK_ALIGN);
+
 	ctx->offset = kvzalloc_objs(int, prog->len);
 	if (!ctx->offset)
 		goto out_offset;
diff --git a/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c b/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c
index 8d38aafe66a28..ab12397a9b52a 100644
--- a/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c
+++ b/tools/testing/selftests/bpf/progs/btf__stack_arg_precision.c
@@ -4,7 +4,8 @@
 #include <bpf/bpf_helpers.h>
 #include "../test_kmods/bpf_testmod_kfunc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 long subprog_call_mem_kfunc(long a, long b, long c, long d, long e, long size)
diff --git a/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c b/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c
index 99bc115f8380a..a980a3a399d3f 100644
--- a/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c
+++ b/tools/testing/selftests/bpf/progs/btf__verifier_stack_arg_order.c
@@ -3,7 +3,8 @@
 #include <vmlinux.h>
 #include <bpf/bpf_helpers.h>
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 int subprog_bad_order_6args(int a, int b, int c, int d, int e, int f)
diff --git a/tools/testing/selftests/bpf/progs/stack_arg.c b/tools/testing/selftests/bpf/progs/stack_arg.c
index 944e3bb603e7e..3e9ed37c57bb9 100644
--- a/tools/testing/selftests/bpf/progs/stack_arg.c
+++ b/tools/testing/selftests/bpf/progs/stack_arg.c
@@ -21,7 +21,8 @@ struct {
 
 int timer_result;
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 const volatile bool has_stack_arg = true;
diff --git a/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c b/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c
index 345f2da2e361b..b6b1a8aa7f44a 100644
--- a/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c
+++ b/tools/testing/selftests/bpf/progs/stack_arg_kfunc.c
@@ -6,7 +6,8 @@
 #include "bpf_kfuncs.h"
 #include "../test_kmods/bpf_testmod_kfunc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 const volatile bool has_stack_arg = true;
diff --git a/tools/testing/selftests/bpf/progs/stack_arg_precision.c b/tools/testing/selftests/bpf/progs/stack_arg_precision.c
index bee2eeec021d7..6eebafe7f2f87 100644
--- a/tools/testing/selftests/bpf/progs/stack_arg_precision.c
+++ b/tools/testing/selftests/bpf/progs/stack_arg_precision.c
@@ -6,7 +6,8 @@
 #include "../test_kmods/bpf_testmod_kfunc.h"
 #include "bpf_misc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 /* Force kfunc extern BTF generation for inline asm call below.
diff --git a/tools/testing/selftests/bpf/progs/verifier_stack_arg.c b/tools/testing/selftests/bpf/progs/verifier_stack_arg.c
index 7e0ce5db28a0d..e8cd296fe7631 100644
--- a/tools/testing/selftests/bpf/progs/verifier_stack_arg.c
+++ b/tools/testing/selftests/bpf/progs/verifier_stack_arg.c
@@ -12,7 +12,8 @@ struct {
 	__type(value, long long);
 } map_hash_8b SEC(".maps");
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 __noinline __used
diff --git a/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c b/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
index c9fe4857da3f5..562e8319ffc22 100644
--- a/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
+++ b/tools/testing/selftests/bpf/progs/verifier_stack_arg_order.c
@@ -5,7 +5,8 @@
 #include <bpf/bpf_helpers.h>
 #include "bpf_misc.h"
 
-#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64)) && \
+#if (defined(__TARGET_ARCH_x86) || defined(__TARGET_ARCH_arm64) || \
+	(defined(__TARGET_ARCH_riscv) && __riscv_xlen == 64)) && \
 	defined(__BPF_FEATURE_STACK_ARGUMENT)
 
 __noinline __used __naked

15/3 2026/08/14 01:36 llm kmsan-evaluator
0m Model:
gemini-3.1-pro-preview

Args:
null

Results:
null

Tokens:
							input: 6699
							output: 186
							thoughts: 829
						

Thoughts:
**My Assessment: No KMSAN Needed**

Okay, so this patch is all about optimizing the RISC-V BPF JIT compiler. Specifically, it's adding stack argument support for BPF functions that take a lot of arguments – more than the register count allows – by modifying the code generation to handle loading and storing them on the stack. My initial concern was about uninitialized memory exposure, a classic issue. But after digging in, I'm pretty confident that's not the case here.

This patch is *solely* concerned with the JIT compiler, which translates BPF instructions into RISC-V machine code. Any bugs introduced here would manifest as flawed machine code, leading to potentially incorrect behavior, crashes, or memory corruption. BPF selftests are a solid defense in this case, and the usual KASAN mechanisms would likely catch any out-of-bounds accesses or similar issues. The key thing is that the *patch itself* isn't introducing uninitialized *kernel* memory or new data structures that would be susceptible to KMSAN's instrumentation of C code.

Let me clarify: KMSAN isn't even relevant here. KMSAN is for x86_64 and s390x, and potentially arm64, not RISC-V. We're talking about a RISC-V-specific change. Even if KMSAN *were* available, it instruments the C code. A JIT stack argument bug is a *logic* bug in code generation, it might result in the BPF program accessing uninitialized stack memory, but KMSAN doesn't (as far as I know) instrument BPF JIT code in this way, especially since this is RISC-V specific. The BPF KMSAN instrumentation is a separate thing.

To be absolutely sure, I went back and re-examined the code. The `ctx` variable, used throughout the modified functions, gets zeroed when allocated via `kvzalloc_objs`. The changes affect the instruction emission logic (`bpf_jit_emit_insn`) and prologue construction (`bpf_jit_build_prologue`) but don't introduce complex new data structures that are copied to userspace or anything that relies on uninitialized C variables. So the risk of uninitialized memory being exposed is practically nil.

Therefore, `NeedsKMSAN = false`. This patch is a JIT compilation optimization and doesn't warrant a KMSAN run.



16/3 2026/08/14 01:37 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch implements BPF stack arguments support for the RISC-V 64-bit JIT compiler. It modifies the translation of BPF instructions to RISC-V machine code, specifically handling stack offsets for function arguments. The changes do not introduce new kernel structures copied to user space, nor do they add complex C data structures or conditional logic dependent on uninitialized memory in the kernel's C code. Any bugs in the JIT compiler would result in incorrect code generation (e.g., crashes, out-of-bounds accesses, or register corruption), which are effectively caught by BPF selftests and standard KASAN. Furthermore, KMSAN is not currently supported on the RISC-V architecture, making a KMSAN run inapplicable for this architecture-specific patch.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch implements BPF stack arguments support for the RISC-V 64-bit JIT compiler. It modifies the translation of BPF instructions to RISC-V machine code, specifically handling stack offsets for function arguments. The changes do not introduce new kernel structures copied to user space, nor do they add complex C data structures or conditional logic dependent on uninitialized memory in the kernel's C code. Any bugs in the JIT compiler would result in incorrect code generation (e.g., crashes, out-of-bounds accesses, or register corruption), which are effectively caught by BPF selftests and standard KASAN. Furthermore, KMSAN is not currently supported on the RISC-V architecture, making a KMSAN run inapplicable for this architecture-specific patch.",
  "NeedsKMSAN": false
}

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)