Skip to content

Commit b9b23fe

Browse files
etsalAlexei Starovoitov
authored andcommitted
selftests/bpf: Remove __arg_arena from the codebase
Now that BPF __arg_arena has been subsumed by __arena, remove __arg_arena from the codebase. This way the user has one fewer annotation to worry about. To remove __arg_arena we remove the typedefs we were previously using to minimize __arena annotations. This is because __arena now also includes a BTF type tag, which is ignored for non-pointer types. As a result, we cannot capture the whole __arena annotation inside a typedef and need to directly annotate the pointer type when declaring the variable. The extra verbosity is worth it because the use of the __arena tag is intuitive to the programmer and removes the __arg_arena tag that has been a consistent source of confusion for users. The typedefs can be reintroduced later (without __arg_arena) once compilers start supporting BTF type tags for non-pointer types. Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> Link: https://lore.kernel.org/r/20260602004120.17087-5-emil@etsalapatis.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 3e924e9 commit b9b23fe

13 files changed

Lines changed: 84 additions & 101 deletions

File tree

tools/testing/selftests/bpf/bpf_arena_htab.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@ struct htab {
1414
htab_bucket_t *buckets;
1515
int n_buckets;
1616
};
17-
typedef struct htab __arena htab_t;
1817

19-
static inline htab_bucket_t *__select_bucket(htab_t *htab, __u32 hash)
18+
static inline htab_bucket_t *__select_bucket(struct htab __arena *htab, __u32 hash)
2019
{
2120
htab_bucket_t *b = htab->buckets;
2221

2322
cast_kern(b);
2423
return &b[hash & (htab->n_buckets - 1)];
2524
}
2625

27-
static inline arena_list_head_t *select_bucket(htab_t *htab, __u32 hash)
26+
static inline arena_list_head_t *select_bucket(struct htab __arena *htab, __u32 hash)
2827
{
2928
return &__select_bucket(htab, hash)->head;
3029
}
@@ -53,7 +52,7 @@ static int htab_hash(int key)
5352
return key;
5453
}
5554

56-
__weak int htab_lookup_elem(htab_t *htab __arg_arena, int key)
55+
__weak int htab_lookup_elem(struct htab __arena *htab, int key)
5756
{
5857
hashtab_elem_t *l_old;
5958
arena_list_head_t *head;
@@ -66,7 +65,7 @@ __weak int htab_lookup_elem(htab_t *htab __arg_arena, int key)
6665
return 0;
6766
}
6867

69-
__weak int htab_update_elem(htab_t *htab __arg_arena, int key, int value)
68+
__weak int htab_update_elem(struct htab __arena *htab, int key, int value)
7069
{
7170
hashtab_elem_t *l_new = NULL, *l_old;
7271
arena_list_head_t *head;
@@ -90,7 +89,7 @@ __weak int htab_update_elem(htab_t *htab __arg_arena, int key, int value)
9089
return 0;
9190
}
9291

93-
void htab_init(htab_t *htab)
92+
void htab_init(struct htab __arena *htab)
9493
{
9594
void __arena *buckets = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0);
9695

tools/testing/selftests/bpf/bpf_arena_strsearch.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#pragma once
44
#include <bpf_arena_common.h>
55

