// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ #define BPF_NO_KFUNC_PROTOTYPES #include <vmlinux.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h> #include "bpf_experimental.h" #include "bpf_arena_common.h" #include "bpf_misc.h" #define ARENA_PAGES (1UL<< (32 - __builtin_ffs(__PAGE_SIZE) + 1)) #define GLOBAL_PAGES (16) struct { __uint(type, BPF_MAP_TYPE_ARENA); __uint(map_flags, BPF_F_MMAPABLE); __uint(max_entries, ARENA_PAGES); #ifdef __TARGET_ARCH_arm64 __ulong(map_extra, (1ull << 32) | (~0u - __PAGE_SIZE * ARENA_PAGES + 1)); #else __ulong(map_extra, (1ull << 44) | (~0u - __PAGE_SIZE * ARENA_PAGES + 1)); #endif } arena SEC(".maps"); /* * Global data, to be placed at the end of the arena. */ volatile char __arena global_data[GLOBAL_PAGES][PAGE_SIZE]; SEC("syscall") __success __retval(0) int check_reserve1(void *ctx) { #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) const u8 magic = 0x5a; __u8 __arena *guard, *globals; volatile char __arena *ptr; int i; int ret; guard = (void __arena *)arena_base(&arena); globals = (void __arena *)(arena_base(&arena) + (ARENA_PAGES - GLOBAL_PAGES) * PAGE_SIZE); /* Reserve the region we've offset the globals by. */ ret = bpf_arena_reserve_pages(&arena, guard, ARENA_PAGES - GLOBAL_PAGES); if (ret) return 1; /* Make sure the globals are in the expected offset. */ ret = bpf_arena_reserve_pages(&arena, globals, 1); if (!ret) return 2; /* Verify globals are properly mapped in by libbpf. */ for (i = 0; i < GLOBAL_PAGES; i++) { ptr = &global_data[i][PAGE_SIZE / 2]; *ptr = magic; if (*ptr != magic) return i + 3; } #endif return 0; } /* * Relocation check by reading directly into the global data w/o using symbols. */ SEC("syscall") __success __retval(0) int check_relocation(void *ctx) { #if defined(__BPF_FEATURE_ADDR_SPACE_CAST) const u8 magic = 0xfa; u8 __arena *ptr; global_data[GLOBAL_PAGES - 1][PAGE_SIZE / 2] = magic; ptr = (u8 __arena *)((u64)(ARENA_PAGES * PAGE_SIZE - PAGE_SIZE / 2)); if (*ptr != magic) return 1; #endif return 0; } char _license[] SEC("license") = "GPL";