diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-20 07:36:20 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-20 07:36:20 -0700 |
| commit | 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500 (patch) | |
| tree | 49b7f303dc09e1806777ebdfc64a30ba31d73720 /kernel/bpf/arraymap.c | |
| parent | a4ff2be345d0abc943da8dd8da98151843b750dc (diff) | |
| parent | f79066c784022fda83f5936559a1af414e41b603 (diff) | |
Merge tag 'bpf-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Pull bpf updates from Daniel Borkmann:
"Major changes:
- Redesign the verifier error reporting: failures now carry source
and instruction annotations along with the causal event history
that led to them, making program rejections far easier to debug and
repair (Kumar Kartikeya Dwivedi)
- Add arena argument support to kfuncs and struct_ops through the new
__arena and __arena__nullable suffixes (Tejun Heo, Puranjay Mohan,
Kumar Kartikeya Dwivedi, Ihor Solodrai)
- Signed BPF program loader rework to accommodate both BPF and
security community needs where the kernel runs the signature
verification at BPF_PROG_LOAD time before the LSM admission hook
(Daniel Borkmann)
- Add a set of ksock kfuncs which let BPF LSM and syscall programs
create, connect and send on UDP sockets in order to emit telemetry
data (Mahe Tardy)
- Unify helper and kfunc call argument verification and classify
kfunc arguments purely from BTF into a generated bpf_func_proto
which is computed once at add-call time (Amery Hung)
Other features and fixes:
- Enable EXECMEM_ROX_CACHE for BPF allocations on x86 (Mike Rapoport)
- Add bidirectional VLAN support to bpf_fib_lookup() through the new
BPF_FIB_LOOKUP_VLAN and BPF_FIB_LOOKUP_VLAN_INPUT flags (Avinash
Duduskar)
- Infer zext_dst from static register liveness analysis to fix 32-bit
zero-extension semantics, and remove the artificial limitations on
pointer types eligible for spilling (Eduard Zingerman)
- Inline the numeric open-coded iterator kfuncs so that bpf_for()
loops no longer pay a kfunc call on every iteration (Puranjay
Mohan)
- Add an arena-based bitmap data structure to libarena along with
serial and parallel selftests (Emil Tsalapatis)
- Teach resolve_btfids to discover kfuncs from the kernel's BTF ID
sets and to emit kfunc BTF decl tags, reducing the kernel build's
dependency on pahole features (Ihor Solodrai)
- Add BPF_F_ADJ_ROOM_DECAP_* flags to bpf_skb_adjust_room() so that
tunnel decapsulation can update the GSO and encapsulation state of
the skb (Nick Hudson)
- Fix the ring buffer pending_pos walk and the available-data
accounting on 32-bit position wrap (Israel Téllez García)
- Add memory usage accounting for arena maps and fix an mmap_lock
deadlock on arena lock failure (Jiayuan Chen)
- Add tracing_multi link info support to the kernel UAPI and bpftool,
and refactor the stack map code to run with preemption disabled
(Jiri Olsa)
- Support BPF_F_EGRESS in bpf_redirect_peer() to emit the skb in the
egress direction of the target's peer device (Jordan Rife)
- Add a KF_SPINLOCK_SAFE kfunc flag so that providers, in particular
modules, can declare kfuncs safe to call under bpf_spin_lock
instead of relying on the verifier's hard-coded allowlist (Kaitao
Cheng)
- Introduce global percpu data for BPF programs with libbpf probing
and bpftool skeleton support, and stop exposing uninitialized
kernel heap memory when copying per-CPU map values (Leon Hwang)
- Add s390 JIT support for load-acquire and store-release
instructions (Maxim Khmelevskii)
- Fix a CFI mismatch in the task work callback and an arm64 KASAN
false positive after bpf_throw() (Mykyta Yatsenko)
- Reject writes through untrusted BTF pointers and bound the
rdonly/rdwr_buf_size kfunc arguments (Nicholas Dudar)
- Invalidate RCU pointers only after the final spin unlock and
account for preempt and IRQ disabled regions as overlapping RCU
protection (Ning Ding)
- Support mixing bpf2bpf calls and tail calls on RV64, add signed
operations and 32-bit atomics to the RV32 JIT, and add timed
may_goto support (Pu Lehui, Kuan-Wei Chiu, Feng Jiang)
- Fix a use-after-free on mm_struct in bpf_find_vma() for foreign
tasks and an mmap_lock leak in the irq_work path (Sanghyun Park)
- Populate mmap-able BPF array map memory lazily which makes mmap()
O(1) instead of proportional to the map size (Song Liu)
- Introduce a jit_required flag and reject programs with inlined
helpers when no JIT is available, where the interpreter would
otherwise jump into an invalid address (Tiezhu Yang)
- Fix the x86 JIT per-CPU address resolution into an extended
register where the REX prefix dropped the high destination register
bit (Vineet Gupta)
- Reject MEM_ALLOC BTF accesses past object bounds, arena frees below
the arena base, and mixed arena and ordinary atomic paths (Yiyang
Chen)
- Fix the trampoline handling of 128-bit arguments and of return
values larger than 8 bytes (Yonghong Song)
- Ensure that any fault prone load is rewritten with exception table
handling, and fix the arena load-acquire and atomic fetch handling
in the x86, arm64, riscv and s390 JITs (Daniel Borkmann)
- Many more fixes and cleanups across the verifier, arena,
trampolines, sockmap, cgroup, ring buffer, x86/arm64/riscv/s390
JITs, libbpf, bpftool, resolve_btfids and selftests"
* tag 'bpf-next-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (373 commits)
selftests/bpf: Add tests for a store on a fault prone qdisc pointer
selftests/bpf: Add tests for fault prone loads out of RCU pointers
selftests/bpf: Add tests for pointer type merge at a shared load
selftests/bpf: Remove duplicate copies of the arena spinlock qnodes
selftests/bpf: Retry stat generation in cgroup_iter_memcg
selftests/bpf: Test pseudo-function policy diagnostics
bpf: Distinguish function references in policy diagnostics
bpf: Preserve source attribution without source text
selftests/bpf: Test kfunc argument diagnostics
bpf: Correct kfunc argument diagnostics
bpf: Use canonical stack argument names in diagnostics
bpf: Preserve R0 lineage across helper calls
selftests/bpf: Exercise negative optlen in cgroup getsockopt hook
bpf: Reject negative optlen in cgroup getsockopt hook
selftests/bpf: tc_tunnel - validate decap GSO and encapsulation state
bpf: Clear decap state on skb_adjust_room shrink path
bpf: Allow new DECAP flags and add guard rails
bpf: Add BPF_F_ADJ_ROOM_DECAP_* flags for tunnel decapsulation
bpf: Refactor masks for ADJ_ROOM flags and encap validation
bpf: Name the enum for BPF_FUNC_skb_adjust_room flags
...
Diffstat (limited to 'kernel/bpf/arraymap.c')
| -rw-r--r-- | kernel/bpf/arraymap.c | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 248b4818178c..ef315b168b29 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -259,6 +259,37 @@ static void *percpu_array_map_lookup_elem(struct bpf_map *map, void *key) return this_cpu_ptr(array->pptrs[index & array->index_mask]); } +static int percpu_array_map_direct_value_addr(const struct bpf_map *map, u64 *imm, u32 off) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + + if (!bpf_jit_supports_percpu_insn()) + return -EOPNOTSUPP; + if (map->max_entries != 1) + return -EOPNOTSUPP; + if (off >= map->value_size) + return -EINVAL; + + *imm = (u64)(__force unsigned long) array->pptrs[0]; + return 0; +} + +static int percpu_array_map_direct_value_meta(const struct bpf_map *map, u64 imm, u32 *off) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + u64 base = (u64)(__force unsigned long) array->pptrs[0]; + + if (!bpf_jit_supports_percpu_insn()) + return -EOPNOTSUPP; + if (map->max_entries != 1) + return -EOPNOTSUPP; + if (imm < base || imm >= base + array->elem_size) + return -ENOENT; + + *off = imm - base; + return 0; +} + /* emit BPF instructions equivalent to C code of percpu_array_map_lookup_elem() */ static int percpu_array_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf) { @@ -551,9 +582,10 @@ static int array_map_check_btf(struct bpf_map *map, const struct btf_type *key_type, const struct btf_type *value_type) { - /* One exception for keyless BTF: .bss/.data/.rodata map */ + /* One exception for keyless BTF: .bss/.data/.rodata/.percpu map */ if (btf_type_is_void(key_type)) { - if (map->map_type != BPF_MAP_TYPE_ARRAY || + if ((map->map_type != BPF_MAP_TYPE_ARRAY && + map->map_type != BPF_MAP_TYPE_PERCPU_ARRAY) || map->max_entries != 1) return -EINVAL; @@ -576,17 +608,42 @@ static int array_map_check_btf(struct bpf_map *map, static int array_map_mmap(struct bpf_map *map, struct vm_area_struct *vma) { struct bpf_array *array = container_of(map, struct bpf_array, map); - pgoff_t pgoff = PAGE_ALIGN(sizeof(*array)) >> PAGE_SHIFT; if (!(map->map_flags & BPF_F_MMAPABLE)) return -EINVAL; - if (vma->vm_pgoff * PAGE_SIZE + (vma->vm_end - vma->vm_start) > + /* use u64 math so the offset cannot overflow on 32-bit archs */ + if ((u64)vma->vm_pgoff * PAGE_SIZE + (vma->vm_end - vma->vm_start) > PAGE_ALIGN((u64)array->map.max_entries * array->elem_size)) return -EINVAL; - return remap_vmalloc_range(vma, array_map_vmalloc_addr(array), - vma->vm_pgoff + pgoff); + /* + * Pages are faulted in on demand by array_map_mmap_fault(). Set the + * same flags that the eager remap_vmalloc_range() path used to set + * via vm_insert_page(), so that e.g. NUMA balancing keeps skipping + * these VMAs. + */ + vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP | VM_MIXEDMAP); + + return 0; +} + +static vm_fault_t array_map_mmap_fault(struct bpf_map *map, + struct vm_fault *vmf) +{ + struct bpf_array *array = container_of(map, struct bpf_array, map); + struct page *page; + + page = vmalloc_to_page(array->value + ((u64)vmf->pgoff << PAGE_SHIFT)); + if (!page) + return VM_FAULT_SIGBUS; + + /* the eager remap_vmalloc_range() flushed via vm_insert_page() */ + flush_dcache_folio(page_folio(page)); + get_page(page); + vmf->page = page; + + return 0; } static bool array_map_meta_equal(const struct bpf_map *meta0, @@ -812,6 +869,7 @@ const struct bpf_map_ops array_map_ops = { .map_direct_value_addr = array_map_direct_value_addr, .map_direct_value_meta = array_map_direct_value_meta, .map_mmap = array_map_mmap, + .map_mmap_fault = array_map_mmap_fault, .map_seq_show_elem = array_map_seq_show_elem, .map_check_btf = array_map_check_btf, .map_lookup_batch = generic_map_lookup_batch, @@ -832,6 +890,8 @@ const struct bpf_map_ops percpu_array_map_ops = { .map_get_next_key = bpf_array_get_next_key, .map_lookup_elem = percpu_array_map_lookup_elem, .map_gen_lookup = percpu_array_map_gen_lookup, + .map_direct_value_addr = percpu_array_map_direct_value_addr, + .map_direct_value_meta = percpu_array_map_direct_value_meta, .map_update_elem = array_map_update_elem, .map_delete_elem = array_map_delete_elem, .map_lookup_percpu_elem = percpu_array_map_lookup_percpu_elem, |