6-
__noinline int bpf_arena_strlen(const char __arena *s __arg_arena)
6+
__noinline int bpf_arena_strlen(const char __arena *s)
77
{
88
const char __arena *sc;
99

@@ -40,7 +40,7 @@ __noinline int bpf_arena_strlen(const char __arena *s __arg_arena)
4040
*
4141
* An opening bracket without a matching close is matched literally.
4242
*/
43-
__noinline bool glob_match(char const __arena *pat __arg_arena, char const __arena *str __arg_arena)
43+
__noinline bool glob_match(char const __arena *pat, char const __arena *str)
4444
{
4545
/*
4646
* Backtrack to previous * on mismatch and retry starting one

tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
#define cast_kern(ptr) /* nop for bpf prog. emitted by LLVM */
3939
#define cast_user(ptr) /* nop for bpf prog. emitted by LLVM */
4040
#else
41-
#define __arena
41+
#define __arena __attribute__((btf_type_tag("arena")))
4242
#define __arena_global SEC(".addr_space.1")
4343
#define cast_kern(ptr) bpf_addr_space_cast(ptr, 0, 1)
4444
#define cast_user(ptr) bpf_addr_space_cast(ptr, 1, 0)
@@ -54,7 +54,6 @@ void bpf_arena_free_pages(void *map, void __arena *ptr, __u32 page_cnt) __ksym _
5454
#else /* when compiled as user space code */
5555

5656
#define __arena
57-
#define __arg_arena
5857
#define cast_kern(ptr) /* nop for user space */
5958
#define cast_user(ptr) /* nop for user space */
6059
__weak char arena[1];

tools/testing/selftests/bpf/libarena/include/bpf_arena_spin_lock.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@
1616
#define EOPNOTSUPP 95
1717
#define ETIMEDOUT 110
1818

19-
#ifndef __arena
20-
#define __arena __attribute__((address_space(1)))
21-
#endif
22-
2319
extern unsigned long CONFIG_NR_CPUS __kconfig;
2420

2521
/*
@@ -246,7 +242,7 @@ static __always_inline int arena_spin_trylock(arena_spinlock_t __arena *lock)
246242
}
247243

248244
__noinline __weak
249-
int arena_spin_lock_slowpath(arena_spinlock_t __arena __arg_arena *lock, u32 val)
245+
int arena_spin_lock_slowpath(arena_spinlock_t __arena *lock, u32 val)
250246
{
251247
struct arena_mcs_spinlock __arena *prev, *next, *node0, *node;
252248
int ret = -ETIMEDOUT;

tools/testing/selftests/bpf/libarena/include/libarena/asan.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@ extern volatile bool asan_report_once;
2525

2626
#ifdef BPF_ARENA_ASAN
2727

28-
typedef s8 __arena s8a;
29-
3028
static inline
31-
s8a *mem_to_shadow(void __arena __arg_arena *addr)
29+
s8 __arena *mem_to_shadow(void __arena *addr)
3230
{
33-
return (s8a *)(((u32)(u64)addr >> ASAN_SHADOW_SHIFT) +
31+
return (s8 __arena *)(((u32)(u64)addr >> ASAN_SHADOW_SHIFT) +
3432
__asan_shadow_memory_dynamic_address);
3533
}
3634

tools/testing/selftests/bpf/libarena/include/libarena/buddy.h

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@
22
/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
33
#pragma once
44

5-
struct buddy_chunk;
6-
typedef struct buddy_chunk __arena buddy_chunk_t;
7-
8-
struct buddy_header;
9-
typedef struct buddy_header __arena buddy_header_t;
10-
115
enum buddy_consts {
126
/*
137
* Minimum allocation is 1 << BUDDY_MIN_ALLOC_SHIFT.
@@ -68,25 +62,21 @@ struct buddy_chunk {
6862
u8 allocated[BUDDY_CHUNK_ITEMS / 8];
6963
/* Freelists for O(1) allocation. */
7064
u64 freelists[BUDDY_CHUNK_NUM_ORDERS];
71-
buddy_chunk_t *next;
65+
struct buddy_chunk __arena *next;
7266
};
7367

7468
struct buddy {
75-
buddy_chunk_t *first_chunk; /* Pointer to the chunk linked list. */
69+
struct buddy_chunk __arena *first_chunk; /* Pointer to the chunk linked list. */
7670
arena_spinlock_t lock; /* Allocator lock */
7771
u64 vaddr; /* Allocation into reserved vaddr */
7872
};
7973

80-
typedef struct buddy __arena buddy_t;
81-
8274
#ifdef __BPF__
8375

84-
int buddy_init(buddy_t *buddy);
85-
int buddy_destroy(buddy_t *buddy);
86-
int buddy_free_internal(buddy_t *buddy, u64 free);
87-
#define buddy_free(buddy, ptr) buddy_free_internal((buddy), (u64)(ptr))
88-
u64 buddy_alloc_internal(buddy_t *buddy, size_t size);
76+
int buddy_init(struct buddy __arena *buddy);
77+
int buddy_destroy(struct buddy __arena *buddy);
78+
int buddy_free(struct buddy __arena *buddy, void __arena *free);
79+
u64 buddy_alloc_internal(struct buddy __arena *buddy, size_t size);
8980
#define buddy_alloc(alloc, size) ((void __arena *)buddy_alloc_internal((alloc), (size)))
9081

91-
9282
#endif /* __BPF__ */

tools/testing/selftests/bpf/libarena/selftests/st_asan_buddy.bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/* Required for parsing the ASAN call stacks. */
99
#include "test_progs_compat.h"
1010

11-
extern buddy_t buddy;
11+
extern struct buddy __arena buddy;
1212

1313
#ifdef BPF_ARENA_ASAN
1414

@@ -54,7 +54,7 @@ static __always_inline int asan_test_buddy_oob_single(size_t alloc_size)
5454
* Factored out because asan_validate_addr is complex enough to cause
5555
* verification failures if verified with the rest of asan_test_buddy_uaf_single.
5656
*/
57-
__weak int asan_test_buddy_byte(u8 __arena __arg_arena *mem, int i, bool freed)
57+
__weak int asan_test_buddy_byte(u8 __arena *mem, int i, bool freed)
5858
{
5959
int ret;
6060

tools/testing/selftests/bpf/libarena/selftests/st_asan_common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ static inline void print_asan_map_state(void __arena *addr)
99
{
1010
arena_stdout("%s:%d ASAN %p -> (val: %x gran: %x set: [%s])",
1111
__func__, __LINE__, addr,
12-
*(s8a *)(addr), ASAN_GRANULE(addr),
12+
*(s8 __arena *)(addr), ASAN_GRANULE(addr),
1313
asan_shadow_set(addr) ? "yes" : "no");
1414
}
1515

tools/testing/selftests/bpf/libarena/selftests/st_buddy.bpf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <libarena/asan.h>
77
#include <libarena/buddy.h>
88

9-
extern buddy_t buddy;
9+
extern struct buddy __arena buddy;
1010

1111
struct segarr_entry {
1212
u8 __arena *block;

tools/testing/selftests/bpf/libarena/src/asan.bpf.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ volatile bool asan_report_once = false;
110110
* to exit due to a missing implementation. Provide a simple implementation
111111
* just for memset to use it for poisoning/unpoisoning the map.
112112
*/
113-
__weak int asan_memset(s8a __arg_arena *dst, s8 val, size_t size)
113+
__weak int asan_memset(s8 __arena *dst, s8 val, size_t size)
114114
{
115115
size_t i;
116116

@@ -121,9 +121,9 @@ __weak int asan_memset(s8a __arg_arena *dst, s8 val, size_t size)
121121
}
122122

123123
/* Validate a 1-byte access, always within a single byte. */
124-
static __always_inline bool memory_is_poisoned_1(s8a *addr)
124+
static __always_inline bool memory_is_poisoned_1(s8 __arena *addr)
125125
{
126-
s8 shadow_value = *(s8a *)mem_to_shadow(addr);
126+
s8 shadow_value = *(s8 __arena *)mem_to_shadow(addr);
127127

128128
/* Byte is 0, access is valid. */
129129
if (likely(!shadow_value))
@@ -139,7 +139,7 @@ static __always_inline bool memory_is_poisoned_1(s8a *addr)
139139
}
140140

141141
/* Validate a 2- 4-, 8-byte access, shadow spans up to 2 bytes. */
142-
static __always_inline bool memory_is_poisoned_2_4_8(s8a *addr, u64 size)
142+
static __always_inline bool memory_is_poisoned_2_4_8(s8 __arena *addr, u64 size)
143143
{
144144
u64 end = (u64)addr + size - 1;
145145

@@ -148,25 +148,25 @@ static __always_inline bool memory_is_poisoned_2_4_8(s8a *addr, u64 size)
148148
* overflow above ASAN_GRANULE).
149149
*/
150150
if (likely(ASAN_GRANULE(end) >= size - 1))
151-
return memory_is_poisoned_1((s8a *)end);
151+
return memory_is_poisoned_1((s8 __arena *)end);
152152

153153
/*
154154
* Otherwise first byte must be fully unpoisoned, and second byte
155155
* must be unpoisoned up to the end of the accessed region.
156156
*/
157157

158-
return *(s8a *)mem_to_shadow(addr) || memory_is_poisoned_1((s8a *)end);
158+
return *(s8 __arena *)mem_to_shadow(addr) || memory_is_poisoned_1((s8 __arena *)end);
159159
}
160160

161-
__weak bool asan_shadow_set(void __arena __arg_arena *addr)
161+
__weak bool asan_shadow_set(void __arena *addr)
162162
{
163163
return memory_is_poisoned_1(addr);
164164
}
165165

166166
static __always_inline u64 first_nonzero_byte(u64 addr, size_t size)
167167
{
168168
while (size && can_loop) {
169-
if (unlikely(*(s8a *)addr))
169+
if (unlikely(*(s8 __arena *)addr))
170170
return addr;
171171
addr += 1;
172172
size -= 1;
@@ -175,7 +175,7 @@ static __always_inline u64 first_nonzero_byte(u64 addr, size_t size)
175175
return SHADOW_ALL_ZEROES;
176176
}
177177

178-
static __always_inline bool memory_is_poisoned_n(s8a *addr, u64 size)
178+
static __always_inline bool memory_is_poisoned_n(s8 __arena *addr, u64 size)
179179
{
180180
u64 ret;
181181
u64 start;
@@ -189,10 +189,10 @@ static __always_inline bool memory_is_poisoned_n(s8a *addr, u64 size)
189189
if (likely(ret == SHADOW_ALL_ZEROES))
190190
return false;
191191

192-
return unlikely(ret != end || ASAN_GRANULE(addr + size - 1) >= *(s8a *)end);
192+
return unlikely(ret != end || ASAN_GRANULE(addr + size - 1) >= *(s8 __arena *)end);
193193
}
194194

195-
__weak int asan_report(s8a __arg_arena *addr, size_t sz, u32 flags)
195+
__weak int asan_report(s8 __arena *addr, size_t sz, u32 flags)
196196
{
197197
u32 reported = __sync_val_compare_and_swap(&asan_reported, false, true);
198198

@@ -211,7 +211,7 @@ __weak int asan_report(s8a __arg_arena *addr, size_t sz, u32 flags)
211211
return 0;
212212
}
213213

214-
static __always_inline bool check_asan_args(s8a *addr, size_t size,
214+
static __always_inline bool check_asan_args(s8 __arena *addr, size_t size,
215215
bool *result)
216216
{
217217
bool valid = true;
@@ -253,7 +253,7 @@ static __always_inline bool check_asan_args(s8a *addr, size_t size,
253253
static __always_inline bool check_region_inline(intptr_t ptr, size_t size,
254254
u32 flags)
255255
{
256-
s8a *addr = (s8a *)(u64)ptr;
256+
s8 __arena *addr = (s8 __arena *)(u64)ptr;
257257
bool is_poisoned, is_valid;
258258

259259
if (check_asan_args(addr, size, &is_valid)) {
@@ -305,19 +305,19 @@ static __always_inline bool check_region_inline(intptr_t ptr, size_t size,
305305
} \
306306
__hidden void __asan_report_store##size(intptr_t addr) \
307307
{ \
308-
asan_report((s8a *)addr, size, ASAN_WRITE); \
308+
asan_report((s8 __arena *)addr, size, ASAN_WRITE); \
309309
} \
310310
__hidden void __asan_report_store##size##_noabort(intptr_t addr) \
311311
{ \
312-
asan_report((s8a *)addr, size, ASAN_WRITE); \
312+
asan_report((s8 __arena *)addr, size, ASAN_WRITE); \
313313
} \
314314
__hidden void __asan_report_load##size(intptr_t addr) \
315315
{ \
316-
asan_report((s8a *)addr, size, ASAN_READ); \
316+
asan_report((s8 __arena *)addr, size, ASAN_READ); \
317317
} \
318318
__hidden void __asan_report_load##size##_noabort(intptr_t addr) \
319319
{ \
320-
asan_report((s8a *)addr, size, ASAN_READ); \
320+
asan_report((s8 __arena *)addr, size, ASAN_READ); \
321321
}
322322

323323
DEFINE_ASAN_LOAD_STORE(1);
@@ -385,7 +385,7 @@ void *__asan_memset(void *p, int c, size_t n)
385385
*/
386386
__hidden __noasan int asan_poison(void __arena *addr, s8 val, size_t size)
387387
{
388-
s8a *shadow;
388+
s8 __arena *shadow;
389389
size_t len;
390390

391391
/*
@@ -443,7 +443,7 @@ __hidden __noasan int asan_poison(void __arena *addr, s8 val, size_t size)
443443
__hidden __noasan int asan_unpoison(void __arena *addr, size_t size)
444444
{
445445
size_t partial = size & ASAN_GRANULE_MASK;
446-
s8a *shadow;
446+
s8 __arena *shadow;
447447
size_t len;
448448

449449
/*

0 commit comments

Comments
 (0)