xref: /linux/tools/testing/selftests/bpf/progs/verifier_arena_globals1.c (revision f17b474e36647c23801ef8fdaf2255ab66dd2973)
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