@@ -21,6 +21,37 @@ struct {
2121#endif
2222} arena SEC (".maps" );
2323
24+ SEC ("socket" )
25+ __success __retval (0 )
26+ int basic_alloc1_nosleep (void * ctx )
27+ {
28+ #if defined(__BPF_FEATURE_ADDR_SPACE_CAST )
29+ volatile int __arena * page1 , * page2 , * no_page ;
30+
31+ page1 = bpf_arena_alloc_pages (& arena , NULL , 1 , NUMA_NO_NODE , 0 );
32+ if (!page1 )
33+ return 1 ;
34+ * page1 = 1 ;
35+ page2 = bpf_arena_alloc_pages (& arena , NULL , 1 , NUMA_NO_NODE , 0 );
36+ if (!page2 )
37+ return 2 ;
38+ * page2 = 2 ;
39+ no_page = bpf_arena_alloc_pages (& arena , NULL , 1 , NUMA_NO_NODE , 0 );
40+ if (no_page )
41+ return 3 ;
42+ if (* page1 != 1 )
43+ return 4 ;
44+ if (* page2 != 2 )
45+ return 5 ;
46+ bpf_arena_free_pages (& arena , (void __arena * )page2 , 1 );
47+ if (* page1 != 1 )
48+ return 6 ;
49+ if (* page2 != 0 && * page2 != 2 ) /* use-after-free should return 0 or the stored value */
50+ return 7 ;
51+ #endif
52+ return 0 ;
53+ }
54+
2455SEC ("syscall" )
2556__success __retval (0 )
2657int basic_alloc1 (void * ctx )
@@ -60,6 +91,44 @@ int basic_alloc1(void *ctx)
6091 return 0 ;
6192}
6293
94+ SEC ("socket" )
95+ __success __retval (0 )
96+ int basic_alloc2_nosleep (void * ctx )
97+ {
98+ #if defined(__BPF_FEATURE_ADDR_SPACE_CAST )
99+ volatile char __arena * page1 , * page2 , * page3 , * page4 ;
100+
101+ page1 = bpf_arena_alloc_pages (& arena , NULL , 2 , NUMA_NO_NODE , 0 );
102+ if (!page1 )
103+ return 1 ;
104+ page2 = page1 + __PAGE_SIZE ;
105+ page3 = page1 + __PAGE_SIZE * 2 ;
106+ page4 = page1 - __PAGE_SIZE ;
107+ * page1 = 1 ;
108+ * page2 = 2 ;
109+ * page3 = 3 ;
110+ * page4 = 4 ;
111+ if (* page1 != 1 )
112+ return 1 ;
113+ if (* page2 != 2 )
114+ return 2 ;
115+ if (* page3 != 0 )
116+ return 3 ;
117+ if (* page4 != 0 )
118+ return 4 ;
119+ bpf_arena_free_pages (& arena , (void __arena * )page1 , 2 );
120+ if (* page1 != 0 && * page1 != 1 )
121+ return 5 ;
122+ if (* page2 != 0 && * page2 != 2 )
123+ return 6 ;
124+ if (* page3 != 0 )
125+ return 7 ;
126+ if (* page4 != 0 )
127+ return 8 ;
128+ #endif
129+ return 0 ;
130+ }
131+
63132SEC ("syscall" )
64133__success __retval (0 )
65134int basic_alloc2 (void * ctx )
@@ -102,6 +171,19 @@ struct bpf_arena___l {
102171 struct bpf_map map ;
103172} __attribute__((preserve_access_index ));
104173
174+ SEC ("socket" )
175+ __success __retval (0 ) __log_level (2 )
176+ int basic_alloc3_nosleep (void * ctx )
177+ {
178+ struct bpf_arena___l * ar = (struct bpf_arena___l * )& arena ;
179+ volatile char __arena * pages ;
180+
181+ pages = bpf_arena_alloc_pages (& ar -> map , NULL , ar -> map .max_entries , NUMA_NO_NODE , 0 );
182+ if (!pages )
183+ return 1 ;
184+ return 0 ;
185+ }
186+
105187SEC ("syscall" )
106188__success __retval (0 ) __log_level (2 )
107189int basic_alloc3 (void * ctx )
@@ -115,6 +197,38 @@ int basic_alloc3(void *ctx)
115197 return 0 ;
116198}
117199
200+ SEC ("socket" )
201+ __success __retval (0 )
202+ int basic_reserve1_nosleep (void * ctx )
203+ {
204+ #if defined(__BPF_FEATURE_ADDR_SPACE_CAST )
205+ char __arena * page ;
206+ int ret ;
207+
208+ page = bpf_arena_alloc_pages (& arena , NULL , 1 , NUMA_NO_NODE , 0 );
209+ if (!page )
210+ return 1 ;
211+
212+ page += __PAGE_SIZE ;
213+
214+ /* Reserve the second page */
215+ ret = bpf_arena_reserve_pages (& arena , page , 1 );
216+ if (ret )
217+ return 2 ;
218+
219+ /* Try to explicitly allocate the reserved page. */
220+ page = bpf_arena_alloc_pages (& arena , page , 1 , NUMA_NO_NODE , 0 );
221+ if (page )
222+ return 3 ;
223+
224+ /* Try to implicitly allocate the page (since there's only 2 of them). */
225+ page = bpf_arena_alloc_pages (& arena , NULL , 1 , NUMA_NO_NODE , 0 );
226+ if (page )
227+ return 4 ;
228+ #endif
229+ return 0 ;
230+ }
231+
118232SEC ("syscall" )
119233__success __retval (0 )
120234int basic_reserve1 (void * ctx )
@@ -147,6 +261,26 @@ int basic_reserve1(void *ctx)
147261 return 0 ;
148262}
149263
264+ SEC ("socket" )
265+ __success __retval (0 )
266+ int basic_reserve2_nosleep (void * ctx )
267+ {
268+ #if defined(__BPF_FEATURE_ADDR_SPACE_CAST )
269+ char __arena * page ;
270+ int ret ;
271+
272+ page = arena_base (& arena );
273+ ret = bpf_arena_reserve_pages (& arena , page , 1 );
274+ if (ret )
275+ return 1 ;
276+
277+ page = bpf_arena_alloc_pages (& arena , page , 1 , NUMA_NO_NODE , 0 );
278+ if ((u64 )page )
279+ return 2 ;
280+ #endif
281+ return 0 ;
282+ }
283+
150284SEC ("syscall" )
151285__success __retval (0 )
152286int basic_reserve2 (void * ctx )
@@ -168,6 +302,27 @@ int basic_reserve2(void *ctx)
168302}
169303
170304/* Reserve the same page twice, should return -EBUSY. */
305+ SEC ("socket" )
306+ __success __retval (0 )
307+ int reserve_twice_nosleep (void * ctx )
308+ {
309+ #if defined(__BPF_FEATURE_ADDR_SPACE_CAST )
310+ char __arena * page ;
311+ int ret ;
312+
313+ page = arena_base (& arena );
314+
315+ ret = bpf_arena_reserve_pages (& arena , page , 1 );
316+ if (ret )
317+ return 1 ;
318+
319+ ret = bpf_arena_reserve_pages (& arena , page , 1 );
320+ if (ret != - EBUSY )
321+ return 2 ;
322+ #endif
323+ return 0 ;
324+ }
325+
171326SEC ("syscall" )
172327__success __retval (0 )
173328int reserve_twice (void * ctx )
@@ -190,6 +345,36 @@ int reserve_twice(void *ctx)
190345}
191346
192347/* Try to reserve past the end of the arena. */
348+ SEC ("socket" )
349+ __success __retval (0 )
350+ int reserve_invalid_region_nosleep (void * ctx )
351+ {
352+ #if defined(__BPF_FEATURE_ADDR_SPACE_CAST )
353+ char __arena * page ;
354+ int ret ;
355+
356+ /* Try a NULL pointer. */
357+ ret = bpf_arena_reserve_pages (& arena , NULL , 3 );
358+ if (ret != - EINVAL )
359+ return 1 ;
360+
361+ page = arena_base (& arena );
362+
363+ ret = bpf_arena_reserve_pages (& arena , page , 3 );
364+ if (ret != - EINVAL )
365+ return 2 ;
366+
367+ ret = bpf_arena_reserve_pages (& arena , page , 4096 );
368+ if (ret != - EINVAL )
369+ return 3 ;
370+
371+ ret = bpf_arena_reserve_pages (& arena , page , (1ULL << 32 ) - 1 );
372+ if (ret != - EINVAL )
373+ return 4 ;
374+ #endif
375+ return 0 ;
376+ }
377+
193378SEC ("syscall" )
194379__success __retval (0 )
195380int reserve_invalid_region (void * ctx )
0 commit comments