Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says:

====================
pull-request: bpf 2024-03-25

The following pull-request contains BPF updates for your *net* tree.

We've added 17 non-merge commits during the last 12 day(s) which contain
a total of 19 files changed, 184 insertions(+), 61 deletions(-).

The main changes are:

1) Fix an arm64 BPF JIT bug in BPF_LDX_MEMSX implementation's offset handling
found via test_bpf module, from Puranjay Mohan.

2) Various fixups to the BPF arena code in particular in the BPF verifier and
around BPF selftests to match latest corresponding LLVM implementation,
from Puranjay Mohan and Alexei Starovoitov.

3) Fix xsk to not assume that metadata is always requested in TX completion,
from Stanislav Fomichev.

4) Fix riscv BPF JIT's kfunc parameter incompatibility between BPF and the riscv
ABI which requires sign-extension on int/uint, from Pu Lehui.

5) Fix s390x BPF JIT's bpf_plt pointer arithmetic which triggered a crash when
testing struct_ops, from Ilya Leoshkevich.

6) Fix libbpf's arena mmap handling which had incorrect u64-to-pointer cast on
32-bit architectures, from Andrii Nakryiko.

7) Fix libbpf to define MFD_CLOEXEC when not available, from Arnaldo Carvalho de Melo.

8) Fix arm64 BPF JIT implementation for 32bit unconditional bswap which
resulted in an incorrect swap as indicated by test_bpf, from Artem Savkov.

9) Fix BPF man page build script to use silent mode, from Hangbin Liu.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
riscv, bpf: Fix kfunc parameters incompatibility between bpf and riscv abi
bpf: verifier: reject addr_space_cast insn without arena
selftests/bpf: verifier_arena: fix mmap address for arm64
bpf: verifier: fix addr_space_cast from as(1) to as(0)
libbpf: Define MFD_CLOEXEC if not available
arm64: bpf: fix 32bit unconditional bswap
bpf, arm64: fix bug in BPF_LDX_MEMSX
libbpf: fix u64-to-pointer cast on 32-bit arches
s390/bpf: Fix bpf_plt pointer arithmetic
xsk: Don't assume metadata is always requested in TX completion
selftests/bpf: Add arena test case for 4Gbyte corner case
selftests/bpf: Remove hard coded PAGE_SIZE macro.
libbpf, selftests/bpf: Adjust libbpf, bpftool, selftests to match LLVM
bpf: Clarify bpf_arena comments.
MAINTAINERS: Update email address for Quentin Monnet
scripts/bpf_doc: Use silent mode when exec make cmd
bpf: Temporarily disable atomic operations in BPF arena
====================

