summaryrefslogtreecommitdiff
path: root/arch/x86/net
AgeCommit message (Collapse)Author
3 daysbpf: Keep stack arguments in arch_bpf_timed_may_goto()Alexei Starovoitov
The JITs pass the first stack arguments of a call in registers: x86-64 r9 argument 6 arm64 x5-x7 arguments 6-8 riscv64 a5-a7 arguments 6-8 '*(u64 *)(r11 - 8) = rX' writes such a register in the caller. 'rX = *(u64 *)(r11 + 8)' reads it in the callee. A call changes these registers. Thus the verifier accepts no call between the write and the call of the callee, and no call in the callee before the read. may_goto is not a call for the verifier. But one time in 65535 iterations it calls arch_bpf_timed_may_goto(), and this function calls C code. It saves R0-R5 only. *(u64 *)(r11 - 8) = 0 ; the verifier: argument 6 is 0 call sub sub: 1: may_goto 2f ; C code changes r9 goto 1b 2: r2 = *(u64 *)(r11 + 8) ; r2 is a kernel address r1 = map_value r1 += r2 *(u64 *)(r1 + 0) = 0 On x86-64 the C code changes r9 when the time of may_goto is up. With the hpet clocksource a look at the clock changes r9 too. The prog above crashes the kernel. LLVM does not emit such code: it reads stack arguments at the entry of a function, and it writes them immediately before the call. Save and restore these registers too. The cost is 2 insns on x86-64, 4 on arm64 and 6 on riscv64, one time in 65535 iterations. Fixes: 324c3ca6eed6 ("bpf,x86: Implement JIT support for stack arguments") Fixes: 235b2fe772f5 ("bpf, arm64: Add JIT support for stack arguments") Fixes: ba754185f902 ("riscv, bpf: Add BPF stack arguments support for RV64 JIT") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261027190314.1440199-19-alexei.starovoitov@gmail.com
3 daysbpf, x86: Remove r0_on_stack from fetching atomics in arenaAlexei Starovoitov
x86 has no fetching AND/OR/XOR. Thus the JIT emits a loop with cmpxchg. cmpxchg uses RAX, and RAX holds BPF R0. Thus the JIT saves R0 before the loop. prog the address is in the JIT saves R0 in -------------------------- ------------------ ------------------- without the flag a BPF register BPF_REG_AX with BPF_F_ARENA_SCALAR BPF_REG_AX the stack The flag is removed. Remove the second variant. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261027190314.1440199-7-alexei.starovoitov@gmail.com
3 daysbpf: Remove BPF_F_ARENA_SCALARAlexei Starovoitov
Rust has no address spaces. Thus a prog in Rust accesses arena through scalars. With BPF_F_ARENA_SCALAR the verifier accepts each load and each store through a scalar as an access to arena. The verifier rewrites one insn at a time. Thus it must add one insn to each access. The compiler knows the source of each pointer. It can emit one addr_space_cast for each pointer, as it does for the __arena pointers of C. flag: one move for each access cast: one cast for each pointer ax = (u32)r1 r1 = addr_space_cast(r1, 0, 1) r2 = *(u64 *)(ax + 0) r2 = *(u64 *)(r1 + 0) ax = (u32)r1 r3 = *(u64 *)(r1 + 8) r3 = *(u64 *)(ax + 8) 20 progs of rust-bpf, with the flag and with the casts that a prototype of an LLVM pass emits: flag casts moves or casts 1568 571 insns 14864 13938 jited bytes 72351 69111 No released kernel has the flag. LLVM does not emit the casts for Rust at this time. Until it does, Rust progs that access arena do not load. scx_mavd and scx_nitosis set the flag too. They are experimental schedulers in C in sched-ext/scx, and they use the flag to omit __arena. They must use __arena again. This reverts commit 4c651a91bdfc ("bpf: Treat load and store through a number as arena access"). One part stays: BPF_REG_AX in reg2pt_regs[] of the x86 JIT. The fetching AND/OR/XOR atomics in arena use it now. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261027190314.1440199-6-alexei.starovoitov@gmail.com
7 daysbpf: Size backward jumps by the insns they jump overMykyta Yatsenko
A backward jump is sized from its target's current-pass address and its own previous-pass address, so it can grow while other jumps shrink. Two passes may then give the same image length with jumps still changing, which ends in "bpf_jit: fatal error", and a jump growing in a padding pass ends in "unexpected jmp_cond padding". Shift the jump's previous-pass address by how far the current pass has moved it, so a backward jump is sized by the insns it jumps over, like a forward one. Also start every insn at BPF_MAX_INSN_SIZE instead of 64, so none can grow in the first pass. Then no insn grows from one pass to the next, and a repeated image length means nothing moved. The 123 limit on imm8 offsets worked around that growth and is dropped. The ja -1 special case is subsumed, such a jump is now imm8 from the first pass. Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://patch.msgid.link/20261022-jit_size_fix-v2-1-4bee6921b218@meta.com
7 daysbpf, x86: Use emit_rsb_call() to call bpf_unwind_target()Alexei Starovoitov
clang inlines emit_unwind_ret_addr() and emit_patch() into do_jit() and folds 'bpf_unwind_target - X86_PATCH_SIZE' into one relocation. It points to a nop in the padding in front of the function, and objtool complains: vmlinux.o: warning: objtool: do_jit+0x1330: relocation to !ENDBR: .text+0xc7fab It's only used to compute rel32 of a direct call, so nothing is wrong at run time. emit_rsb_call() does call depth accounting too and hides func from the optimizer. Use it instead of open coding. Fixes: cff94a3d78d8 ("bpf, x86: Support unwind_goto and unwind_exit") Reported-by: Nathan Chancellor <nathan@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Tested-by: Nathan Chancellor <nathan@kernel.org> # build Link: https://patch.msgid.link/20261021220844.239400-1-alexei.starovoitov@gmail.com Closes: https://lore.kernel.org/bpf/20261021201456.GA3197963@ax162/
10 daysbpf: Make unwind_exit of an exception callback exit in JITsAlexei Starovoitov
For the verifier unwind_exit of an exception callback is exit. For JITs the callback is a subprog, so they emit the lookup of the return address. The idea was that the kernel calls the callback and the lookup finds nothing. But an exception callback has no frame of its own. It returns from the frame of the main prog that threw, and the kernel isn't always the caller of that one: - An extension returns to the caller of the subprog that it replaced. - After a tail call in a subprog the main prog returns to the caller of that subprog. When unwind_goto follows that call, the callback goes to the pad, and the pad wasn't verified with it: r6 = 1 call a // can unwind unwind_goto pad r6 = 2 call b // cannot unwind unwind_goto pad // stays, since the pad is not dead code exit pad: r0 = r6 // r6 is 1 for the verifier An extension without unwind_exit can replace b(). When it throws and its exception callback ends with unwind_exit, the pad runs with r6 = 2. Both JITs ask bpf_prog_can_unwind(). Let it say no for an exception callback. An async callback has a frame of its own and the kernel is the caller. Fixes: a2d274771321 ("bpf: Add unwind_goto and unwind_exit insns") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/5f24cbed1ec4a6a0ecd0b834d738c48dc9eb64362be4fa50dfb0eaddfad928b3@mail.kernel.org/ Link: https://patch.msgid.link/20261020231942.2568163-2-alexei.starovoitov@gmail.com Closes: https://lore.kernel.org/bpf/sashiko-outbox-179498@kernel.org/
11 daysbpf, x86: Support unwind_goto and unwind_exitAlexei Starovoitov
bpf x86 call inner call inner unwind_goto pad w0 = w6 mov eax, ebx r0 = 0 xor eax, eax unwind_exit push rax push rsi mov rdi, [rbp + 8] call bpf_unwind_target mov [rbp + 8], rax pop rsi pop rax leave ret unwind_goto is an extable entry and no code. unwind_exit looks its return address up there and returns to the pad. r0 and r2 are what a subprog returns, so rax and rsi are saved around the lookup. When there is no entry, the kernel called the subprog as an async or an exception callback, and unwind_exit is exit. The caller of the main prog doesn't tell exit from unwind_exit, so there it's exit. An extension is different. freplace is a jump, so its return address is the one of the subprog that it replaced. With private stack r9 is saved around a call, and 'pop r9' has to be done on the way to the pad too. In such progs unwind_goto is: push r9 call foo pop r9 <- exit returns here jmp 1f pop r9 <- unwind_exit returns here jmp pad 1: Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261020181320.1284798-3-alexei.starovoitov@gmail.com
12 daysbpf: Set up the arena base only in functions that use itKumar Kartikeya Dwivedi
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
13 daysbpf, x86: Mask the shift counts of the magic number divisionDaniel Borkmann
The kernel test robot reports for a clang 22 randconfig with UBSAN and ThinLTO: vmlinux.o: error: objtool: do_jit(): unexpected end of section .text.do_jit Fix by masking the counts to their range like rol64() does, which keeps the shifts defined for the sanitizer and removes the __ubsan_handle_shift_out_of_bounds() checks. The counts are below 32 and 64 anyway, so the emitted code does not change. Reproduced with clang 20 and the robot's config without LTO. Fixes: 02cfd66f3d9a ("bpf, x86: Divide by constants via multiplication with a magic number") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202610171029.DfoBvNXv-lkp@intel.com/ Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261018113352.730799-1-daniel@iogearbox.net
2026-10-16bpf, x86: Place trampoline arguments by the x86-64 calling conventionYonghong Song
save_args() numbers the on-stack argument slots consecutively, and the area built for the original function is sized the same way, while the x86-64 ABI rounds the stack slot up to an even one for an argument aligned to 16 bytes: an __int128, or an aggregate holding one. When such an argument lands on an odd stack slot, it and every argument after it are read from the wrong place, so a bpf program attached to the function reads a neighbouring eightbyte, and the arguments handed on to the original function are shifted. For example: /* s holds an __int128 */ void foo(u64 a, u64 b, u64 c, u64 d, u64 e, u64 f, u64 g, struct s h, u64 i) x86-64 puts g in the first stack slot, leaves the second empty and puts h in the third and fourth, while the trampoline reads h from the second and third. Take the position of each argument slot from bpf_jit_place_args(), which knows the x86-64 rules, backfill included. save_args() then reads each slot from its register or incoming stack slot, restore_regs() puts back only the register slots, and the area built for the original function mirrors the incoming one, holes included. A trampoline on a BPF function is not changed by this: since the previous patch, the function's model has one u64 per argument slot, which bpf_jit_place_args() places in slot order, so the trampoline still takes the arguments where BPF code put them. Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261016183105.1134967-1-yonghong.song@linux.dev
2026-10-16bpf, x86: Pass a trampoline's stack arguments by the calling conventionYonghong Song
A trampoline on a function of a program that can tail call keeps the tail call counter pointer by pushing rax after allocating its frame. When it calls the original function, for fexit, fmod_ret or fsession, the push sits between the stack arguments and the return address, which the x86-64 calling convention does not allow. For example, in run() -> call_stack() -> callee_stack(a, b, c, d, e, f, g, h) run() -> subprog_tail() -> bpf_tail_call() callee_stack() is not on the path to the tail call, so the verifier allows its stack arguments g and h. fexit on it builds, with T the trampoline's rbp: T-120 h save_args() T-128 g save_args(), RSP after sub rsp, 128 T-136 tail_call_cnt_ptr push rax, RSP at the call T-144 return address call orig_call and callee_stack() finds the counter pointer where g belongs, at 8(%rsp) on entry, and g where h belongs. Keep the pointer in a slot of the frame instead, so that the stack arguments sit right above the return address again: T-120 tail_call_cnt_ptr mov [rbp - 120], rax T-128 (pad to 16) T-136 h save_args() T-144 g save_args(), RSP at the call T-152 return address call orig_call Fixes: 324c3ca6eed6 ("bpf,x86: Implement JIT support for stack arguments") Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261016183044.1132751-1-yonghong.song@linux.dev
2026-10-16bpf, x86: Support fetching AND/OR/XOR atomics in arenaPuranjay Mohan
x86-64 has no single instruction for a fetching AND/OR/XOR, so the JIT lowers them to a CMPXCHG loop. That loop could not be used against arena memory: it contains two memory accesses, the load of the old value and the CMPXCHG itself, either of which can fault when the arena page goes away, while the verifier reserves only one exception table entry per instruction. bpf_jit_supports_insn() therefore rejected the three opcodes and such programs failed to load with BPF_ATOMIC stores into R1 arena is not allowed Emit the same loop with R12-indexed addressing and give each of the two accesses its own exception table entry. The verifier still reserves one per instruction, so the JIT accounts for the extra entry itself by rescanning the instruction stream in bpf_int_jit_compile() before the extable is sized, as s390 does in bpf_jit_alloc() for its BPF_XCHG lowering. The rescan sits after the extra-pass early exit, so a program is counted exactly once. Drop the bpf_jit_supports_insn() rejection. A loop without the load would need only one entry, since a CMPXCHG that loses the comparison reloads RAX, but its first CMPXCHG would then almost always lose. Every operation would pay for a second locked CMPXCHG, which makes the fetching insn more expensive than the load and CMPXCHG loop programs write by hand today. The second entry is paid for once, in the JIT. Both entries resume past the whole loop rather than past the faulting instruction alone, with the fetch destination cleared, so a fault cannot re-enter the loop, and both are reported as writes since the BPF insn is a read-modify-write. This repurposes the INSN_LEN field of the fixup as a resume distance rather than an instruction length; a sequence long enough to overflow its 8 bits would first have to exceed BPF_MAX_INSN_SIZE, which do_jit() rejects before the image is used. The loop needs RAX for CMPXCHG and saves R0 in BPF_REG_AX, which it also substitutes for R0 when either operand is R0. ex_handler_bpf() may then have to name r10 as the register holding the arena address or the one to clear on fault; reg2pt_regs[] already has that entry. An access through a number, made by a program loaded with BPF_F_ARENA_SCALAR, keeps its address in BPF_REG_AX itself (see arena_scalar_access()), which is where the loop would save R0. Save R0 on the stack in that case, as the div and mod lowering does. An R0 operand stays in that stack slot: the new value is built from it, RAX ends up holding the old value that R0 is to return, and the slot is dropped instead of popped. Both entries resume before that pop or drop, so a fault leaves the stack balanced. Signed-off-by: Puranjay Mohan <puranjay@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Tejun Heo <tj@kernel.org> Link: https://patch.msgid.link/20261016171319.1623447-2-puranjay@kernel.org
2026-10-15bpf, x86: Shorten the cast to a user addressDaniel Borkmann
The cast of an arena pointer to its user address zero extended the low half, shifted it up, or'ed the user base in, rotated it back down and replaced the result with zero from a cleared r11 through a cmove for a NULL pointer: seven instructions with a dependency chain of six. Or the user base into r11 instead and pick it with a cmovne when the low half is not zero, five instructions with a chain of three. LLVM emits the cast for every arena pointer handed back to user space. Before, for r1 = addr_space_cast(r7, 1, 0) with a user base of 0x7f1200000000: 44 89 ef movl %r13d,%edi 48 c1 e7 20 shlq $0x20,%rdi 48 81 cf 12 7f 00 00 orq $0x7f12,%rdi 48 c1 c7 20 rolq $0x20,%rdi 4d 31 db xorq %r11,%r11 85 ff testl %edi,%edi 49 0f 44 fb cmoveq %r11,%rdi After: 44 89 ef movl %r13d,%edi 49 bb 00 00 00 00 12 7f 00 00 movabsq $0x7f1200000000,%r11 49 09 fb orq %rdi,%r11 85 ff testl %edi,%edi 49 0f 45 fb cmovneq %r11,%rdi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-17-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Use emit_sub_rsp() for the trampoline stackDaniel Borkmann
The trampoline prologue open codes the choice between the imm8 and the imm32 form of sub rsp which emit_sub_rsp() already makes. Use it. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-16-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Multiply by 3, 5 and 9 with leaDaniel Borkmann
LLVM turns a multiplication by a power of two into a shift, but keeps the other constants as a multiplication since BPF has no lea to lower them into, so r *= 3 and friends reach the JIT as BPF_MUL with BPF_K and were emitted as imul with an immediate, a 3 cycle instruction on Intel and AMD. Emit lea dst, [dst + dst * 2/4/8] for 3, 5 and 9 instead, which is the same size and a single cycle on Intel and on Zen 3 and later, two cycles on older AMD cores. r13 keeps the imul, since it needs a displacement byte as base register, which makes the lea a byte longer and a slow three operand form with 3 cycles of latency on Intel. Before/after for r1 *= 3: 48 6b ff 03 imulq $0x3,%rdi,%rdi 48 8d 3c 7f leaq (%rdi,%rdi,2),%rdi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-15-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Divide by constants via multiplication with a magic numberDaniel Borkmann
LLVM strength-reduces 32-bit divisions by a constant into a 64-bit multiplication, but has no high-half multiply for the 64-bit ones, so these reach the JIT as BPF_DIV/BPF_MOD with BPF_K and were emitted as div or idiv, which take 20-100 cycles on Intel before Ice Lake, about 15 cycles on Ice Lake and later, and 9-19 cycles on AMD Zen 3-5, whereas a mul is 3 to 4 cycles on all current cores. Emit the multiplication with a magic number instead, with the constants computed per Hacker's Delight, 2nd ed., figures 10-1 and 10-2, which is also what compilers do for native code: an unsigned division becomes a mul plus a shift, or plus a sub/shr/add/shr sequence when the magic number needs 65 bits, which an even divisor avoids by shifting the dividend by its trailing zeros first, a signed one an imul, an optional add or sub of the dividend, a sar and the sign bit adjustment. A modulo multiplies the quotient back and subtracts it from the dividend. Divisors 0 and +-1 as well as unsigned divisors above 2^63 (negative imm32) are left to div/idiv as before, and so are the 32-bit divisions. The magic numbers were validated in user space against the bounds from Hacker's Delight for every divisor an imm32 can hold, in both signednesses, and the emitted sequences were executed with dividends around every multiple boundary of the divisor, at the extremes and at random. Before, for r1 /= 1000: 50 pushq %rax 52 pushq %rdx 49 c7 c3 e8 03 00 00 movq $0x3e8,%r11 48 89 f8 movq %rdi,%rax 31 d2 xorl %edx,%edx 49 f7 f3 divq %r11 48 89 c7 movq %rax,%rdi 5a popq %rdx 58 popq %rax After: 50 pushq %rax 52 pushq %rdx 48 89 f8 movq %rdi,%rax 48 c1 e8 03 shrq $0x3,%rax 49 bb cf f7 53 e3 a5 9b c4 20 movabsq $0x20c49ba5e353f7cf,%r11 49 f7 e3 mulq %r11 48 c1 ea 04 shrq $0x4,%rdx 48 89 d7 movq %rdx,%rdi 5a popq %rdx 58 popq %rax Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-14-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Compare the PROBE_MEM address range with a shiftDaniel Borkmann
The PROBE_MEM check rejects src_reg + off - VSYSCALL_ADDR up to a limit of TASK_SIZE_MAX + PAGE_SIZE - VSYSCALL_ADDR, which does not fit into a 32-bit immediate and therefore needed a movabs into r10 and a register compare. Compare against the next power of two above the limit instead, which is a shift by fls64(limit) followed by a jne on the result. The addresses between the limit and that power of two are non-canonical on every x86-64 layout, since user space ends at TASK_SIZE_MAX and the kernel half starts far above 2^57, so they faulted and had the register zeroed by the exception handler before. Now they are zeroed by the check without taking the fault. The compare and branch stay two uops on Intel and AMD, while the sequence shrinks from 15 to 6 bytes. Before, for the compare of a 4-level paging kernel: 49 ba 00 00 a0 00 00 80 00 00 movabsq $0x800000a00000,%r10 4d 39 d3 cmpq %r10,%r11 77 05 ja 0x... After: 49 c1 eb 30 shrq $0x30,%r11 75 05 jne 0x... Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-13-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Fold the PROBE_MEM address computation into a leaDaniel Borkmann
The kernel address check in front of a BPF_PROBE_MEM load computed src_reg + off - VSYSCALL_ADDR with a mov of VSYSCALL_ADDR, a mov of the base register, an add of the offset in imm32 form and a sub, that is 20 bytes and 4 uops. VSYSCALL_ADDR is -10 MiB, so together with the 16-bit instruction offset it fits into a 32-bit displacement and a single lea does the same in 7 bytes and 1 uop on Intel and AMD. Before, for the check on r0 = *(u64 *)(r1 + 16): 49 c7 c2 00 00 60 ff movq $0xffffffffff600000,%r10 49 89 fb movq %rdi,%r11 49 81 c3 10 00 00 00 addq $0x10,%r11 4d 29 d3 subq %r10,%r11 After: 4c 8d 9f 10 00 a0 00 leaq 0xa00010(%rdi),%r11 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-12-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Use BMI2 shifts also when the count is in rcxDaniel Borkmann
Commit 77d8f5d47bfb ("bpf,x64: use shrx/sarx/shlx when available") kept the legacy shift by cl when the count already is in rcx, since that encoding is two bytes shorter. However, shl/shr/sar r,cl are 3 uops on Intel from Haswell through Skylake and still 2 uops on Ice Lake, as a zero count must leave the flags untouched, whereas shlx/shrx/sarx are a single uop with a latency of 1. On AMD both forms are a single uop, so the two extra bytes are the only cost there. Use the BMI2 form whenever it is available. LLVM keeps the count in whichever register it was allocated to, r4 included. Before/after for r1 <<= r4: 48 d3 e7 shlq %cl,%rdi c4 e2 f1 f7 ff shlxq %rcx,%rdi,%rdi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-11-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Swap 16-bit values with bswap and shr, not ror and movzxDaniel Borkmann
The 16-bit byte swap was emitted as a 16-bit rotate followed by a zero extending move. bswap of the 32-bit register followed by a right shift by 16 has the same result, is two bytes shorter, and avoids the operand size prefix and the 16-bit partial register write. Both sequences are two single cycle uops on Intel and AMD. LLVM emits be16 for bpf_htons() and bpf_ntohs() with cpu v3 and bswap16 with cpu v4, both of which take this path. Before, for r1 = be16 r1: 66 c1 cf 08 rorw $0x8,%di 0f b7 ff movzwl %di,%edi After: 0f cf bswap %edi c1 ef 10 shrl $0x10,%edi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-10-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Use shorter and faster forms for some ALU immediatesDaniel Borkmann
An add or sub of 1 or -1 is an inc or dec, which is a byte shorter and a single uop on all current cores, and the flags they leave untouched are not read across BPF instructions anyway. An add of 128 is the sub of -128 and the other way round, which fits into an imm8. An and of a 64-bit register with a non-negative immediate clears the upper half just like the 32-bit and does, which drops the REX.W prefix on the lower eight registers. A shift left by one is the add of the register to itself, the same size and a single uop that runs on more ports. LLVM emits all of them, r += 1 for every counter, r &= mask for the masks beyond the byte and word ones and r <<= 1 for x * 2 and x + x, and does the same replacements for native code. Before, for r1 += 1, r1 += 128, r1 &= 0x3ff and r1 <<= 1: 48 83 c7 01 addq $0x1,%rdi 48 81 c7 80 00 00 00 addq $0x80,%rdi 48 81 e7 ff 03 00 00 andq $0x3ff,%rdi 48 d1 e7 shlq %rdi After: 48 ff c7 incq %rdi 48 83 ef 80 subq $-0x80,%rdi 81 e7 ff 03 00 00 andl $0x3ff,%edi 48 01 ff addq %rdi,%rdi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-9-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Consolidate the ALU, shift and neg encodings into helpersDaniel Borkmann
The add, sub, and, or and xor with an immediate or a register, the shifts by an immediate and neg are open coded in the ALU cases of do_jit(), the add with an immediate once more in the tail call and KASAN check sequences. Add emit_alu_imm(), emit_alu_reg(), emit_shift_imm() and emit_neg() for them and use them there, together with emit_mov_reg(), emit_mov_imm32() and emit_add_rsp() for the open coded moves and stack adjustment in the tail call, the division and the trampoline. The emitted code is unchanged. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-8-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Use movzx for byte and word masks and a not for xor with -1Daniel Borkmann
LLVM lowers u8 and u16 truncations to r &= 0xff and r &= 0xffff, and a bitwise not to r ^= -1, since BPF has neither a zero extending move from a sub-register nor a not instruction. On x86 these masks need the imm32 form of and as they do not fit into a sign-extended imm8. Emit a movzx from the low byte or word instead, which is 3 to 4 bytes and zero extends into the full register for both the 32 and 64-bit variant, and a not for the xor with -1. Both are single cycle instructions on Intel and AMD cores. Before/after for r1 &= 0xff, r1 &= 0xffff and r1 ^= -1: 48 81 e7 ff 00 00 00 andq $0xff,%rdi 40 0f b6 ff movzbl %dil,%edi 48 81 e7 ff ff 00 00 andq $0xffff,%rdi 0f b7 ff movzwl %di,%edi 48 83 f7 ff xorq $-1,%rdi 48 f7 d7 notq %rdi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-7-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Compare against 0, 127 and -128 with the adjusted conditionDaniel Borkmann
A strict compare against 1 or 128 is the non-strict compare against 0 or 127, and a strict compare against -129 or, with a signed condition, -1 the non-strict compare against -128 or 0. LLVM canonicalizes x <= 0 to x < 1, x >= 0 to x > -1 and x <= 127 to x < 128, so these reach the JIT as compares against 1, -1 and 128. Adjust the condition and the immediate, so that the compare against 0 becomes the test without an immediate already emitted for it and 127 and -128 fit into an imm8. Before, for if r1 s> -1 goto ... and if r1 < 128 goto ...: 48 83 ff ff cmpq $-0x1,%rdi 7f xx jg ... 48 81 ff 80 00 00 00 cmpq $0x80,%rdi 72 xx jb ... After: 48 85 ff testq %rdi,%rdi 7d xx jge ... 48 83 ff 7f cmpq $0x7f,%rdi 76 xx jbe ... Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-6-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Use shorter test and cmp encodings for immediatesDaniel Borkmann
test has no sign-extended imm8 form, so a JSET against a constant was always emitted as a 6 to 7 byte test with imm32. When the mask fits into the low byte, the result only depends on that byte, so test the 8-bit register instead, which takes 2 to 4 bytes. Reading the low byte of a register that was written as a whole has no partial register penalty on Intel or AMD cores. Also use the one byte shorter accumulator forms of test and cmp with imm32 when the destination is r0, like the ALU immediates already do. Before/after for if r1 & 0x40 goto ...: 48 f7 c7 40 00 00 00 testq $0x40,%rdi 40 f6 c7 40 testb $0x40,%dil Before/after for if r0 == 0x1000 goto ...: 48 81 f8 00 10 00 00 cmpq $0x1000,%rax 48 3d 00 10 00 00 cmpq $0x1000,%rax Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-5-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Shorten the stack adjusts and the tail call counter loadsDaniel Borkmann
The prologue and the tail call sequences always used the imm32 forms of sub/add rsp and a disp32 load of the tail call counter pointer, even when the rounded stack depth fits into a byte. Route them through the existing emit_sub_rsp()/emit_add_rsp() and emit_ldx() helpers which pick the short forms, and derive the ip adjustment for the counter load in front of a subprog call from the emitted length instead of hardcoding the 7 bytes. Nothing depends on the size of these instructions: the tail call entry offset covers only the code in front of the stack adjustment, and the poke targets are computed from the emitted bytes. Before/after for a program with 32 bytes of stack: 48 81 ec 20 00 00 00 subq $0x20,%rsp 48 83 ec 20 subq $0x20,%rsp 48 8b 85 d0 ff ff ff movq -0x30(%rbp),%rax 48 8b 45 d0 movq -0x30(%rbp),%rax Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-4-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Omit the displacement byte for zero offsetsDaniel Borkmann
A memory operand with a zero offset was encoded with a mod 01 ModR/M and an explicit zero displacement byte. Use the mod 00 form instead, which saves a byte for every load, store and atomic with a zero offset, as LLVM emits them for the first field of a struct and for every plain pointer dereference. The exception are rbp and r13 as base register, where mod 00 with r/m 101 selects a RIP-relative disp32 and with SIB base 101 a disp32 without base, so these keep their displacement byte. Also let emit_st() reuse emit_insn_suffix() instead of open-coding the ModR/M encoding. Before/after for r0 = *(u64 *)(r1 + 0): 48 8b 47 00 movq 0x0(%rdi),%rax 48 8b 07 movq (%rdi),%rax Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-3-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-15bpf, x86: Drop redundant REX prefixes from zero and sign extensionsDaniel Borkmann
movzx into a 32-bit register already clears the upper 32 bits, so the REX.W prefix on the 8 and 16-bit BPF_LDX loads only costs a byte. This also matches what the arena variants of these loads emit. Likewise, the 32-bit movsx from an 8-bit register only needs a REX prefix when the destination is an extended register or the source is sil, dil, bpl or an extended register. LLVM emits these loads for u8 and u16 fields and, with cpu v4, the movsx for a cast to s8 or s16. Before/after for r0 = *(u8 *)(r1 + 0): 48 0f b6 47 00 movzbq 0x0(%rdi),%rax 0f b6 47 00 movzbl 0x0(%rdi),%eax Before/after for w1 = (s8)w0: 40 0f be f8 movsbl %al,%edi 0f be f8 movsbl %al,%edi Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20261013171230.523677-2-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-03bpf: Treat load and store through a number as arena accessAlexei Starovoitov
There are no address spaces in Rust. LLVM emits plain loads and stores for arena memory, without cast_kern: r3 = 0x20 ll // R_BPF_64_64 .bss, libbpf puts it into arena r2 = *(u64 *)(r3 + 0) // R3 invalid mem access 'scalar' lock *(u64 *)(r2 + 8) += r1 Add BPF_F_ARENA_SCALAR flag of BPF_PROG_LOAD. When the program is loaded with it and has an arena treat ldx, stx, st and atomics through a number as arena access. It's as safe as access through PTR_TO_ARENA: JIT adds the base of arena to the low 32 bits of the address. The program has an arena only with CAP_BPF and CAP_PERFMON. Registers of the program are not changed, since Rust compares and stores the address after the access. bpf_do_misc_fixups() copies the low 32 bits into BPF_REG_AX and the access goes through it: r2 = *(u64 *)(r3 + 0) -> w12 = w3 r2 = *(u64 *)(r12 + 0) Constant blinding needs BPF_REG_AX for immediates and leaves insns that use BPF_REG_AX alone. So the immediate of st through a number is not blinded, the rest of the program is: *(u64 *)(r3 + 0) = 1 -> w12 = w3 *(u64 *)(r12 + 0) = 1 The same insn may see PTR_TO_ARENA on another path. It works for both. It's a flag, since a number is also what the verifier makes of a pointer that went away when the program has CAP_PERFMON: a ringbuf record after bpf_ringbuf_submit(), a pointer to the packet after bpf_skb_pull_data(). Programs in C that have an arena keep "invalid mem access 'scalar'" for such bugs. JIT tells with bpf_jit_supports_arena_scalar() that it takes BPF_REG_AX as the address of arena access. With other JITs the flag is rejected with -EOPNOTSUPP. x86 and arm64 do: - x86: the fault handler finds the register that holds the address through reg2pt_regs[]. Add BPF_REG_AX, r10 of x86, there. - arm64: nothing else is needed. The JIT takes any register as the address and the fault handler reads it by its number. Compile tested only. Any number is an address of arena, NULL and small numbers included, like it is for PTR_TO_ARENA: arena code in C dereferences NULL and relies on the fault being handled. Still rejected: - insn that sees a number on one path and a pointer that is not PTR_TO_ARENA on another. - numbers passed to helpers and kfuncs, except __arena arguments. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20261002124714.180012-4-alexei.starovoitov@gmail.com Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-10-02Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.3-rc5Alexei Starovoitov
Cross-merge BPF and other fixes after downstream PR. Conflicts: arch/arm64/net/bpf_jit_comp.c arch/x86/net/bpf_jit_comp.c Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-29bpf: Skip detached progs in trampoline images that are still in useFlorent Revest (Anthropic)
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-25bpf, x86: Fix timed may_goto with private stackAlexei Starovoitov
arch_bpf_timed_may_goto() computes the address of count and timestamp as rbp + offset. When the prog uses private stack the JIT maps r10 to r9 and nothing is reserved under rbp, so bpf_check_timed_may_goto() reads and writes the timestamp in the kernel stack, where arch_bpf_timed_may_goto() has just saved r0-r5 or further down. The following loop in fentry prog with r0-r5 set to zero: 1: may_goto +2 r6 += 1 goto 1b leaves r3 with ktime in it when the prog has 64 bytes of stack and ends after 65535 iterations when it has 128. Add the frame pointer to the offset in the JIT, where rbp vs r9 is known, and pass the pointer in AX. arm64 and powerpc JITs keep the address of private stack in BPF_REG_FP and are not affected. Fixes: 2fb761823ead ("bpf, x86: Add x86 JIT support for timed may_goto") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260924233130.1213812-2-alexei.starovoitov@gmail.com
2026-09-24bpf, x86: Allow programs 2 KiB of stackKumar Kartikeya Dwivedi
The x86-64 JIT encodes frame sizes as 32-bit immediates in its prologue, epilogue and tail call sequences, a tail call pops the frame of the program making it and lands in the target's prologue before the target allocates its own frame, and private stacks are allocated from each program's depth, so nothing in it depends on frames staying within 512 bytes. Report bpf_jit_supports_large_stack(), which raises the budget of JITed programs to MAX_BPF_STACK_JIT: 2 KiB combined over a call chain, or per frame on a private stack, with no separate limit on a single frame. Interpreted programs keep 512 bytes. The worst case kernel stack use of a chain of tail calls grows accordingly: the callers of a tail call may still leave at most 256 bytes on the stack, so 33 programs can accumulate 8 KiB of dead frames below the last one, which may now use 2 KiB instead of 512 bytes, for a little over 10 KiB in total on a 16 KiB kernel stack. The per-cpu memory behind a private stack grows in proportion to the frames a program asks for, up to 2 KiB plus guards per frame. The budget does not depend on the privileges of the loader: an unprivileged program cannot call other BPF functions, so a tail call from one leaves no frame behind and its worst case is a single 2 KiB frame. Programs nested through helpers or attach points, such as a tracing program entered from a helper of a networking program, are not accounted against each other before or after this change; each level of nesting may now add up to 1.5 KiB more. The one nesting a program can force on itself, bpf_clone_redirect() to its own device, keeps that program at 512 bytes. The verifier state of a frame grows with the stack it uses, up to four times as many stack slots as before; the allocation is on demand, so only programs using deep frames pay for them. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260924165740.2146806-17-memxor@gmail.com
2026-09-24bpf, x86: Add JIT support for callxAlexei Starovoitov
Emit indirect call via the register that holds the address of bpf subprog. ld_imm64 BPF_PSEUDO_FUNC is resolved to func[i]->bpf_func by jit_subprogs() already. It's the same address that is passed to helpers as a callback. Add emit_indirect_call() similar to emit_indirect_jump() used by tail calls and gotox: use ITS or retpoline thunks when enabled. Save/restore r9 around the call when private stack is used, like direct calls do. The verifier guarantees that callees of callx are not tail call reachable, so don't pass tail call counter in rax, which may hold the callee address. FineIBT expects indirect callers to go through CFI preamble. Not done yet. Return false from bpf_jit_supports_callx() in this mode, so such progs are rejected at load time. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260924031042.1690890-8-alexei.starovoitov@gmail.com
2026-09-13bpf, x86: Use global buffer for trampoline size generationJiri Olsa
Currently arch_bpf_trampoline_size allocates and frees a temporary trampoline buffer on every invocation. The buffer is only used as a scratch space while __arch_prepare_bpf_trampoline() calculates the required size, and the generated trampoline is discarded. Allocating a writable scratch page during kernel initialization and reusing it for all size calculations. This improves tracing_multi attachment time. With current code: # ./test_progs -t tracing_multi_bench_attach -v ... serial_test_tracing_multi_bench_attach: found 55227 functions serial_test_tracing_multi_bench_attach: attached in 1.563s serial_test_tracing_multi_bench_attach: detached in 0.256s With the fix: # ./test_progs -t tracing_multi_bench_attach -v ... serial_test_tracing_multi_bench_attach: found 55235 functions serial_test_tracing_multi_bench_attach: attached in 0.798s serial_test_tracing_multi_bench_attach: detached in 0.258s Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20260910094353.1256316-1-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-12bpf, x86: Move kfunc arguments into the x86-64 calling conventionYonghong Song
The x86-64 allows 6 register arguments and then stack arguments, but backfilling the 6th register is possible, as in the following example: /* s is a 16-byte struct */ void kfunc(u64 a, u64 b, u64 c, u64 d, u64 e, struct big s, u64 f) BPF puts s in slots 5 and 6, R9 and the first stack slot, and f in slot 7, while x86-64 puts s in the two stack slots and f in R9. Emit the moves bpf_jit_plan_arg_moves() plans to bridge the two. Only one argument ever moves down, as an argument frees one register at most, so carrying that single value in the scratch register past its own destination is enough. In addition, the arena argument walk counts eightbytes rather than parameters, as an argument may take two registers. Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Link: https://lore.kernel.org/r/20260912195247.989857-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-06Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.3-rc2Alexei Starovoitov
Cross-merge BPF and other fixes after downstream PR. Conflicts: kernel/bpf/backtrack.c include/linux/bpf_verifier.h Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-04bpf, x86: emit KASAN checks in x86 JITed programsAlexis Lothoré (eBPF Foundation)
Insert KASAN shadow memory checks before memory load and store operations in JIT-compiled BPF programs. This helps detect memory safety bugs such as use-after-free and out-of-bounds accesses at runtime. The main instructions being targeted are BPF_ST, BPF_STX and BPF_LDX, but not all of them are being instrumented: - if the load/store instruction is in fact accessing the program stack, emit_kasan_check silently skips the instrumentation, as we can already benefit from guard pages to monitor stack accesses. - if the load/store instruction is a BPF_PROBE_MEM or a BPF_PROBE_ATOMIC instruction, we do not instrument it, as the passed address can fault (hence the custom fault management with BPF_PROBE_XXX instructions), and so the corresponding kasan check could fault as well. To support those new instructions insertion, create the emit_kasan_check() helper that emits KASAN shadow memory checks before memory accesses in JIT-compiled BPF programs. The implementation relies on the existing __asan_{load,store}X functions from KASAN subsystem. The helper: - saves registers. This includes caller-saved registers, but also temporary registers, as those were possibly used by the affected program. - computes the accessed address and stores it in %rdi - calls the relevant function, depending on the instruction being a load or a store, and the size of the access. - restores registers The special care needed when inserting this instrumentation comes at the cost of a non negligeable increase in JITed code size. For example, a bare mov 0x0(%si),rbx # Load in rbx content at address stored in rsi becomes push %rax push %rcx push %rdx push %rsi push %rdi push %r8 push %r9 push %r10 push %r11 mov %rsi,%rdi call 0xffffffff81da0a60 <__asan_load8> pop %r11 pop %r10 pop %r9 pop %r8 pop %rdi pop %rsi pop %rdx pop %rcx pop %rax mov 0x0(%rsi),rbx Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Link: https://lore.kernel.org/r/20260903-kasan-v9-4-2407fe99255a@bootlin.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-09-04bpf, x86: refactor BPF_ST management in do_jitAlexis Lothoré (eBPF Foundation)
In order to prepare for KASAN checks insertion before every memory-related load or store, group all BPF_ST instructions that indeed access memory in a single helper to allow instrumenting those in one call, rather than having to instrument all cases individually. Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com> Link: https://lore.kernel.org/r/20260903-kasan-v9-3-2407fe99255a@bootlin.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-08-21bpf: Wire up JIT support for 16-byte kfunc returnsYonghong Song
LLVM 23 returns an __int128, or a struct/union larger than 8 bytes and no larger than 16 bytes, in the BPF R0:R2 register pair. The previous patch added the shared helpers describing that convention; wire up the JIT side so that the second half of the return value actually lands in R2. Placing the second return half into R2 is possible on any JIT, but it needs architecture-specific JIT work. Rather than requiring every JIT to implement it at once, add a bpf_jit_supports_kfunc_ret_reg_pair() capability, defaulting to false in the generic core; an architecture opts in once its JIT handles the R0:R2 pair, and the remaining ones are left for future work. Only the x86-64, arm64 and riscv64 JITs opt in so far. On arm64 and riscv64 the native second return register is already BPF R2 (x1 in bpf2a64[] and a1 in regmap[] respectively), so the upper half needs no move at all, unlike x86-64's RDX->RSI. The lower half is covered by the move into BPF R0 that those JITs already emit after every call, from x0 into x8 and from a0 into a5. This has been tested on x86-64 and arm64. The riscv64 path is expected to work by the same register-mapping reasoning as arm64 but has not been tested. bpf_add_kfunc_call() also rejects a kfunc that is marked KF_FASTCALL and returns more than 8 bytes. The bpf_fastcall contract implemented by mark_fastcall_pattern_for_call() assumes a call clobbers R0 plus the registers holding its arguments, so a return in the R0:R2 pair would clobber an R2 the caller expects the fastcall pattern to preserve. Such a kfunc is rejected with -EOPNOTSUPP as well. Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260819055254.3295610-1-yonghong.song@linux.dev Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-08-20x86/bpf: Make arch_bpf_trampoline_size allocate from EXECMEM_MODULE_DATAMike Rapoport (Microsoft)
Jiri Olsa reports slowdown of tracing_multi benchmark that allocates huge number of trampolines [1]. The slowdown caused by extra protection changes in execmem_alloc_rw() and execmem_free(). With ROX caches enabled, all execmem allocations except EXECMEM_MODULE_DATA are ROX after the allocation. execmem_alloc_rw() temporarily sets them to W+NX and execmem_free() resets them back to ROX. The only user of bpf_jit_alloc_exec_rw() is x86::arch_bpf_trampoline_size() that only needs a temporary writable buffer in the modules address space. On x86 executable memory and module data are constrained to the same address range, so x86::arch_bpf_trampoline_size() can directly use execmem_alloc(EXECMEM_MODULE_DATA) Replace the call to bpf_jit_alloc_exec_rw() with a call to execmem_alloc(EXECMEM_MODULE_DATA) in x86::arch_bpf_trampoline_size() and drop bpf_jit_alloc_exec_rw() helper. Fixes: 5bf02dbf39fa ("bpf, x86: Make sure allocation in arch_bpf_trampoline_size() is writable") Reported-by: Jiri Olsa <olsajiri@gmail.com> Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Tested-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/all/an8r7EODLIL-bZM3@krava Link: https://lore.kernel.org/bpf/20260818130510.3110054-1-rppt@kernel.org
2026-08-14bpf, x86: Fix per-CPU address resolution into an extended registerVineet Gupta
The destination of the per-CPU address MOV is encoded in ModRM.reg, which is extended by REX.R, but the REX prefix is built with add_1mod(), which sets REX.B. REX.B extends ModRM.rm and SIB.base, and this instruction addresses memory as disp32 with no base, so the bit has no effect at all and the high register bit is simply lost. Every is_ereg() destination therefore resolves to the wrong register, picking whichever one shares the low three bits: R5 -> RAX R7 -> RBP R8 -> RSI R9 -> RDI With BPF_REG_5, whose reg2hex is 0, the emitted 65 49 03 04 25 <off> add %gs:<off>,%rax adds the per-CPU offset to RAX rather than R8. The destination keeps the unadjusted address and RAX is clobbered, so the program goes on to dereference a pointer that was never made per-CPU: BUG: unable to handle page fault for address: 0000607e386a8894 RIP: bpf_prog_707837aafd2aa9ae_update_percpu_data+0x93/0xc9 Call Trace: __bpf_prog_test_run_raw_tp+0x2dc/0x7d0 __flush_smp_call_function_queue+0x1e9/0xc80 Kernel panic - not syncing: Fatal exception in interrupt R5 is the mildest of the four, aliasing a scratch register and faulting at the store. R7 aliases RBP and would corrupt the frame pointer, R8 and R9 alias the argument registers. Use add_2mod() so the register goes through REX.R, matching how add_2reg() places it in ModRM.reg and how emit_priv_frame_ptr() hardcodes 0x4c for the same instruction with R9. Encodings for the non-extended registers are unchanged. Problem showed up when trying to resurrect BPF_GCC CI (selftests built with BPF_GCC). This has gone unnoticed because clang reloads the address into R1 before each per-CPU access, so the destination is never an extended register. GCC keeps several per-CPU addresses live at once, and test_progs-bpf_gcc panics the kernel in global_percpu_data/init, where the address of a .percpu variable ends up in R5. Fixes: 7bdbf7446305 ("bpf: add special internal-only MOV instruction to resolve per-CPU addrs") Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260814220254.3797467-2-vineet.gupta@linux.dev Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-08-12bpf, x86: Clear fetch destination on faulting arena atomicDaniel Borkmann
populate_extable() encodes "there is no destination register to clear" as DONT_CLEAR in the DST_REG field of the exception table metadata, and later ex_handler_bpf() then reuses that very value to derive the direction it reports the fault with is_write = (reg == DONT_CLEAR). The two coincide for a plain load or store, but not for a RMW carrying BPF_FETCH. Such an atomic writes memory, so it has to be reported as a WRITE, and it also reads the old value into a register, src_reg for BPF_ADD | BPF_FETCH and BPF_XCHG, r0 for BPF_CMPXCHG, so that register has to be cleared on fault. A single DONT_CLEAR cannot say both, and the store branch picks it unconditionally: [...] } else { arena_reg = reg2pt_regs[dst_reg]; fixup_reg = DONT_CLEAR; } [...] The reported direction is therefore right, but on a fault over an unmapped arena page the fetch destination keeps whatever it held before the atomic, where every other BPF_PROBE_* access delivers 0. Give the metadata its own ARENA_WRITE bit so that the reported direction no longer depends on whether there is a register to clear, and fill DST_REG in from bpf_atomic_load_reg(). BPF_{AND,OR,XOR} | BPF_FETCH need no handling here, bpf_jit_supports_insn() already rejects those in the arena. Fixes: d503a04f8bc0 ("bpf: Add support for certain atomics in bpf_arena to x86 JIT") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Puranjay Mohan <puranjay@kernel.org> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260811131600.506721-3-daniel@iogearbox.net Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-08-08bpf, x86: Fix stack-passed arguments for indirect trampolinesTejun Heo
save_args() reads stack-passed arguments relative to rbp assuming two return addresses sit between the saved rbp and the arguments, which holds when the trampoline is entered through the fentry call from a traced function. An indirect trampoline is called through a function pointer, so only the caller's return address is on the stack and the arguments start at rbp + 16, not rbp + 24. Every stack-passed argument of a struct_ops callback with more than six argument slots is read one slot off. This has gone unnoticed because no in-tree struct_ops member passes arguments on the stack. The jmp-entry form already accounts for having a single return address; treat BPF_TRAMP_F_INDIRECT the same way. Fixes: 473e3150e30a ("bpf, x86: allow function arguments up to 12 for TRACING") Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Tested-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260808003938.3486067-12-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-08-08bpf, x86: Convert struct_ops arena arguments in the trampolineTejun Heo
Implement the struct_ops arena argument conversion on x86. save_args() receives the arena base from bpf_tramp_arena_base() and consults the btf_func_model argument flags as it copies each native argument into the BPF ctx, routing a marked argument through RAX: movl %esrc, %eax /* truncate and clear the upper 32 bits */ subl $base_lo, %eax movq %rax, ctx_slot A nullable argument tests the full 64-bit kernel pointer first: movq %rsrc, %rax testq %rax, %rax jz 1f subl $base_lo, %eax 1: movq %rax, ctx_slot The 32-bit subtraction is sufficient since (u32)(kaddr - base) == (u32)kaddr - (u32)base, and it clears the upper half as the JITs require of arena pointer registers. Stack-passed arguments already reload through RAX, so only the subtraction (and the NULL test) is inserted there. Keep arena and nullable classification in btf_func_model. bpf_tramp_arena_base() returns a base only for a single-program struct_ops indirect trampoline; other trampolines pass zero and perform no conversion. The size probe reruns the same emission with the same model and nodes, so the image size matches by construction. With both the kfunc and struct_ops directions implemented, flip bpf_jit_supports_arena_args() on for x86. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260808003938.3486067-8-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-08-08bpf, x86: JIT __arena kfunc argument rebasingTejun Heo
Implement arena argument rebasing for kfunc calls on x86. R12 already holds kern_vm_start whenever the prog has an arena, so each tagged argument costs two instructions emitted right before the call: movl %eN, %eN /* truncate, clear the upper 32 bits */ addq %r12, %rN A nullable argument tests the truncated value and jumps over the add: movl %eN, %eN testl %eN, %eN jz 1f addq %r12, %rN 1: addq carries a REX prefix for every argument register and is always three bytes, so the jz displacement is constant. The sequence is native code generated after constant blinding has run on the BPF instruction stream, so blinding never sees the rebase and needs no special handling. bpf_jit_supports_arena_args() is not flipped yet; that happens when the struct_ops trampoline side is in place as well. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://patch.msgid.link/20260808003938.3486067-7-memxor@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
2026-08-07bpf, x86: Fix exception table metadata for arena load-acquireDaniel Borkmann
A load-acquire from an arena pointer is converted to BPF_PROBE_ATOMIC and gets an exception table entry, but the entry is filled in as if it were a store, since populate_extable() decides based on instruction class alone and a load-acquire is of BPF_STX class: if (BPF_CLASS(insn->code) == BPF_LDX) { arena_reg = reg2pt_regs[src_reg]; fixup_reg = reg2pt_regs[dst_reg]; } else { arena_reg = reg2pt_regs[dst_reg]; fixup_reg = DONT_CLEAR; } For a load-acquire dst_reg holds the loaded value and src_reg holds the address, so both assignments in the else branch are wrong. On a fault over an unmapped arena page ex_handler_bpf() then: - computes the reported address from the value register instead of the address register - reports the access as a WRITE, since it derives the direction from fixup_reg == DONT_CLEAR - leaves dst_reg untouched, so the program continues with a stale value instead of the 0 that BPF_PROBE_* loads deliver The access itself is emitted correctly, emit_atomic_ld_st_index() uses src_reg as the address, so this is a broken probe contract and a wrong diagnostic rather than a memory safety issue. Use bpf_atomic_is_load_acq() helper so a load-acquire takes the load path. Fixes: 5341c9a4d833 ("bpf, x86: Support load-acquire and store-release instructions") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20260806201047.333389-3-daniel@iogearbox.net Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-08-01bpf, x86: Fix trampoline stack size for 128-bit argumentsYonghong Song
btf_distill_func_proto() accepts a function argument up to 16 bytes, so a 128-bit scalar such as __int128 reaches the x86 trampoline with arg_size == 16. But the current implementation assumes an __int128 argument only needs one register, so the register save area is under-allocated and save_args() overwrites adjacent stack slots. Compute the register count from arg_size for all arguments to fix it. Fixes: a9c5ad31fbdc ("bpf: x86: Support in-register struct arguments in trampoline programs") Signed-off-by: Yonghong Song <yonghong.song@linux.dev> Acked-by: Leon Hwang <leon.hwang@linux.dev> Link: https://lore.kernel.org/bpf/20260729050204.2586457-1-yonghong.song@linux.dev Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-22bpf, x86: Make sure allocation in arch_bpf_trampoline_size() is writableMike Rapoport (Microsoft)
arch_bpf_trampoline_size() allocates a buffer to get actual size required for a trampoline. This buffer must be in the module address space because __arch_prepare_bpf_trampoline() calculates rel32 offsets relatively to that buffer. In preparation for enabling ROX mode for EXECMEM_BPF make sure that the allocated memory is writable. Add bpf_jit_alloc_exec_rw() wrapper for execmem_alloc_rw() and use it for buffer allocation in arch_bpf_trampoline_size(). Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Acked-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/bpf/20260716-execmem-x86-rox-bpf-v0-v3-4-4e76158c01c5@kernel.org Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
2026-07-01bpf: Restrict JIT predictor flush to cBPFPawan Gupta
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>