1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3 4 #define BPF_NO_KFUNC_PROTOTYPES 5 #include <vmlinux.h> 6 #include <bpf/bpf_helpers.h> 7 #include <bpf/bpf_tracing.h> 8 #include "bpf_experimental.h" 9 #include "bpf_arena_common.h" 10 #include "bpf_misc.h" 11 12 #define ARENA_PAGES (1UL<< (32 - __builtin_ffs(__PAGE_SIZE) + 1)) 13 #define GLOBAL_PAGES (16) 14 15 struct { 16 __uint(type, BPF_MAP_TYPE_ARENA); 17 __uint(map_flags, BPF_F_MMAPABLE); 18 __uint(max_entries, ARENA_PAGES); 19 #ifdef __TARGET_ARCH_arm64 20 __ulong(map_extra, (1ull << 32) | (~0u - __PAGE_SIZE * ARENA_PAGES + 1)); 21 #else 22 __ulong(map_extra, (1ull << 44) | (~0u - __PAGE_SIZE * ARENA_PAGES + 1)); 23 #endif 24 } arena SEC(".maps"); 25 26 /* 27 * Global data, to be placed at the end of the arena. 28 */ 29 volatile char __arena global_data[GLOBAL_PAGES][PAGE_SIZE]; 30 31 SEC("syscall") 32 __success __retval(0) 33 int check_reserve1(void *ctx) 34 { 35 #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) 36 const u8 magic = 0x5a; 37 __u8 __arena *guard, *globals; 38 volatile char __arena *ptr; 39 int i; 40 int ret; 41 42 guard = (void __arena *)arena_base(&arena); 43 globals = (void __arena *)(arena_base(&arena) + (ARENA_PAGES - GLOBAL_PAGES) * PAGE_SIZE); 44 45 /* Reserve the region we've offset the globals by. */ 46 ret = bpf_arena_reserve_pages(&arena, guard, ARENA_PAGES - GLOBAL_PAGES); 47 if (ret) 48 return 1; 49 50 /* Make sure the globals are in the expected offset. */ 51 ret = bpf_arena_reserve_pages(&arena, globals, 1); 52 if (!ret) 53 return 2; 54 55 /* Verify globals are properly mapped in by libbpf. */ 56 for (i = 0; i < GLOBAL_PAGES; i++) { 57 ptr = &global_data[i][PAGE_SIZE / 2]; 58 59 *ptr = magic; 60 if (*ptr != magic) 61 return i + 3; 62 } 63 #endif 64 return 0; 65 } 66 67 /* 68 * Relocation check by reading directly into the global data w/o using symbols. 69 */ 70 SEC("syscall") 71 __success __retval(0) 72 int check_relocation(void *ctx) 73 { 74 #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) 75 const u8 magic = 0xfa; 76 u8 __arena *ptr; 77 78 global_data[GLOBAL_PAGES - 1][PAGE_SIZE / 2] = magic; 79 ptr = (u8 __arena *)((u64)(ARENA_PAGES * PAGE_SIZE - PAGE_SIZE / 2)); 80 if (*ptr != magic) 81 return 1; 82 83 #endif 84 return 0; 85 } 86 87 char _license[] SEC("license") = "GPL"; 88