| a8471eb0 | 19-Oct-2026 |
Kumar Kartikeya Dwivedi <memxor@gmail.com> |
bpf: Set up the arena base only in functions that use it
A JIT sets up the arena base in the prologue of every function of a program that has an arena, a callee-saved register loaded with a 64-bit i
bpf: Set up the arena base only in functions that use it
A JIT sets up the arena base in the prologue of every function of a program that has an arena, a callee-saved register loaded with a 64-bit immediate and spilled around the function on x86. That is paid for by every program with an arena, whether it touches the arena or not, and now that libbpf binds the arena of an object to every program in it, by every program of an object that happens to contain an arena.
Decide per function, on its final insns, right before it is JITed. bpf_prog_has_arena_insns() looks for an insn that works with the base: an access through an arena pointer, or through a number in a program loaded with BPF_F_ARENA_SCALAR, has been rewritten to a BPF_PROBE_MEM32 form by then, a cast to the user address space keeps BPF_ADDR_SPACE_CAST, and a kfunc call with an __arena argument, which the JIT rebases, has a function model that says so. A load of an __arena struct member is rewritten with an immediate and needs none; dereferencing the result does.
Looking at the final insns rather than recording the uses during verification keeps the answer in step with what the JIT sees. A constant NULL passed to a nullable __arena kfunc argument takes the early exit for NULL arguments in the verifier, and the JIT rebases the call all the same; an insn that is dead code has disappeared by then.
bpf_prog_jit_compile() caches the answer in bpf_prog_aux for a single function program, jit_subprogs() for each subprogram once it has its kfunc table and arena. It implies that the program has an arena, as the scan says no without one. The JITs with arena support pick up the arena base and user address only when bpf_prog_uses_arena_insns() says so, and so generate the prologue and epilogue of a program bound to an arena it never touches as if it had none.
The other users of the arena address of a program stay as they are on purpose. The struct_ops trampoline converts __arena arguments on entry and arena_member_fixup() converts loaded __arena members after the load, both with the base as an immediate. Both have to happen whether or not the program dereferences the result, it may compare, store or pass it on, so neither depends on the base register nor on the flag. The arena fault report reads the user address of the arena the faulting insn belongs to, and such an insn sets the flag anyway. check_map_prog_compatibility() checks the user address when the arena is bound, before any use is known. The rest, in arena.c and sched_ext, works with the map and not with a program.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261019132203.3034698-14-memxor@gmail.com
show more ...
|
| c0316386 | 28-Sep-2026 |
Chen Pei <cp0613@linux.alibaba.com> |
bpf, riscv: Add support for indirect jumps
Implement JIT support for the indirect jump instruction (BPF_JMP | BPF_JA | BPF_X), a.k.a. gotox, which lets a BPF program jump through a BPF_MAP_TYPE_INSN
bpf, riscv: Add support for indirect jumps
Implement JIT support for the indirect jump instruction (BPF_JMP | BPF_JA | BPF_X), a.k.a. gotox, which lets a BPF program jump through a BPF_MAP_TYPE_INSN_ARRAY jump table.
Emit "jalr zero, rd, 0" and hand the xlated to jitted offsets to bpf_prog_update_insn_ptrs(), which is what fills in the jump table entries; without that call the load fails with -EFAULT in bpf_insn_array_ready(). ctx->offset[] holds the offset of the insn *following* insn i, as bpf_prog_fill_jited_linfo() expects, so it is shifted by one and offset[0] comes from the prologue length. build_body() now records both halves of a multi-insn record, so no slot keeps a fabricated offset.
Only the RV64 JIT is covered; RV32 keeps failing to load as before.
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Björn Töpel <bjorn@kernel.org> Reviewed-by: Pu Lehui <pulehui@huawei.com> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://patch.msgid.link/20260928071845.2432-2-cp0613@linux.alibaba.com
show more ...
|
| b4a1ecae | 30-Sep-2026 |
Kumar Kartikeya Dwivedi <memxor@gmail.com> |
bpf, riscv: Fix stack-passed arguments for indirect trampolines
store_args() reads stack-passed arguments relative to FP assuming the trampoline was entered through the fentry call from a traced fun
bpf, riscv: Fix stack-passed arguments for indirect trampolines
store_args() reads stack-passed arguments relative to FP assuming the trampoline was entered through the fentry call from a traced function. In that path, the trampoline pushes the parent frame before establishing its final FP, so the incoming stack arguments start at FP + 16.
An indirect trampoline for a struct_ops callback is called through a function pointer. Its prologue allocates only the trampoline frame and sets FP to the incoming SP. The RISC-V ABI places the first stack argument at that incoming SP, so the arguments start at FP, not FP + 16. Every stack-passed argument of a callback with more than eight argument slots is therefore read two slots late.
Pass the prologue-dependent offset to store_args(), using zero for a direct struct_ops trampoline and 16 for the fentry path.
Fixes: 6801b0aef79d ("riscv, bpf: Add 12-argument support for RV64 bpf trampoline") Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260930083522.1914145-2-pulehui@huaweicloud.com
show more ...
|
| ba754185 | 05-Sep-2026 |
Feng Jiang <jiangfeng@kylinos.cn> |
riscv, bpf: Add BPF stack arguments support for RV64 JIT
Implement bpf_jit_supports_stack_args() on RV64 JIT to allow bpf subprogs and kfuncs to pass and receive more than 5 arguments.
In the riscv
riscv, bpf: Add BPF stack arguments support for RV64 JIT
Implement bpf_jit_supports_stack_args() on RV64 JIT to allow bpf subprogs and kfuncs to pass and receive more than 5 arguments.
In the riscv abi, the first 8 arguments are passed in registers a0 to a7, and arguments 9+ reside on the stack. To align bpf stack arguments with this calling convention and unify bpf2bpf calls with kfuncs, map the first 3 bpf stack arguments (6th to 8th) directly to a5 to a7, and store or load the remaining arguments (9th+) at SP or FP. Reserve outgoing stack space in the prologue accordingly when stack_arg_cnt exceeds 3.
In addition, update kfunc argument sign extension to handle all 8 register arguments as well as any arguments passed on the stack.
Co-developed-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Signed-off-by: Pu Lehui <pulehui@huawei.com> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260905085857.14143-3-pulehui@huaweicloud.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| b4757714 | 19-Aug-2026 |
Chen Pei <cp0613@linux.alibaba.com> |
bpf, riscv: Add support for signed arena loads
Signed loads from arena memory are currently rejected on riscv64, as bpf_jit_supports_insn() refuses BPF_MEMSX loads when in_arena is set, while x86 an
bpf, riscv: Add support for signed arena loads
Signed loads from arena memory are currently rejected on riscv64, as bpf_jit_supports_insn() refuses BPF_MEMSX loads when in_arena is set, while x86 and arm64 gained support for them in v6.18. Compilers such as GCC-14 are free to generate signed loads into arena memory, which breaks loading of otherwise valid BPF programs on riscv64.
Implement BPF_PROBE_MEM32SX support in the RV64 JIT by reusing the existing arena handling: the arena base (RV_REG_ARENA) is added to the source register and the load is emitted with sign extension (lb/lh/lw). Add BPF_PROBE_MEM32SX to the add_exception_handler() mode gate so that faulting loads get an exception table entry which clears the destination register and resumes execution. Since BPF_PROBE_MEM32SX shares its mode value (0xc0) with BPF_ATOMIC, the gate accepts it only for LDX class instructions so that plain atomic instructions do not register exception table entries.
Verified by running the arena LDSX selftests (arena_ldsx_disasm, arena_ldsx_exception, arena_ldsx_s8/s16/s32) and the full arena_atomics test suite on riscv64 QEMU, all passing.
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com> Tested-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Pu Lehui <pulehui@huawei.com> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/67422a421852c3eed2269c6def7b5569e727617f.1787140923.git.cp0613@linux.alibaba.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| 6ef8ff20 | 23-Jul-2026 |
Feng Jiang <jiangfeng@kylinos.cn> |
bpf, riscv: Add support for timed may_goto
Implement arch_bpf_timed_may_goto() for the RV64 JIT. The argument and return value are carried in BPF_REG_AX, and BPF R0-R5 are preserved across the call
bpf, riscv: Add support for timed may_goto
Implement arch_bpf_timed_may_goto() for the RV64 JIT. The argument and return value are carried in BPF_REG_AX, and BPF R0-R5 are preserved across the call to the generic bpf_check_timed_may_goto().
Enable bpf_jit_supports_timed_may_goto() so the verifier uses the timed expansion path.
Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Reviewed-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260723-riscv-bpf-timed-may-goto-v5-1-86acb54e5642@kylinos.cn Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| a1b37972 | 14-Jul-2026 |
Kuan-Wei Chiu <visitorckw@gmail.com> |
riscv, bpf: Add 32 bit atomic operations to RV32 JIT
The RV32 BPF JIT compiler currently only supports the BPF_ADD atomic operation. Other 32 bit atomic operations (and, or, xor, xchg) and their BPF
riscv, bpf: Add 32 bit atomic operations to RV32 JIT
The RV32 BPF JIT compiler currently only supports the BPF_ADD atomic operation. Other 32 bit atomic operations (and, or, xor, xchg) and their BPF_FETCH variants are not supported and gracefully fall back to the interpreter.
Since the RISC-V A extension is required for Linux on RV32, we can natively support these 32-bit BPF atomic operations by mapping them directly to the corresponding RISC-V amo*.w instructions.
Implement BPF_ADD, BPF_AND, BPF_OR, BPF_XOR, and BPF_XCHG with and without BPF_FETCH. BPF_CMPXCHG requires a more complex lr.w/sc.w loop and is left to fall back to the interpreter.
Before this patch: [ 138.862161] test_bpf: Summary: 1054 PASSED, 0 FAILED, [843/1042 JIT'ed]
After this patch: [ 157.024124] test_bpf: Summary: 1054 PASSED, 0 FAILED, [902/1042 JIT'ed]
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com> Reviewed-by: Pu Lehui <pulehui@huawei.com> Link: https://lore.kernel.org/bpf/20260714002451.4091139-4-visitorckw@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| c6a08afd | 14-Jul-2026 |
Kuan-Wei Chiu <visitorckw@gmail.com> |
riscv, bpf: Add support for BPF_MOVSX in RV32 JIT
The current rv32 bpf jit compiler incorrectly treats BPF_MOVSX as a standard zero-extended move operation. The bpf instruction set allows sign-exten
riscv, bpf: Add support for BPF_MOVSX in RV32 JIT
The current rv32 bpf jit compiler incorrectly treats BPF_MOVSX as a standard zero-extended move operation. The bpf instruction set allows sign-extension moves by reusing the BPF_MOV opcode with the instruction offset set to 8, 16, or 32.
Update the bpf_jit_emit_insn() function to check the offset field for both ALU and ALU64 MOV operations. If the offset is non-zero, emit the correct slli and srai instructions to perform the sign extension.
Before this patch: [ 19.549705] test_bpf: #82 ALU_MOVSX | BPF_B jited:1 ret 2 != 1 (0x2 != 0x1)FAIL (1 times) [ 19.551354] test_bpf: #83 ALU_MOVSX | BPF_H jited:1 ret 2 != 1 (0x2 != 0x1)FAIL (1 times) [ 19.552576] test_bpf: #84 ALU64_MOVSX | BPF_B jited:1 ret 2 != 1 (0x2 != 0x1)FAIL (1 times) [ 19.553542] test_bpf: #85 ALU64_MOVSX | BPF_H jited:1 ret 2 != 1 (0x2 != 0x1)FAIL (1 times) [ 19.554807] test_bpf: #86 ALU64_MOVSX | BPF_W jited:1 ret 2 != 1 (0x2 != 0x1)FAIL (1 times)
After this patch: [ 17.931172] test_bpf: #82 ALU_MOVSX | BPF_B jited:1 125 PASS [ 17.932198] test_bpf: #83 ALU_MOVSX | BPF_H jited:1 124 PASS [ 17.933039] test_bpf: #84 ALU64_MOVSX | BPF_B jited:1 124 PASS [ 17.933918] test_bpf: #85 ALU64_MOVSX | BPF_H jited:1 124 PASS [ 17.934751] test_bpf: #86 ALU64_MOVSX | BPF_W jited:1 122 PASS
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com> Reviewed-by: Pu Lehui <pulehui@huawei.com> Link: https://lore.kernel.org/bpf/20260714002451.4091139-3-visitorckw@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| 2e0fa238 | 14-Jul-2026 |
Kuan-Wei Chiu <visitorckw@gmail.com> |
riscv, bpf: Add support for BPF_SDIV and BPF_SMOD in RV32 JIT
The current rv32 bpf jit compiler incorrectly treats BPF_SDIV and BPF_SMOD as unsigned operations. The BPF instruction set allows signed
riscv, bpf: Add support for BPF_SDIV and BPF_SMOD in RV32 JIT
The current rv32 bpf jit compiler incorrectly treats BPF_SDIV and BPF_SMOD as unsigned operations. The BPF instruction set allows signed division and modulo by reusing the BPF_DIV and BPF_MOD opcodes with the instruction offset set to 1.
Update the emit_alu_r32() function to accept an 'is_sdiv' variable and emit the correct div and rem instructions when the offset is 1.
Before this patch: [ 44.161771] test_bpf: #165 ALU_SDIV_X: -6 / 2 = -3 jited:1 ret 2147483645 != -3 (0x7ffffffd != 0xfffffffd)FAIL (1 times) [ 44.167385] test_bpf: #166 ALU_SDIV_K: -6 / 2 = -3 jited:1 ret 2147483645 != -3 (0x7ffffffd != 0xfffffffd)FAIL (1 times) [ 44.171053] test_bpf: #169 ALU_SMOD_X: -7 % 2 = -1 jited:1 ret 1 != -1 (0x1 != 0xffffffff)FAIL (1 times) [ 44.172081] test_bpf: #170 ALU_SMOD_K: -7 % 2 = -1 jited:1 ret 1 != -1 (0x1 != 0xffffffff)FAIL (1 times)
After this patch: [ 16.002192] test_bpf: #165 ALU_SDIV_X: -6 / 2 = -3 jited:1 95 PASS [ 16.002983] test_bpf: #166 ALU_SDIV_K: -6 / 2 = -3 jited:1 1059 PASS [ 16.017167] test_bpf: #169 ALU_SMOD_X: -7 % 2 = -1 jited:1 136 PASS [ 16.023002] test_bpf: #170 ALU_SMOD_K: -7 % 2 = -1 jited:1 109 PASS
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com> Reviewed-by: Pu Lehui <pulehui@huawei.com> Link: https://lore.kernel.org/bpf/20260714002451.4091139-2-visitorckw@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| 5eb89213 | 20-Jul-2026 |
Feng Jiang <jiangfeng@kylinos.cn> |
bpf, riscv: Fix extable handling for arena load_acquire
emit_atomic_ld_st() returns 1 to have build_body() skip the zext after a sub-word load_acquire. The caller does "ret = ret ?: add_exception_ha
bpf, riscv: Fix extable handling for arena load_acquire
emit_atomic_ld_st() returns 1 to have build_body() skip the zext after a sub-word load_acquire. The caller does "ret = ret ?: add_exception_handler(...)", which skips add_exception_handler() on any non-zero ret, so the extable entry is missing and a faulting PROBE_ATOMIC load_acquire oopses.
REG_DONT_CLEAR_MARKER leaves rd stale on fault, and the verifier still thinks the load overwrote it, so a program can leak it through a map.
Check ret >= 0 before calling add_exception_handler(), and pass rd for LOAD_ACQ so the fault zeroes rd like a PROBE_MEM load. Return ret unchanged for the zext skip.
Fixes: fb7cefabae81 ("riscv, bpf: Add support arena atomics for RV64") Suggested-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Reviewed-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260720-bpf-riscv-fix-extable-v4-1-165c0b3b07d5@kylinos.cn Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| ec72848c | 08-Jul-2026 |
Pu Lehui <pulehui@huawei.com> |
riscv, bpf: Mixing bpf2bpf and tailcalls
In the current RV64 JIT, if we just don't initialize the TCC in subprog, the TCC can be propagated from the parent process to the subprocess, but the updated
riscv, bpf: Mixing bpf2bpf and tailcalls
In the current RV64 JIT, if we just don't initialize the TCC in subprog, the TCC can be propagated from the parent process to the subprocess, but the updated TCC of the parent process cannot be restored when the subprocess exits. Since the RV64 TCC is initialized before saving the callee saved registers into the stack, we cannot use the callee saved register to pass the TCC, otherwise the original value of the callee saved register will be destroyed. So we implemented mixing bpf2bpf and tailcalls similar to x86_64, i.e. using a non-callee saved register to transfer the TCC between functions, and saving that register to the stack to protect the TCC value. As for the tailcall hierarchy issue, inspired by the s390's low-overhead approach, we store TCC from RV_REG_TCC back to stack after calling bpf2bpf call or calling orig bpf func in bpf trampoline.
Tests test_bpf.ko and test_verifier have passed, as well as the relative testcases of test_progs*.
Signed-off-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260708064436.2971933-7-pulehui@huaweicloud.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| a21731f5 | 08-Jul-2026 |
Pu Lehui <pulehui@huawei.com> |
riscv, bpf: Add RV_TAILCALL_OFFSET macro to format tailcall offset
Add RV_TAILCALL_OFFSET macro to format tailcall offset, and correct the relevant comments.
Signed-off-by: Pu Lehui <pulehui@huawei
riscv, bpf: Add RV_TAILCALL_OFFSET macro to format tailcall offset
Add RV_TAILCALL_OFFSET macro to format tailcall offset, and correct the relevant comments.
Signed-off-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260708064436.2971933-6-pulehui@huaweicloud.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| 52fb1756 | 08-Jul-2026 |
Pu Lehui <pulehui@huawei.com> |
riscv, bpf: Fix kernel stack corruption in tailcall with CFI
When CONFIG_CFI_CLANG is enabled, prog->bpf_func already skips the kcfi instruction during setup. Including it again in the tailcall jump
riscv, bpf: Fix kernel stack corruption in tailcall with CFI
When CONFIG_CFI_CLANG is enabled, prog->bpf_func already skips the kcfi instruction during setup. Including it again in the tailcall jump offset causes it to jump over an extra 4 bytes, skipping the stack pointer adjustment, which will result in kernel stack corruption.
Fixes: 30a59cc79754 ("riscv, bpf: Fix possible infinite tailcall when CONFIG_CFI_CLANG is enabled") Reported-by: Sashiko <sashiko-bot@kernel.org> Signed-off-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260708064436.2971933-5-pulehui@huaweicloud.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|
| f3ab8785 | 08-Jul-2026 |
Pu Lehui <pulehui@huawei.com> |
riscv, bpf: Using kvzalloc_objs to allocate cache buffer
It is unnecessary to allocate continuous physical memory for cache buffer, and when ebpf program is too large, it may cause memory allocation
riscv, bpf: Using kvzalloc_objs to allocate cache buffer
It is unnecessary to allocate continuous physical memory for cache buffer, and when ebpf program is too large, it may cause memory allocation failure.
Signed-off-by: Pu Lehui <pulehui@huawei.com> Reviewed-by: Björn Töpel <bjorn@kernel.org> Acked-by: Björn Töpel <bjorn@kernel.org> Link: https://lore.kernel.org/bpf/20260708064436.2971933-4-pulehui@huaweicloud.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
show more ...
|