Link: https://lore.kernel.org/r/20240325213520.26688-1-daniel@iogearbox.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+184 -61
+2 -1
.mailmap
··· 497 497 Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com> 498 498 Qais Yousef <qyousef@layalina.io> <qais.yousef@imgtec.com> 499 499 Qais Yousef <qyousef@layalina.io> <qais.yousef@arm.com> 500 - Quentin Monnet <quentin@isovalent.com> <quentin.monnet@netronome.com> 500 + Quentin Monnet <qmo@kernel.org> <quentin.monnet@netronome.com> 501 + Quentin Monnet <qmo@kernel.org> <quentin@isovalent.com> 501 502 Quentin Perret <qperret@qperret.net> <quentin.perret@arm.com> 502 503 Rafael J. Wysocki <rjw@rjwysocki.net> <rjw@sisk.pl> 503 504 Rajeev Nandan <quic_rajeevny@quicinc.com> <rajeevny@codeaurora.org>
+1 -1
MAINTAINERS
··· 3967 3967 F: kernel/bpf/cgroup.c 3968 3968 3969 3969 BPF [TOOLING] (bpftool) 3970 - M: Quentin Monnet <quentin@isovalent.com> 3970 + M: Quentin Monnet <qmo@kernel.org> 3971 3971 L: bpf@vger.kernel.org 3972 3972 S: Maintained 3973 3973 F: kernel/bpf/disasm.*
+2 -2
arch/arm64/net/bpf_jit_comp.c
··· 943 943 emit(A64_UXTH(is64, dst, dst), ctx); 944 944 break; 945 945 case 32: 946 - emit(A64_REV32(is64, dst, dst), ctx); 946 + emit(A64_REV32(0, dst, dst), ctx); 947 947 /* upper 32 bits already cleared */ 948 948 break; 949 949 case 64: ··· 1256 1256 } else { 1257 1257 emit_a64_mov_i(1, tmp, off, ctx); 1258 1258 if (sign_extend) 1259 - emit(A64_LDRSW(dst, src_adj, off_adj), ctx); 1259 + emit(A64_LDRSW(dst, src, tmp), ctx); 1260 1260 else 1261 1261 emit(A64_LDR32(dst, src, tmp), ctx); 1262 1262 }
+16
arch/riscv/net/bpf_jit_comp64.c
··· 1463 1463 if (ret < 0) 1464 1464 return ret; 1465 1465 1466 + if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) { 1467 + const struct btf_func_model *fm; 1468 + int idx; 1469 + 1470 + fm = bpf_jit_find_kfunc_model(ctx->prog, insn); 1471 + if (!fm) 1472 + return -EINVAL; 1473 + 1474 + for (idx = 0; idx < fm->nr_args; idx++) { 1475 + u8 reg = bpf_to_rv_reg(BPF_REG_1 + idx, ctx); 1476 + 1477 + if (fm->arg_size[idx] == sizeof(int)) 1478 + emit_sextw(reg, reg, ctx); 1479 + } 1480 + } 1481 + 1466 1482 ret = emit_call(addr, fixed_addr, ctx); 1467 1483 if (ret) 1468 1484 return ret;
+20 -26
arch/s390/net/bpf_jit_comp.c
··· 516 516 * PLT for hotpatchable calls. The calling convention is the same as for the 517 517 * ftrace hotpatch trampolines: %r0 is return address, %r1 is clobbered. 518 518 */ 519 - extern const char bpf_plt[]; 520 - extern const char bpf_plt_ret[]; 521 - extern const char bpf_plt_target[]; 522 - extern const char bpf_plt_end[]; 523 - #define BPF_PLT_SIZE 32 519 + struct bpf_plt { 520 + char code[16]; 521 + void *ret; 522 + void *target; 523 + } __packed; 524 + extern const struct bpf_plt bpf_plt; 524 525 asm( 525 526 ".pushsection .rodata\n" 526 527 " .balign 8\n" ··· 532 531 " .balign 8\n" 533 532 "bpf_plt_ret: .quad 0\n" 534 533 "bpf_plt_target: .quad 0\n" 535 - "bpf_plt_end:\n" 536 534 " .popsection\n" 537 535 ); 538 536 539 - static void bpf_jit_plt(void *plt, void *ret, void *target) 537 + static void bpf_jit_plt(struct bpf_plt *plt, void *ret, void *target) 540 538 { 541 - memcpy(plt, bpf_plt, BPF_PLT_SIZE); 542 - *(void **)((char *)plt + (bpf_plt_ret - bpf_plt)) = ret; 543 - *(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target ?: ret; 539 + memcpy(plt, &bpf_plt, sizeof(*plt)); 540 + plt->ret = ret; 541 + plt->target = target; 544 542 } 545 543 546 544 /* ··· 662 662 jit->prg = ALIGN(jit->prg, 8); 663 663 jit->prologue_plt = jit->prg; 664 664 if (jit->prg_buf) 665 - bpf_jit_plt(jit->prg_buf + jit->prg, 665 + bpf_jit_plt((struct bpf_plt *)(jit->prg_buf + jit->prg), 666 666 jit->prg_buf + jit->prologue_plt_ret, NULL); 667 - jit->prg += BPF_PLT_SIZE; 667 + jit->prg += sizeof(struct bpf_plt); 668 668 } 669 669 670 670 static int get_probe_mem_regno(const u8 *insn) ··· 2040 2040 struct bpf_jit jit; 2041 2041 int pass; 2042 2042 2043 - if (WARN_ON_ONCE(bpf_plt_end - bpf_plt != BPF_PLT_SIZE)) 2044 - return orig_fp; 2045 - 2046 2043 if (!fp->jit_requested) 2047 2044 return orig_fp; 2048 2045 ··· 2145 2148 int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, 2146 2149 void *old_addr, void *new_addr) 2147 2150 { 2151 + struct bpf_plt expected_plt, current_plt, new_plt, *plt; 2148 2152 struct { 2149 2153 u16 opc; 2150 2154 s32 disp; 2151 2155 } __packed insn; 2152 - char expected_plt[BPF_PLT_SIZE]; 2153 - char current_plt[BPF_PLT_SIZE]; 2154 - char new_plt[BPF_PLT_SIZE]; 2155 - char *plt; 2156 2156 char *ret; 2157 2157 int err; 2158 2158 ··· 2168 2174 */ 2169 2175 } else { 2170 2176 /* Verify the PLT. */ 2171 - plt = (char *)ip + (insn.disp << 1); 2172 - err = copy_from_kernel_nofault(current_plt, plt, BPF_PLT_SIZE); 2177 + plt = ip + (insn.disp << 1); 2178 + err = copy_from_kernel_nofault(&current_plt, plt, 2179 + sizeof(current_plt)); 2173 2180 if (err < 0) 2174 2181 return err; 2175 2182 ret = (char *)ip + 6; 2176 - bpf_jit_plt(expected_plt, ret, old_addr); 2177 - if (memcmp(current_plt, expected_plt, BPF_PLT_SIZE)) 2183 + bpf_jit_plt(&expected_plt, ret, old_addr); 2184 + if (memcmp(&current_plt, &expected_plt, sizeof(current_plt))) 2178 2185 return -EINVAL; 2179 2186 /* Adjust the call address. */ 2180 - bpf_jit_plt(new_plt, ret, new_addr); 2181 - s390_kernel_write(plt + (bpf_plt_target - bpf_plt), 2182 - new_plt + (bpf_plt_target - bpf_plt), 2187 + bpf_jit_plt(&new_plt, ret, new_addr); 2188 + s390_kernel_write(&plt->target, &new_plt.target, 2183 2189 sizeof(void *)); 2184 2190 } 2185 2191
+2
include/net/xdp_sock.h
··· 188 188 { 189 189 if (!compl) 190 190 return; 191 + if (!compl->tx_timestamp) 192 + return; 191 193 192 194 *compl->tx_timestamp = ops->tmo_fill_timestamp(priv); 193 195 }
+18 -7
kernel/bpf/arena.c
··· 38 38 39 39 /* number of bytes addressable by LDX/STX insn with 16-bit 'off' field */ 40 40 #define GUARD_SZ (1ull << sizeof(((struct bpf_insn *)0)->off) * 8) 41 - #define KERN_VM_SZ ((1ull << 32) + GUARD_SZ) 41 + #define KERN_VM_SZ (SZ_4G + GUARD_SZ) 42 42 43 43 struct bpf_arena { 44 44 struct bpf_map map; ··· 110 110 return ERR_PTR(-EINVAL); 111 111 112 112 vm_range = (u64)attr->max_entries * PAGE_SIZE; 113 - if (vm_range > (1ull << 32)) 113 + if (vm_range > SZ_4G) 114 114 return ERR_PTR(-E2BIG); 115 115 116 116 if ((attr->map_extra >> 32) != ((attr->map_extra + vm_range - 1) >> 32)) ··· 301 301 302 302 if (pgoff) 303 303 return -EINVAL; 304 - if (len > (1ull << 32)) 304 + if (len > SZ_4G) 305 305 return -E2BIG; 306 306 307 307 /* if user_vm_start was specified at arena creation time */ ··· 322 322 if (WARN_ON_ONCE(arena->user_vm_start)) 323 323 /* checks at map creation time should prevent this */ 324 324 return -EFAULT; 325 - return round_up(ret, 1ull << 32); 325 + return round_up(ret, SZ_4G); 326 326 } 327 327 328 328 static int arena_map_mmap(struct bpf_map *map, struct vm_area_struct *vma) ··· 346 346 return -EBUSY; 347 347 348 348 /* Earlier checks should prevent this */ 349 - if (WARN_ON_ONCE(vma->vm_end - vma->vm_start > (1ull << 32) || vma->vm_pgoff)) 349 + if (WARN_ON_ONCE(vma->vm_end - vma->vm_start > SZ_4G || vma->vm_pgoff)) 350 350 return -EFAULT; 351 351 352 352 if (remember_vma(arena, vma)) ··· 420 420 if (uaddr & ~PAGE_MASK) 421 421 return 0; 422 422 pgoff = compute_pgoff(arena, uaddr); 423 - if (pgoff + page_cnt > page_cnt_max) 423 + if (pgoff > page_cnt_max - page_cnt) 424 424 /* requested address will be outside of user VMA */ 425 425 return 0; 426 426 } ··· 447 447 goto out; 448 448 449 449 uaddr32 = (u32)(arena->user_vm_start + pgoff * PAGE_SIZE); 450 - /* Earlier checks make sure that uaddr32 + page_cnt * PAGE_SIZE will not overflow 32-bit */ 450 + /* Earlier checks made sure that uaddr32 + page_cnt * PAGE_SIZE - 1 451 + * will not overflow 32-bit. Lower 32-bit need to represent 452 + * contiguous user address range. 453 + * Map these pages at kern_vm_start base. 454 + * kern_vm_start + uaddr32 + page_cnt * PAGE_SIZE - 1 can overflow 455 + * lower 32-bit and it's ok. 456 + */ 451 457 ret = vm_area_map_pages(arena->kern_vm, kern_vm_start + uaddr32, 452 458 kern_vm_start + uaddr32 + page_cnt * PAGE_SIZE, pages); 453 459 if (ret) { ··· 516 510 if (!page) 517 511 continue; 518 512 if (page_cnt == 1 && page_mapped(page)) /* mapped by some user process */ 513 + /* Optimization for the common case of page_cnt==1: 514 + * If page wasn't mapped into some user vma there 515 + * is no need to call zap_pages which is slow. When 516 + * page_cnt is big it's faster to do the batched zap. 517 + */ 519 518 zap_pages(arena, full_uaddr, 1); 520 519 vm_area_unmap_pages(arena->kern_vm, kaddr, kaddr + PAGE_SIZE); 521 520 __free_page(page);
+19 -3
kernel/bpf/verifier.c
··· 5682 5682 return reg->type == PTR_TO_FLOW_KEYS; 5683 5683 } 5684 5684 5685 + static bool is_arena_reg(struct bpf_verifier_env *env, int regno) 5686 + { 5687 + const struct bpf_reg_state *reg = reg_state(env, regno); 5688 + 5689 + return reg->type == PTR_TO_ARENA; 5690 + } 5691 + 5685 5692 static u32 *reg2btf_ids[__BPF_REG_TYPE_MAX] = { 5686 5693 #ifdef CONFIG_NET 5687 5694 [PTR_TO_SOCKET] = &btf_sock_ids[BTF_SOCK_TYPE_SOCK], ··· 7026 7019 if (is_ctx_reg(env, insn->dst_reg) || 7027 7020 is_pkt_reg(env, insn->dst_reg) || 7028 7021 is_flow_key_reg(env, insn->dst_reg) || 7029 - is_sk_reg(env, insn->dst_reg)) { 7022 + is_sk_reg(env, insn->dst_reg) || 7023 + is_arena_reg(env, insn->dst_reg)) { 7030 7024 verbose(env, "BPF_ATOMIC stores into R%d %s is not allowed\n", 7031 7025 insn->dst_reg, 7032 7026 reg_type_str(env, reg_state(env, insn->dst_reg)->type)); ··· 14022 14014 verbose(env, "addr_space_cast insn can only convert between address space 1 and 0\n"); 14023 14015 return -EINVAL; 14024 14016 } 14017 + if (!env->prog->aux->arena) { 14018 + verbose(env, "addr_space_cast insn can only be used in a program that has an associated arena\n"); 14019 + return -EINVAL; 14020 + } 14025 14021 } else { 14026 14022 if ((insn->off != 0 && insn->off != 8 && insn->off != 16 && 14027 14023 insn->off != 32) || insn->imm) { ··· 14058 14046 if (insn->imm) { 14059 14047 /* off == BPF_ADDR_SPACE_CAST */ 14060 14048 mark_reg_unknown(env, regs, insn->dst_reg); 14061 - if (insn->imm == 1) /* cast from as(1) to as(0) */ 14049 + if (insn->imm == 1) { /* cast from as(1) to as(0) */ 14062 14050 dst_reg->type = PTR_TO_ARENA; 14051 + /* PTR_TO_ARENA is 32-bit */ 14052 + dst_reg->subreg_def = env->insn_idx + 1; 14053 + } 14063 14054 } else if (insn->off == 0) { 14064 14055 /* case: R1 = R2 14065 14056 * copy register state to dest reg ··· 19616 19601 (((struct bpf_map *)env->prog->aux->arena)->map_flags & BPF_F_NO_USER_CONV)) { 19617 19602 /* convert to 32-bit mov that clears upper 32-bit */ 19618 19603 insn->code = BPF_ALU | BPF_MOV | BPF_X; 19619 - /* clear off, so it's a normal 'wX = wY' from JIT pov */ 19604 + /* clear off and imm, so it's a normal 'wX = wY' from JIT pov */ 19620 19605 insn->off = 0; 19606 + insn->imm = 0; 19621 19607 } /* cast from as(0) to as(1) should be handled by JIT */ 19622 19608 goto next_insn; 19623 19609 }
+2 -2
scripts/bpf_doc.py
··· 414 414 version = version.stdout.decode().rstrip() 415 415 except: 416 416 try: 417 - version = subprocess.run(['make', 'kernelversion'], cwd=linuxRoot, 418 - capture_output=True, check=True) 417 + version = subprocess.run(['make', '-s', '--no-print-directory', 'kernelversion'], 418 + cwd=linuxRoot, capture_output=True, check=True) 419 419 version = version.stdout.decode().rstrip() 420 420 except: 421 421 return 'Linux'
+1 -1
tools/bpf/bpftool/gen.c
··· 121 121 int i, n; 122 122 123 123 /* recognize hard coded LLVM section name */ 124 - if (strcmp(sec_name, ".arena.1") == 0) { 124 + if (strcmp(sec_name, ".addr_space.1") == 0) { 125 125 /* this is the name to use in skeleton */ 126 126 snprintf(buf, buf_sz, "arena"); 127 127 return true;
+7 -3
tools/lib/bpf/libbpf.c
··· 498 498 #define KSYMS_SEC ".ksyms" 499 499 #define STRUCT_OPS_SEC ".struct_ops" 500 500 #define STRUCT_OPS_LINK_SEC ".struct_ops.link" 501 - #define ARENA_SEC ".arena.1" 501 + #define ARENA_SEC ".addr_space.1" 502 502 503 503 enum libbpf_map_type { 504 504 LIBBPF_MAP_UNSPEC, ··· 1649 1649 { 1650 1650 return syscall(__NR_memfd_create, name, flags); 1651 1651 } 1652 + 1653 + #ifndef MFD_CLOEXEC 1654 + #define MFD_CLOEXEC 0x0001U 1655 + #endif 1652 1656 1653 1657 static int create_placeholder_fd(void) 1654 1658 { ··· 5356 5352 goto err_out; 5357 5353 } 5358 5354 if (map->def.type == BPF_MAP_TYPE_ARENA) { 5359 - map->mmaped = mmap((void *)map->map_extra, bpf_map_mmap_sz(map), 5360 - PROT_READ | PROT_WRITE, 5355 + map->mmaped = mmap((void *)(long)map->map_extra, 5356 + bpf_map_mmap_sz(map), PROT_READ | PROT_WRITE, 5361 5357 map->map_extra ? MAP_SHARED | MAP_FIXED : MAP_SHARED, 5362 5358 map->fd, 0); 5363 5359 if (map->mmaped == MAP_FAILED) {
+1 -1
tools/testing/selftests/bpf/bpf_arena_common.h
··· 32 32 */ 33 33 #endif 34 34 35 - #if defined(__BPF_FEATURE_ARENA_CAST) && !defined(BPF_ARENA_FORCE_ASM) 35 + #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) && !defined(BPF_ARENA_FORCE_ASM) 36 36 #define __arena __attribute__((address_space(1))) 37 37 #define cast_kern(ptr) /* nop for bpf prog. emitted by LLVM */ 38 38 #define cast_user(ptr) /* nop for bpf prog. emitted by LLVM */
+5 -3
tools/testing/selftests/bpf/prog_tests/arena_htab.c
··· 3 3 #include <test_progs.h> 4 4 #include <sys/mman.h> 5 5 #include <network_helpers.h> 6 - 6 + #include <sys/user.h> 7 + #ifndef PAGE_SIZE /* on some archs it comes in sys/user.h */ 8 + #include <unistd.h> 9 + #define PAGE_SIZE getpagesize() 10 + #endif 7 11 #include "arena_htab_asm.skel.h" 8 12 #include "arena_htab.skel.h" 9 - 10 - #define PAGE_SIZE 4096 11 13 12 14 #include "bpf_arena_htab.h" 13 15
+5 -2
tools/testing/selftests/bpf/prog_tests/arena_list.c
··· 3 3 #include <test_progs.h> 4 4 #include <sys/mman.h> 5 5 #include <network_helpers.h> 6 - 7 - #define PAGE_SIZE 4096 6 + #include <sys/user.h> 7 + #ifndef PAGE_SIZE /* on some archs it comes in sys/user.h */ 8 + #include <unistd.h> 9 + #define PAGE_SIZE getpagesize() 10 + #endif 8 11 9 12 #include "bpf_arena_list.h" 10 13 #include "arena_list.skel.h"
+2
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 5 5 #include "cap_helpers.h" 6 6 #include "verifier_and.skel.h" 7 7 #include "verifier_arena.skel.h" 8 + #include "verifier_arena_large.skel.h" 8 9 #include "verifier_array_access.skel.h" 9 10 #include "verifier_basic_stack.skel.h" 10 11 #include "verifier_bitfield_write.skel.h" ··· 121 120 122 121 void test_verifier_and(void) { RUN(verifier_and); } 123 122 void test_verifier_arena(void) { RUN(verifier_arena); } 123 + void test_verifier_arena_large(void) { RUN(verifier_arena_large); } 124 124 void test_verifier_basic_stack(void) { RUN(verifier_basic_stack); } 125 125 void test_verifier_bitfield_write(void) { RUN(verifier_bitfield_write); } 126 126 void test_verifier_bounds(void) { RUN(verifier_bounds); }
+1 -1
tools/testing/selftests/bpf/progs/arena_htab.c
··· 22 22 SEC("syscall") 23 23 int arena_htab_llvm(void *ctx) 24 24 { 25 - #if defined(__BPF_FEATURE_ARENA_CAST) || defined(BPF_ARENA_FORCE_ASM) 25 + #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) || defined(BPF_ARENA_FORCE_ASM) 26 26 struct htab __arena *htab; 27 27 __u64 i; 28 28
+5 -5
tools/testing/selftests/bpf/progs/arena_list.c
··· 30 30 int cnt; 31 31 bool skip = false; 32 32 33 - #ifdef __BPF_FEATURE_ARENA_CAST 33 + #ifdef __BPF_FEATURE_ADDR_SPACE_CAST 34 34 long __arena arena_sum; 35 35 int __arena test_val = 1; 36 36 struct arena_list_head __arena global_head; 37 37 #else 38 - long arena_sum SEC(".arena.1"); 39 - int test_val SEC(".arena.1"); 38 + long arena_sum SEC(".addr_space.1"); 39 + int test_val SEC(".addr_space.1"); 40 40 #endif 41 41 42 42 int zero; ··· 44 44 SEC("syscall") 45 45 int arena_list_add(void *ctx) 46 46 { 47 - #ifdef __BPF_FEATURE_ARENA_CAST 47 + #ifdef __BPF_FEATURE_ADDR_SPACE_CAST 48 48 __u64 i; 49 49 50 50 list_head = &global_head; ··· 66 66 SEC("syscall") 67 67 int arena_list_del(void *ctx) 68 68 { 69 - #ifdef __BPF_FEATURE_ARENA_CAST 69 + #ifdef __BPF_FEATURE_ADDR_SPACE_CAST 70 70 struct elem __arena *n; 71 71 int sum = 0; 72 72
+7 -3
tools/testing/selftests/bpf/progs/verifier_arena.c
··· 12 12 __uint(type, BPF_MAP_TYPE_ARENA); 13 13 __uint(map_flags, BPF_F_MMAPABLE); 14 14 __uint(max_entries, 2); /* arena of two pages close to 32-bit boundary*/ 15 - __ulong(map_extra, (1ull << 44) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */ 15 + #ifdef __TARGET_ARCH_arm64 16 + __ulong(map_extra, (1ull << 32) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */ 17 + #else 18 + __ulong(map_extra, (1ull << 44) | (~0u - __PAGE_SIZE * 2 + 1)); /* start of mmap() region */ 19 + #endif 16 20 } arena SEC(".maps"); 17 21 18 22 SEC("syscall") 19 23 __success __retval(0) 20 24 int basic_alloc1(void *ctx) 21 25 { 22 - #if defined(__BPF_FEATURE_ARENA_CAST) 26 + #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) 23 27 volatile int __arena *page1, *page2, *no_page, *page3; 24 28 25 29 page1 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0); ··· 62 58 __success __retval(0) 63 59 int basic_alloc2(void *ctx) 64 60 { 65 - #if defined(__BPF_FEATURE_ARENA_CAST) 61 + #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) 66 62 volatile char __arena *page1, *page2, *page3, *page4; 67 63 68 64 page1 = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0);
+68
tools/testing/selftests/bpf/progs/verifier_arena_large.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include <vmlinux.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + #include "bpf_misc.h" 8 + #include "bpf_experimental.h" 9 + #include "bpf_arena_common.h" 10 + 11 + #define ARENA_SIZE (1ull << 32) 12 + 13 + struct { 14 + __uint(type, BPF_MAP_TYPE_ARENA); 15 + __uint(map_flags, BPF_F_MMAPABLE); 16 + __uint(max_entries, ARENA_SIZE / PAGE_SIZE); 17 + } arena SEC(".maps"); 18 + 19 + SEC("syscall") 20 + __success __retval(0) 21 + int big_alloc1(void *ctx) 22 + { 23 + #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) 24 + volatile char __arena *page1, *page2, *no_page, *page3; 25 + void __arena *base; 26 + 27 + page1 = base = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0); 28 + if (!page1) 29 + return 1; 30 + *page1 = 1; 31 + page2 = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE - PAGE_SIZE, 32 + 1, NUMA_NO_NODE, 0); 33 + if (!page2) 34 + return 2; 35 + *page2 = 2; 36 + no_page = bpf_arena_alloc_pages(&arena, base + ARENA_SIZE, 37 + 1, NUMA_NO_NODE, 0); 38 + if (no_page) 39 + return 3; 40 + if (*page1 != 1) 41 + return 4; 42 + if (*page2 != 2) 43 + return 5; 44 + bpf_arena_free_pages(&arena, (void __arena *)page1, 1); 45 + if (*page2 != 2) 46 + return 6; 47 + if (*page1 != 0) /* use-after-free should return 0 */ 48 + return 7; 49 + page3 = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0); 50 + if (!page3) 51 + return 8; 52 + *page3 = 3; 53 + if (page1 != page3) 54 + return 9; 55 + if (*page2 != 2) 56 + return 10; 57 + if (*(page1 + PAGE_SIZE) != 0) 58 + return 11; 59 + if (*(page1 - PAGE_SIZE) != 0) 60 + return 12; 61 + if (*(page2 + PAGE_SIZE) != 0) 62 + return 13; 63 + if (*(page2 - PAGE_SIZE) != 0) 64 + return 14; 65 + #endif 66 + return 0; 67 + } 68 + char _license[] SEC("license") = "GPL";