Skip to content

Commit 09a96c7

Browse files
committed
selftests/bpf: Add tests for arena fault reporting
Add selftests for testing the reporting of arena page faults through BPF streams. Two new bpf programs are added that read and write to an unmapped arena address and the fault reporting is verified in the userspace through streams. Signed-off-by: Puranjay Mohan <[email protected]>
1 parent 1d6e42e commit 09a96c7

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

tools/testing/selftests/bpf/prog_tests/stream.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ struct {
4141
"([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
4242
"|[ \t]+[^\n]+\n)*",
4343
},
44+
{
45+
offsetof(struct stream, progs.stream_arena_read_fault),
46+
"ERROR: Arena READ access at unmapped address 0x.*\n"
47+
"CPU: [0-9]+ UID: 0 PID: [0-9]+ Comm: .*\n"
48+
"Call trace:\n"
49+
"([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
50+
"|[ \t]+[^\n]+\n)*",
51+
},
52+
{
53+
offsetof(struct stream, progs.stream_arena_write_fault),
54+
"ERROR: Arena WRITE access at unmapped address 0x.*\n"
55+
"CPU: [0-9]+ UID: 0 PID: [0-9]+ Comm: .*\n"
56+
"Call trace:\n"
57+
"([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
58+
"|[ \t]+[^\n]+\n)*",
59+
},
4460
};
4561

4662
static int match_regex(const char *pattern, const char *string)
@@ -85,6 +101,14 @@ void test_stream_errors(void)
85101
continue;
86102
}
87103
#endif
104+
#if !defined(__x86_64__) && !defined(__aarch64__)
105+
ASSERT_TRUE(1, "Arena fault reporting unsupported, skip.");
106+
if (i == 2 || i == 3) {
107+
ret = bpf_prog_stream_read(prog_fd, 2, buf, sizeof(buf), &ropts);
108+
ASSERT_EQ(ret, 0, "stream read");
109+
continue;
110+
}
111+
#endif
88112

89113
ret = bpf_prog_stream_read(prog_fd, BPF_STREAM_STDERR, buf, sizeof(buf), &ropts);
90114
ASSERT_GT(ret, 0, "stream read");

tools/testing/selftests/bpf/progs/stream.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
// SPDX-License-Identifier: GPL-2.0
22
/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
3+
#define BPF_NO_KFUNC_PROTOTYPES
34
#include <vmlinux.h>
45
#include <bpf/bpf_tracing.h>
56
#include <bpf/bpf_helpers.h>
67
#include "bpf_misc.h"
78
#include "bpf_experimental.h"
9+
#include "bpf_arena_common.h"
10+
11+
extern int bpf_res_spin_lock(struct bpf_res_spin_lock *lock) __weak __ksym;
12+
extern void bpf_res_spin_unlock(struct bpf_res_spin_lock *lock) __weak __ksym;
813

914
struct arr_elem {
1015
struct bpf_res_spin_lock lock;
@@ -17,6 +22,12 @@ struct {
1722
__type(value, struct arr_elem);
1823
} arrmap SEC(".maps");
1924

25+
struct {
26+
__uint(type, BPF_MAP_TYPE_ARENA);
27+
__uint(map_flags, BPF_F_MMAPABLE);
28+
__uint(max_entries, 1); /* number of pages */
29+
} arena SEC(".maps");
30+
2031
#define ENOSPC 28
2132
#define _STR "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
2233

@@ -76,4 +87,30 @@ int stream_syscall(void *ctx)
7687
return 0;
7788
}
7889

90+
SEC("syscall")
91+
__success __retval(0)
92+
int stream_arena_write_fault(void *ctx)
93+
{
94+
unsigned char __arena *page;
95+
96+
page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
97+
bpf_arena_free_pages(&arena, page, 1);
98+
99+
*(page + 0xbeef) = 1;
100+
101+
return 0;
102+
}
103+
104+
SEC("syscall")
105+
__success __retval(0)
106+
int stream_arena_read_fault(void *ctx)
107+
{
108+
unsigned char __arena *page;
109+
110+
page = bpf_arena_alloc_pages(&arena, NULL, 1, NUMA_NO_NODE, 0);
111+
bpf_arena_free_pages(&arena, page, 1);
112+
113+
return *(page + 0xbeef);
114+
}
115+
79116
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)