aboutsummaryrefslogtreecommitdiff
path: root/arch/loongarch/net
AgeCommit message (Collapse)AuthorFilesLines
2 daysMerge tag 'loongarch-7.4' of ↵Linus Torvalds2-193/+223
git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson Pull LoongArch updates from Huacai Chen: - Add LoongArch-specific ACPI initialization - Set NX compat flag in PE/COFF efi header - Use pa_to_nid()/nid_to_addrbase() rather than hard-code - Detect and expose LAMCAS/DIV32 feature existence - Fix and improve perf hardware breakpoints - Fix and improve BPF JIT (trampoline and 32-bit operations) - Add arch_crash_save_vmcoreinfo() support - Some bug fixes and other small changes * tag 'loongarch-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: (24 commits) soc: loongson: loongson2_guts: Use of_root instead of own reference soc: loongson: loongson2_pm: Fix build warnings for 32BIT LoongArch: dts: loongson-2k0500: Drop unsupported bus_id in DWMAC LoongArch: BPF: Optimize 32-bit operations using native instructions LoongArch: BPF: Clean up and decouple is32 parameter from move_imm() LoongArch: BPF: Fix stack arguments for indirect trampolines LoongArch: Add arch_crash_save_vmcoreinfo() support LoongArch: Fix one-shot limitation for perf hardware breakpoints LoongArch: Fix perf hardware breakpoint failure via installation LoongArch: Only send SIGTRAP signal if necessary in do_watch() LoongArch: Fix architectural naming typo for CSR_FWPS_SKIP LoongArch: Fix bitmask corruption in update_bp_registers() LoongArch: Remove redundant call in update_bp_registers() LoongArch: Remove arch-specific __smp_mb__{before,after}_atomic() LoongArch: Detect and expose DIV32 feature existence LoongArch: Detect and expose LAMCAS feature existence LoongArch: Use pa_to_nid()/nid_to_addrbase() rather than hard-code LoongArch: Don't init & online empty nodes LoongArch: Call cpu_final_simd() with pure_initcall() LoongArch: Use assign_bit() API where applicable ...
5 daysLoongArch: BPF: Optimize 32-bit operations using native instructionsTiezhu Yang2-155/+178
Currently, the LoongArch BPF JIT emits numerous redundant zero and sign extensions across 32-bit operations, bloating the final JIT image size and also leading to runtime overhead, particularly in the division and modulo operations. Thus, it is necessary to optimize 32-bit operations by emitting LoongArch native 32-bit word instructions. For general ALU32 operations, utilize native 32-bit word instructions for core calculations. Given that the BPF spec requires the upper 32 bits of the destination register to be zero-extended upon completion, use a unified 'bstrpickd' instruction to clear the upper 32 bits at the common exit of build_insn(), while immediate loads are optimized via (u32) casting to bypass the trailing extension. According to the LoongArch Reference Manual, native 32-bit division and modulo instructions (DIV.W[U] and MOD.W[U]) require the upper 33 bits [63:31] of both input operands to be all 0s or all 1s (0x0 or 0x1ffffffff), that is to say, they need to be properly sign-extended by the software on CPU cores without the DIV32 feature. Otherwise, the 32-bit division and modulo instructions will trigger undefined hardware behaviors and return unexpected values. To ensure both performance and hardware compatibility, leverage the newly introduced 'cpu_has_div32' helper: (1) on newer CPUs with DIV32, emit native 32-bit div/mod instructions directly for optimal performance; (2) on older CPUs without DIV32, sign-extend the destination register in place and the source register into a temporary register via 'addw' before executing the native 32-bit div/mod instructions. Note that the JIT compiler must never alter the state of the src register because it remains read-only for the duration of the instruction. For JMP32 conditional branches, the source operands may originate from 64-bit contexts where the upper 32 bits contain arbitrary data, so use 6 independent case structures to prevent 64-bit comparison inversions. Furthermore, use 'bstrpickd' to mask out upper bits for unsigned JMP32, and 'addw' with GPR_ZERO to re-align sign bits for signed JMP32. With this patch, the emit_{zext, sext}_32() and is_signed_bpf_cond() helpers are completely wiped out from the header and source files, delivering a native execution stream with a reduced JIT image size, especially for division and mod operations. All of the testcases of test_bpf passed on Loongson-3A6000 (with DIV32) and Loongson-3A5000 (without DIV32), here are the test results: $ sudo modprobe test_bpf $ dmesg -t | grep Summary test_bpf: Summary: 1061 PASSED, 0 FAILED, [1049/1049 JIT'ed] test_bpf: test_tail_calls: Summary: 10 PASSED, 0 FAILED, [10/10 JIT'ed] test_bpf: test_skb_segment: Summary: 2 PASSED, 0 FAILED For the BPF selftests test_verifier and test_progs, there are no any regressions. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
5 daysLoongArch: BPF: Clean up and decouple is32 parameter from move_imm()Tiezhu Yang2-51/+58
The current move_imm() relies on the 'is32' parameter for both ALU32 and JMP32, forcing the helper to internally clear the upper 32 bits. However this parameter is redundant for all 64-bit immediate loads. Furthermore, it is even undesirable for load/store signed address offset computations. Clean up move_imm() by removing the 'is32' parameter which allows it to focus on loading values, while moving the zero-extension logic outward to the explicit callers. For 64-bit and load-store operations, just drop the parameter. This is preparation for later patch, no functional changes. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
5 daysLoongArch: BPF: Fix stack arguments for indirect trampolinesKumar Kartikeya Dwivedi1-4/+4
LoongArch passes arguments beyond a0-a7 at the caller stack pointer. The trampoline store_args() helper always reads those arguments at FP + 16, which is correct for a regular fentry trampoline: its prologue leaves FP 16 bytes below the stack pointer at trampoline entry to hold the saved RA/FP frame record of the parent function. A struct_ops indirect trampoline is entered through a function pointer and only saves its own RA and FP before setting FP to the entry stack pointer. Its stack arguments therefore start at FP rather than FP + 16. As a result, every stack-passed struct_ops argument is currently read two slots late. Select the source offset based on whether the trampoline is indirect. This also prepares the stack-passed arena argument path to consume the actual pointer slot. With this patch the BPF selftest "./test_progs -t struct_ops_multi_args" passed on LoongArch. Fixes: c9ebe2016de9 ("LoongArch: BPF: Support up to 12 function arguments for trampoline") Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
13 daysbpf: Set up the arena base only in functions that use itKumar Kartikeya Dwivedi1-2/+4
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
2026-09-29bpf: Skip detached progs in trampoline images that are still in useFlorent Revest (Anthropic)1-20/+40
bpf_tramp_image_put() makes sure a trampoline image is not freed while a task may still be running in it, but nothing similar is done for the progs called by that image. Detach drops the last prog reference right away and the prog is freed after grace periods, on the basis that a task still in the traced function skips the fexit progs once the nop at ip_after_call is patched to a jump. That leaves out a task sleeping in a sleepable prog that runs before the detached one, which no grace period waits for: CPU 0 CPU 1 in image I, sleeping in prog S detach P from I's trampoline -> new image, bpf_tramp_image_put(I) bpf_prog_put(P), last ref grace periods, P freed back from S __bpf_prog_enter(P) call P->bpf_func If S and P are fexit progs the task is already past the patched jump, and fentry only images don't have one. On x86 this is an int3 in poisoned bpf_prog_pack memory: Oops: int3: 0000 [#1] SMP NOPTI CPU: 18 UID: 0 PID: 94573 Comm: x169 Not tainted 6.18.44 #1 PREEMPT(lazy) RIP: 0010:0xffffffffc0601d8d Call Trace: <TASK> ? bpf_trampoline_6442515411+0x1a4/0x21b bpf_lsm_bprm_committed_creds+0x5/0x10 security_bprm_committed_creds+0x5f/0x70 begin_new_exec+0x2d6/0x410 ... We hit this in production when progs attached through trampolines got detached while their hooks were busy, and it was independently found with a fuzzer and KASAN. Have the JITs emit a patchable nop in front of each prog call sequence and record it in the image. When a prog is detached, patch its nop to a jump over the call sequence. Progs that stay attached keep running for the tasks that are in the image, and ip_after_call isn't needed anymore. The task can be in any image that isn't freed yet, not only in the current one. It sleeps in image I1 that calls S, P and Q, then P is detached and the trampoline moves to image I2, then Q is detached and its call is still in I1. So the trampoline keeps a list of its images until they are freed, and detaching a prog patches its nop in all of them. Images hold a reference on the trampoline for that long. On riscv and loongarch a jump of any range takes several instructions, and a task preempted in the middle of them could resume into half of the new sequence. The nop is a single instruction there, patched to a near branch through arch_bpf_trampoline_skip(). With the extra nops, BPF_MAX_TRAMP_LINKS progs no longer fit in a page on x86 and arm64 (and already didn't on powerpc), so lower the limit there like s390 does. Fixes: e21aa341785c ("bpf: Fix fexit trampoline.") Reported-by: Sechang Lim <rhkrqnwk98@gmail.com> Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Florent Revest (Anthropic) <florent.revest@linux.dev> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260926135605.1217928-3-florent.revest@linux.dev Closes: https://lore.kernel.org/bpf/20260815071927.147049-1-zirajs7@gmail.com/
2026-09-04LoongArch: BPF: Fix off-by-one error for insn_is_cast_user()Tiezhu Yang1-1/+1
In the LoongArch BPF JIT code, the branch offset represents the number of instructions. An offset of 1 means the target of the "beq" is the current PC plus 1 instruction (PC + 4 bytes). This matches the exact same path as the sequential non-branch execution, the "or" instruction is always executed for the cast_user JIT arm in build_insn(). If the pointer is not NULL, there is no side effect. But if the pointer is NULL, it is incorrectly combined with the base address and turns into a non-zero address, meaning a zero arena offset no longer casts to NULL. Fix this by changing the branch offset from 1 to 2, which properly skips the "or" instruction and jumps directly to the "move_reg" instruction if the pointer is NULL, ensuring the destination register is safely cleared to 0. Cc: stable@vger.kernel.org Fixes: 4fdb5dd8aeba ("LoongArch: BPF: Implement bpf_addr_space_cast instruction") Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Add arch_bpf_stack_walk() implementationGeorge Guo1-0/+38
Implement arch_bpf_stack_walk() on top of the ORC unwinder within the LoongArch BPF JIT backend to provide generic BPF stack walking capabilities. This function is required by advanced BPF features, including timed may_goto timeout tracing and BPF exceptions. It will be invoked in the BPF core subsystem unwinding paths: bpf_prog_find_from_stack(), bpf_stream_stage_dump_stack(), and bpf_throw(). Co-developed-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: George Guo <guodongtai@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Add timed may_goto implementationGeorge Guo3-2/+60
Implement arch_bpf_timed_may_goto() support and advertise it through bpf_jit_supports_timed_may_goto() so the verifier lowers may_goto into the timed variant: instead of a fixed iteration counter, the loop is bounded by a wall-clock timeout maintained in a per-loop stack slot. arch_bpf_timed_may_goto() uses a custom calling convention: the verifier passes the count/timestamp stack offset in BPF_REG_AX and expects the updated count back in the same register. The JIT call path therefore can skip the usual 'BPF_REG_0 = C return value' move for this helper. Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: George Guo <guodongtai@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Resolve per-CPU addrs for internal-only MOVGeorge Guo1-0/+14
Add support for the internal-only BPF_MOV instruction that resolves the absolute addresses of the per-CPU data from their per-CPU offsets. This instruction is used only for internal inlining optimizations between the BPF verifier and the JITs (e.g. inlining bpf_get_smp_processor_id() and per-CPU map lookups). LoongArch keeps the per-CPU offset of the current CPU in $r21 register (a.k.a. __my_cpu_offset), so resolving a per-CPU address only requires adding $r21 to the source register holding the per-CPU offset. Advertise the capability via bpf_jit_supports_percpu_insn(). Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: George Guo <guodongtai@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Advertise JIT support for kptr xchg inlineChenguang Zhao1-0/+5
The BPF verifier can lower bpf_kptr_xchg() to BPF_XCHG when the JIT advertises ptr xchg support. With ordered amswap_db.* emission from the previous patch, declare that LoongArch bpf JIT supports this inlining. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Align value-returning atomics with LKMMChenguang Zhao1-14/+18
Per the Linux Kernel Memory Model, value-returning atomic RMW operations must provide sequentially consistent ordering (a full memory barrier). On LoongArch, plain AMO instructions and bare ll/sc loops do not satisfy this requirement by themselves. Update emit_atomic_rmw() to emit barrier-carrying instructions for all value-returning BPF atomics: - BPF_FETCH (ADD/AND/OR/XOR): use am*_db.{b,h,w,d} - BPF_XCHG: use amswap_db.{b,h,w,d} - BPF_CMPXCHG: emit dbar 0x700 after the ll/sc loop, matching __WEAK_LLSC_MB in cmpxchg.h Add the corresponding instruction encodings and emit helpers to inst.h. Non-value-returning RMW ops (plain BPF_ADD, BPF_AND, etc.) are left as weakly ordered, consistent with LKMM. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Chenguang Zhao <zhaochenguang@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Split unconditional branch JA paths staticallyTiezhu Yang1-4/+5
In build_insn(), both 32-bit and 64-bit unconditional branch JA paths currently share a single case block. It relies on a runtime condition check to multiplex between the 'off' and 'imm' fields. Since the instruction classes are already resolved at compile-time via distinct switch-case labels, this runtime check is redundant. Split the two paths into individual case blocks to remove the redundant runtime check. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Remove dead move_imm() call in BPF_NEG pathTiezhu Yang1-1/+0
The BPF_NEG operation is a unary operator that performs `dst = -dst`. The current code unconditionally executes a move_imm() call before the subtraction, generating useless JITted instructions to load data into the temporary register `t1`. This `t1` register is never used anywhere else in the entire BPF_NEG path. Remove this dead `move_imm()` call to avoid useless instructions. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Remove redundant zext jumping in move_imm()Tiezhu Yang1-1/+1
In move_imm(), when an immediate hits the 12-bit unsigned range, an `ori rd, $zero, imm` instruction is emitted. According to the manual, the `ori` instruction inherently performs a logical or with zero-extended immediate operands against $zero, so the upper 32 bits of the destination register `rd` are already 0. However, the existing JIT code unconditionally executes `goto zext;` after `ori`, forcing it to fallthrough into `emit_zext_32()` to clear the upper 32 bits for 32-bit ALU operations. Fix this redundancy by directly returning from the function inside the `is_unsigned_imm12()` block. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Implement branchless conditional move for TCCTiezhu Yang1-34/+13
The current implementation handles combined bpf2bpf and tail calls by checking at runtime whether REG_TCC holds a scalar count or a pointer address via a conditional jump. This adds branch prediction overhead in the hot path of tail call execution. To implement branchless conditional move, use an unsigned comparison (sltui) combined with mask instructions (maskeqz/masknez) to achieve branchless classification and blending of incoming scalar counts and kernel pointers in REG_TCC. This optimization refactors the inner logic of the helper function, unifies the offset decrement at the function entry, and removes all runtime branching from the prologue hot path completely. Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Refactor jump offset calculation in tail callTiezhu Yang1-8/+4
The old macro-based jmp_offset calculation derives the jump distance from a stale prior-pass code stride, which can lead to wrong branch offsets and soft lockups under extra JIT passes. Fix this by calculating the offset directly on the absolute target: "ctx->offset[insn + 1] - ctx->idx". To avoid a false 16-bit range check abort during size estimation, add a "ctx->image == NULL" guard to inject a safe dummy offset. Cc: stable@vger.kernel.org Fixes: cd39d9e6b7e4 ("LoongArch: BPF: Fix jump offset calculation in tailcall") Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Move arena register slot below TCC contextTiezhu Yang1-7/+13
Currently, the stack layout places the optional arena register slot above the tail call counter context. When arena_vm_start is dynamically enabled, it shifts the relative offset of the tcc_ptr slot within the stack frame, causing hardcoded tracking macros to mismatch and leading to memory misalignment or corruption potentially. To fix this, move the arena register save and restore sequences below the tail call counter context slots in both build_prologue() and the epilogue. Update __build_epilogue() to insert a proper offset decrement to safely skip the unneeded tcc_ptr reading block while accurately aligning with the relocated arena slot at the very bottom. With this patch, the tcc_ptr slot is always positioned at a fixed distance directly underneath the base callee-saved registers that is independent of whether the arena features are on. Cc: stable@vger.kernel.org Fixes: ef54c517a937 ("LoongArch: BPF: Implement PROBE_MEM32 pseudo instructions") Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-08-17LoongArch: BPF: Optimize redundant TCC loads in epilogueTiezhu Yang1-8/+2
The legacy epilogue implementation pops the tail call counter (TCC) context via a redundant double-load pattern. It first decrements the load_offset by 2 slots to fetch 'tcc_ptr', and then immediately bumps it back up by 1 slot to load the original 'tcc' value into REG_TCC, unnecessarily overwriting the register. Optimize this sequence by adjusting the load_offset by only 1 slot. This aligns the offset directly with the higher stack slot containing the entry TCC counter (or caller state), allowing us to restore the REG_TCC register safely with a single load. This removes one redundant instruction from the epilogue hot path, improves code readability, and ensures the correct TCC register context is handed back cleanly upon normal return. Cc: stable@vger.kernel.org Fixes: c0fcc955ff82 ("LoongArch: BPF: Fix the tailcall hierarchy") Fixes: ef54c517a937 ("LoongArch: BPF: Implement PROBE_MEM32 pseudo instructions") Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-24LoongArch: BPF: Fix memory leak in bpf_jit_free()Pu Lehui1-0/+1
When bpf_int_jit_compile() is called for subprograms, it returns early during the first pass (!prog->is_func || extra_pass is false), keeping ctx->offset alive for the subsequent extra pass. If JIT compilation fails for a later subprogram, the BPF core aborts and calls bpf_jit_free() to clean up the first subprogram. However, bpf_jit_free() fails to free jit_data->ctx.offset, which causes a memory leak of the JIT context offsets array. So fix this by adding the missing kvfree(jit_data->ctx.offset) in bpf_jit_free(). Reported-by: Sashiko <sashiko-bot@kernel.org> Fixes: 4ab17e762b34 ("LoongArch: BPF: Use BPF prog pack allocator") Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Pu Lehui <pulehui@huawei.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-23LoongArch: BPF: Zero-extend signed ALU32 div/mod resultsNicholas Dudar1-4/+4
ALU32 operations write a 32-bit result and leave the upper 32 bits of the BPF register zero. The LoongArch JIT sign-extends the result of signed ALU32 BPF_DIV and BPF_MOD (off=1), so a negative 32-bit quotient or remainder leaves bits 63:32 set in JITted code while the verifier and interpreter model those bits as zero. Keep sign-extension on the operands, which signed divide needs, and zero-extend the ALU32 result after the divide or modulo instruction, matching the unsigned ALU32 div/mod paths and every other ALU32 operation in this JIT. Fixes: 2425c9e002d2 ("LoongArch: BPF: Support signed div instructions") Fixes: 7b6b13d32965 ("LoongArch: BPF: Support signed mod instructions") Assisted-by: Claude:claude-opus-4-8 Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn> Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-07-02Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpfLinus Torvalds1-2/+3
Pull BPF fixes from Daniel Borkmann: - Initialize task local storage before fork bails out to free the task (Jann Horn) - Fix insn_aux_data leak on verifier error path (KaFai Wan) - Reject BPF inode storage map creation when BPF LSM is uninitialized (Matt Bobrowski) - Mask pseudo pointer values in verifier logs when pointer leaks are not allowed (Nuoqi Gui) - Harden BPF JIT against spraying via IBPB flush (Pawan Gupta) - Reject a skb-modifying SK_SKB stream parser since the latter is only meant to measure the next message (Sechang Lim) - Fix bpf_refcount_acquire to reject refcounted allocation arguments with a non-zero fixed offset (Yiyang Chen) * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: bpf: Prefer dirty packs for eBPF allocations bpf: Prefer packs that won't trigger an IBPB flush on allocation bpf: Skip redundant IBPB in pack allocator bpf: Restrict JIT predictor flush to cBPF x86/bugs: Enable IBPB flush on BPF JIT allocation bpf: Support for hardening against JIT spraying bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized bpf,fork: wipe ->bpf_storage before bailouts that access it bpf: Fix insn_aux_data leak on verifier err_free_env path selftests/bpf: Cover pseudo-BTF ksym log masking bpf: Mask pseudo pointer values in verifier logs selftests/bpf: Cover refcount acquire node offsets bpf: Reject offset refcount acquire arguments selftests/bpf: test rejection of a packet-modifying SK_SKB stream parser bpf, sockmap: reject a packet-modifying SK_SKB stream parser selftests/bpf: don't modify the skb in the strparser parser prog
2026-07-01bpf: Restrict JIT predictor flush to cBPFPawan Gupta1-2/+3
Currently predictor flush on memory reuse is done for all BPF JIT allocations, but only cBPF programs can be loaded by an unprivileged user. eBPF is privileged by default, and flushing predictors for all CPUs on every eBPF reuse penalizes the common case for no security benefit. eBPF allocations can be frequent on busy systems, only flush predictors for cBPF programs. Trampoline and dispatcher allocations also skip the flush as they are eBPF-only. Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2026-06-25LoongArch: BPF: Inline bpf_get_smp_processor_id() helperTiezhu Yang1-0/+8
The pointer to thread_info is always available in the $tp register, so the call to bpf_get_smp_processor_id() can be inlined into a single load instruction. (1) Here is the sample test.c: #include <linux/bpf.h> #include <bpf/bpf_helpers.h> SEC("raw_tp/sys_enter") int test_cpuid(void *ctx) { return bpf_get_smp_processor_id(); } char _license[] SEC("license") = "GPL"; (2) Here are the test steps: sudo yum install libbpf-devel kernel-devel bpftool clang -target bpf -O2 -c test.c -o test.o sudo sysctl -w net.core.bpf_jit_enable=1 sudo bpftool prog show name test_cpuid sudo rm -f /sys/fs/bpf/test_cpuid sudo bpftool prog load test.o /sys/fs/bpf/test_cpuid ID=$(sudo bpftool prog show pinned /sys/fs/bpf/test_cpuid | grep -oE '^[0-9]+') sudo bpftool prog dump jited id $ID (3) Here are the test results: Before: 6 instructions ... 64: lu12i.w $t1, 1213 68: ori $t1, $t1, 1680 6c: lu32i.d $t1, 0 70: lu52i.d $t1, $t1, -1792 74: jirl $ra, $t1, 0 78: move $a5, $a0 ... After: 1 instruction ... 64: ld.wu $a5, $tp, 16 ... This is similar with commit 2ddec2c80b44 ("riscv, bpf: inline bpf_get_smp_processor_id()"). Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25LoongArch: BPF: Inline bpf_get_current_task/_btf() helpersTiezhu Yang1-0/+18
The pointer to task_struct is always available in the $tp register, so the calls to bpf_get_current_task() and bpf_get_current_task_btf() can be inlined into a single move instruction. (1) Here is the sample test.c: #include <linux/bpf.h> #include <bpf/bpf_helpers.h> SEC("raw_tp/sys_enter") long test_task(void *ctx) { return (long)bpf_get_current_task(); } char _license[] SEC("license") = "GPL"; (2) Here are the test steps: sudo yum install libbpf-devel kernel-devel bpftool clang -target bpf -O2 -c test.c -o test.o sudo sysctl -w net.core.bpf_jit_enable=1 sudo bpftool prog show name test_task sudo rm -f /sys/fs/bpf/test_task sudo bpftool prog load test.o /sys/fs/bpf/test_task ID=$(sudo bpftool prog show pinned /sys/fs/bpf/test_task | grep -oE '^[0-9]+') sudo bpftool prog dump jited id $ID (3) Here are the test results: Before: 6 instructions ... 64: lu12i.w $t1, 1093 68: ori $t1, $t1, 3320 6c: lu32i.d $t1, 0 70: lu52i.d $t1, $t1, -1792 74: jirl $ra, $t1, 0 78: move $a5, $a0 ... After: 1 instruction ... 64: move $a5, $tp ... This is similar with commit 2bb138cb20a6 ("bpf, arm64: Inline bpf_get_current_task/_btf() helpers"). Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25LoongArch: BPF: Fix off-by-one error in tail callTiezhu Yang1-3/+5
The current code updates the tail call counter (TCC) using a pre-increment approach, it stores the incremented value back to memory before performing any boundary or target validation checks. This causes two major issues: 1. When a tail call fails because the target program is NULL, the TCC is incorrectly incremented and saved in memory anyway. 2. This dummy increment implicitly consumes one slot of the allowed tail call budget. As a result, the subsequent loop reaches the maximum limit prematurely, leading to a test failure where the actual loop count is 32 instead of the expected 33. Fix this by deferring the counter update. Change the branch condition to BPF_JSGE (greater or equal) so that we check the boundary first. The TCC is only incremented and stored back to memory after the boundary check and the NULL-target check both pass. Before: $ sudo ./test_progs -t tailcalls/tailcall_3 ... test_tailcall_count:FAIL:tailcall count unexpected tailcall count: actual 32 != expected 33 ... #465/3 tailcalls/tailcall_3:FAIL #465 tailcalls:FAIL After: $ sudo ./test_progs -t tailcalls/tailcall_3 #465/3 tailcalls/tailcall_3:OK #465 tailcalls:OK Summary: 1/1 PASSED, 0 SKIPPED, 0 FAILED Fixes: c0fcc955ff82 ("LoongArch: BPF: Fix the tailcall hierarchy") Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-25LoongArch: BPF: Fix outdated tail call commentsTiezhu Yang1-4/+16
The current LoongArch BPF JIT implementation hardcodes the number of prologue instructions skipped during a tail call as a magic number '7' in the jirl instruction. However, the accompanying comment explaining this offset is completely outdated. It inaccurately states that only a single TCC initialization instruction is bypassed, but in reality, multiple setup slots are skipped, so fix these outdated comments in __build_epilogue(). While at it, refine the comments in build_prologue() to describe the skipped setup slots (RA saving, fentry nops, and the TCC register slot) using proper dynamic tracing context. Also, remove the magic number '7' by introducing descriptive macros to formally define the prologue layout and make the tail call jump offset self-documenting. Fixes: 61319d15a560 ("LoongArch: BPF: Adjust the jump offset of tail calls") Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-06-07bpf: Add struct bpf_tramp_node objectJiri Olsa1-26/+26
Adding struct bpf_tramp_node to decouple the link out of the trampoline attachment info. At the moment the object for attaching bpf program to the trampoline is 'struct bpf_tramp_link': struct bpf_tramp_link { struct bpf_link link; struct hlist_node tramp_hlist; u64 cookie; } The link holds the bpf_prog pointer and forces one link - one program binding logic. In following changes we want to attach program to multiple trampolines but we want to keep just one bpf_link object. Splitting struct bpf_tramp_link into: struct bpf_tramp_link { struct bpf_link link; struct bpf_tramp_node node; }; struct bpf_tramp_node { struct bpf_link *link; struct hlist_node tramp_hlist; u64 cookie; }; The 'struct bpf_tramp_link' defines standard single trampoline link and 'struct bpf_tramp_node' is the attachment trampoline object with pointer to the bpf_link object. This will allow us to define link for multiple trampolines, like: struct bpf_tracing_multi_link { struct bpf_link link; ... int nodes_cnt; struct bpf_tracing_multi_node nodes[] __counted_by(nodes_cnt); }; Cc: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20260606123955.345967-9-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-04-24Merge tag 'loongarch-7.1' of ↵Linus Torvalds1-65/+316
git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson Pull LoongArch updates from Huacai Chen: - Adjust build infrastructure for 32BIT/64BIT - Add HIGHMEM (PKMAP and FIX_KMAP) support - Show and handle CPU vulnerabilites correctly - Batch the icache maintenance for jump_label - Add more atomic instructions support for BPF JIT - Add more features (e.g. fsession) support for BPF trampoline - Some bug fixes and other small changes * tag 'loongarch-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson: (21 commits) selftests/bpf: Enable CAN_USE_LOAD_ACQ_STORE_REL for LoongArch LoongArch: BPF: Add fsession support for trampolines LoongArch: BPF: Introduce emit_store_stack_imm64() helper LoongArch: BPF: Support up to 12 function arguments for trampoline LoongArch: BPF: Support small struct arguments for trampoline LoongArch: BPF: Open code and remove invoke_bpf_mod_ret() LoongArch: BPF: Support load-acquire and store-release instructions LoongArch: BPF: Support 8 and 16 bit read-modify-write instructions LoongArch: BPF: Add the default case in emit_atomic() and rename it LoongArch: Define instruction formats for AM{SWAP/ADD}.{B/H} and DBAR LoongArch: Batch the icache maintenance for jump_label LoongArch: Add flush_icache_all()/local_flush_icache_all() LoongArch: Add spectre boundry for syscall dispatch table LoongArch: Show CPU vulnerabilites correctly LoongArch: Make arch_irq_work_has_interrupt() true only if IPI HW exist LoongArch: Use get_random_canary() for stack canary init LoongArch: Improve the logging of disabling KASLR LoongArch: Align FPU register state to 32 bytes LoongArch: Handle CONFIG_32BIT in syscall_get_arch() LoongArch: Add HIGHMEM (PKMAP and FIX_KMAP) support ...
2026-04-23LoongArch: BPF: Add fsession support for trampolinesHengqi Chen1-10/+66
Implement BPF_TRACE_FSESSION support in LoongArch BPF JIT. The logic here is almost identical to what has been done in RISC-V JIT. The key changes are: - Allocate stack space for function meta and session cookies - Introduce invoke_bpf() as a wrapper around invoke_bpf_prog() that populates session cookies before each invocation - Implement bpf_jit_supports_fsession() callback Tested-by: Vincent Li <vincent.mc.li@gmail.com> Reviewed-by: Menglong Dong <menglong8.dong@gmail.com> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-23LoongArch: BPF: Introduce emit_store_stack_imm64() helperHengqi Chen1-11/+13
Introduce a helper to store 64-bit immediate on the trampoline stack. The helper will be used in the next patch. Also refactor the existing code to use this helper. Tested-by: Vincent Li <vincent.mc.li@gmail.com> Reviewed-by: Menglong Dong <menglong8.dong@gmail.com> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-22LoongArch: BPF: Support up to 12 function arguments for trampolineTiezhu Yang1-35/+64
Currently, LoongArch bpf trampoline supports up to 8 function arguments. According to the statistics from commit 473e3150e30a ("bpf, x86: allow function arguments up to 12 for TRACING"), there are over 200 functions accept 9 to 12 arguments, so add 12 arguments support for trampoline. With this patch, the following related testcases passed: sudo ./test_progs -a tracing_struct/struct_many_args sudo ./test_progs -a fentry_test/fentry_many_args sudo ./test_progs -a fexit_test/fexit_many_args Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Tested-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-22LoongArch: BPF: Support small struct arguments for trampolineTiezhu Yang1-24/+31
In the current BPF code, the struct argument size is at most 16 bytes, enforced by the verifier. According to the Procedure Call Standard for LoongArch, the struct argument size below 16 bytes are provided as part of the 8 argument registers, that is to say, the struct argument may be passed in a pair of registers if its size is more than 8 bytes and no more than 16 bytes. Extend the BPF trampoline JIT to support attachment to functions that take small structures (up to 16 bytes) as argument, save and restore a number of "argument registers" rather than a number of arguments. With this patch, the following related testcases passed: sudo ./test_progs -a tracing_struct/struct_args sudo ./test_progs -a tracing_struct/union_args Link: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc#structures Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Tested-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-22LoongArch: BPF: Open code and remove invoke_bpf_mod_ret()Tiezhu Yang1-15/+10
invoke_bpf_mod_ret() is a small wrapper over invoke_bpf_prog(), it should check the return value of invoke_bpf_prog() and then return immediately if invoke_bpf_prog() failed, just open code and remove it due to it is called only once. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Tested-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-22LoongArch: BPF: Support load-acquire and store-release instructionsTiezhu Yang1-1/+97
Use the LoongArch common memory access instructions with the barrier 'dbar' to support the BPF load-acquire and store-release instructions. With this patch, the following testcases passed on LoongArch if the macro CAN_USE_LOAD_ACQ_STORE_REL is usable in bpf selftests: sudo ./test_progs -t verifier_load_acquire sudo ./test_progs -t verifier_store_release sudo ./test_progs -t verifier_precision/bpf_load_acquire sudo ./test_progs -t verifier_precision/bpf_store_release sudo ./test_progs -t compute_live_registers/atomic_load_acq_store_rel Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-22LoongArch: BPF: Support 8 and 16 bit read-modify-write instructionsTiezhu Yang1-9/+68
The 8 and 16 bit read-modify-write instructions {amadd/amswap}.{b/h} were newly added in the latest LoongArch Reference Manual, use them to avoid the error of unknown opcode if possible. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-22LoongArch: BPF: Add the default case in emit_atomic() and rename itTiezhu Yang1-2/+9
Like the other archs such as x86 and riscv, add the default case in emit_atomic() to print an error message for the invalid opcode and return -EINVAL, then make its return type as int. While at it, given that all of the instructions in emit_atomic() are only read-modify-write instructions, rename emit_atomic() to emit_atomic_rmw() to make it clear, because there will be a new function emit_atomic_ld_st() for load-acquire and store-release instructions in the later patch. Acked-by: Hengqi Chen <hengqi.chen@gmail.com> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
2026-04-16bpf: Pass bpf_verifier_env to JITXu Kuohai1-1/+1
Pass bpf_verifier_env to bpf_int_jit_compile(). The follow-up patch will use env->insn_aux_data in the JIT stage to detect indirect jump targets. Since bpf_prog_select_runtime() can be called by cbpf and lib/test_bpf.c code without verifier, introduce helper __bpf_prog_select_runtime() to accept the env parameter. Remove the call to bpf_prog_select_runtime() in bpf_prog_load(), and switch to call __bpf_prog_select_runtime() in the verifier, with env variable passed. The original bpf_prog_select_runtime() is preserved for cbpf and lib/test_bpf.c, where env is NULL. Now all constants blinding calls are moved into the verifier, except the cbpf and lib/test_bpf.c cases. The instructions arrays are adjusted by bpf_patch_insn_data() function for normal cases, so there is no need to call adjust_insn_arrays() in bpf_jit_blind_constants(). Remove it. Reviewed-by: Anton Protopopov <a.s.protopopov@gmail.com> # v8 Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com> # v12 Acked-by: Hengqi Chen <hengqi.chen@gmail.com> # v14 Signed-off-by: Xu Kuohai <xukuohai@huawei.com> Link: https://lore.kernel.org/r/20260416064341.151802-3-xukuohai@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-04-16bpf: Move constants blinding out of arch-specific JITsXu Kuohai1-42/+17
During the JIT stage, constants blinding rewrites instructions but only rewrites the private instruction copy of the JITed subprog, leaving the global env->prog->insnsi and env->insn_aux_data untouched. This causes a mismatch between subprog instructions and the global state, making it difficult to use the global data in the JIT. To avoid this mismatch, and given that all arch-specific JITs already support constants blinding, move it to the generic verifier code, and switch to rewrite the global env->prog->insnsi with the global states adjusted, as other rewrites in the verifier do. This removes the constants blinding calls in each JIT, which are largely duplicated code across architectures. Since constants blinding is only required for JIT, and there are two JIT entry functions, jit_subprogs() for BPF programs with multiple subprogs and bpf_prog_select_runtime() for programs with no subprogs, move the constants blinding invocation into these two functions. In the verifier path, bpf_patch_insn_data() is used to keep global verifier auxiliary data in sync with patched instructions. A key question is whether this global auxiliary data should be restored on the failure path. Besides instructions, bpf_patch_insn_data() adjusts: - prog->aux->poke_tab - env->insn_array_maps - env->subprog_info - env->insn_aux_data For prog->aux->poke_tab, it is only used by JIT or only meaningful after JIT succeeds, so it does not need to be restored on the failure path. For env->insn_array_maps, when JIT fails, programs using insn arrays are rejected by bpf_insn_array_ready() due to missing JIT addresses. Hence, env->insn_array_maps is only meaningful for JIT and does not need to be restored. For subprog_inf