1 // SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause 2 /* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ 3 #pragma once 4 5 #ifdef __BPF__ 6 7 #include <vmlinux.h> 8 9 #include <bpf_arena_common.h> 10 #include <bpf_arena_spin_lock.h> 11 12 #include <asm-generic/errno.h> 13 14 #ifndef __BPF_FEATURE_ADDR_SPACE_CAST 15 #error "Arena allocators require bpf_addr_space_cast feature" 16 #endif 17 18 #define arena_stdout(fmt, ...) bpf_stream_printk(1, (fmt), ##__VA_ARGS__) 19 #define arena_stderr(fmt, ...) bpf_stream_printk(2, (fmt), ##__VA_ARGS__) 20 21 #ifndef __maybe_unused 22 #define __maybe_unused __attribute__((__unused__)) 23 #endif 24 25 #define private(name) SEC(".data." #name) __hidden __attribute__((aligned(8))) 26 27 #define ARENA_PAGES (1UL << (32 - __builtin_ffs(__PAGE_SIZE) + 1)) 28 29 struct { 30 __uint(type, BPF_MAP_TYPE_ARENA); 31 __uint(map_flags, BPF_F_MMAPABLE); 32 __uint(max_entries, ARENA_PAGES); /* number of pages */ 33 #if defined(__TARGET_ARCH_arm64) || defined(__aarch64__) 34 __ulong(map_extra, (1ull << 32)); /* start of mmap() region */ 35 #else 36 __ulong(map_extra, (1ull << 44)); /* start of mmap() region */ 37 #endif 38 } arena __weak SEC(".maps"); 39 40 /* 41 * This is a variable used to aid verification. The may_goto directive 42 * permits open-coded for loops, but requires that the index variable is 43 * imprecise. To force the variable to be imprecise, initialize it with 44 * the opaque volatile variable 0 instead of the constant 0. 45 */ 46 volatile u32 zero __weak; 47 extern volatile u64 asan_violated; 48 49 int arena_fls(__u64 word); 50 51 void __arena *arena_malloc(size_t size); 52 void arena_free(void __arena *ptr); 53 54 /* 55 * The verifier associates arenas with programs by checking LD.IMM 56 * instruction operands for an arena and populating the program state 57 * with the first instance it finds. This requires accessing our global 58 * arena variable, but subprogs do not necessarily do so while still 59 * using pointers from that arena. Insert an LD.IMM instruction to 60 * access the arena and help the verifier. 61 */ 62 #define arena_subprog_init() do { asm volatile ("" :: "r"(&arena)); } while (0) 63 64 #else /* ! __BPF__ */ 65 66 #include <stdint.h> 67 68 #define __arena 69 70 typedef uint8_t u8; 71 typedef uint16_t u16; 72 typedef uint32_t u32; 73 typedef uint64_t u64; 74 typedef int8_t s8; 75 typedef int16_t s16; 76 typedef int32_t s32; 77 typedef int64_t s64; 78 79 /* Dummy "definition" for userspace. */ 80 #define arena_spinlock_t int 81 82 #endif /* __BPF__ */ 83 84 struct arena_get_info_args { 85 void __arena *arena_base; 86 }; 87 88 struct arena_alloc_reserve_args { 89 u64 nr_pages; 90 }; 91 92 /* Reasonable default number of pages reserved by arena_alloc_reserve. */ 93 #define ARENA_RESERVE_PAGES_DFL (8) 94