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
13struct {
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
19SEC("syscall")
20__success __retval(0)
21int 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}
68char _license[] SEC("license") = "GPL";
69