1300f19dcSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
2300f19dcSKumar Kartikeya Dwivedi #include <vmlinux.h>
3300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h>
4300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h>
5300f19dcSKumar Kartikeya Dwivedi #include <bpf/bpf_core_read.h>
6300f19dcSKumar Kartikeya Dwivedi #include "bpf_experimental.h"
7300f19dcSKumar Kartikeya Dwivedi
8300f19dcSKumar Kartikeya Dwivedi #include "linked_list.h"
9300f19dcSKumar Kartikeya Dwivedi
10300f19dcSKumar Kartikeya Dwivedi #define INIT \
11300f19dcSKumar Kartikeya Dwivedi struct map_value *v, *v2, *iv, *iv2; \
12300f19dcSKumar Kartikeya Dwivedi struct foo *f, *f1, *f2; \
13300f19dcSKumar Kartikeya Dwivedi struct bar *b; \
14300f19dcSKumar Kartikeya Dwivedi void *map; \
15300f19dcSKumar Kartikeya Dwivedi \
16300f19dcSKumar Kartikeya Dwivedi map = bpf_map_lookup_elem(&map_of_maps, &(int){ 0 }); \
17300f19dcSKumar Kartikeya Dwivedi if (!map) \
18300f19dcSKumar Kartikeya Dwivedi return 0; \
19300f19dcSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &(int){ 0 }); \
20300f19dcSKumar Kartikeya Dwivedi if (!v) \
21300f19dcSKumar Kartikeya Dwivedi return 0; \
22300f19dcSKumar Kartikeya Dwivedi v2 = bpf_map_lookup_elem(&array_map, &(int){ 0 }); \
23300f19dcSKumar Kartikeya Dwivedi if (!v2) \
24300f19dcSKumar Kartikeya Dwivedi return 0; \
25300f19dcSKumar Kartikeya Dwivedi iv = bpf_map_lookup_elem(map, &(int){ 0 }); \
26300f19dcSKumar Kartikeya Dwivedi if (!iv) \
27300f19dcSKumar Kartikeya Dwivedi return 0; \
28300f19dcSKumar Kartikeya Dwivedi iv2 = bpf_map_lookup_elem(map, &(int){ 0 }); \
29300f19dcSKumar Kartikeya Dwivedi if (!iv2) \
30300f19dcSKumar Kartikeya Dwivedi return 0; \
31300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f)); \
32300f19dcSKumar Kartikeya Dwivedi if (!f) \
33300f19dcSKumar Kartikeya Dwivedi return 0; \
34300f19dcSKumar Kartikeya Dwivedi f1 = f; \
35300f19dcSKumar Kartikeya Dwivedi f2 = bpf_obj_new(typeof(*f2)); \
36300f19dcSKumar Kartikeya Dwivedi if (!f2) { \
37300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f1); \
38300f19dcSKumar Kartikeya Dwivedi return 0; \
39300f19dcSKumar Kartikeya Dwivedi } \
40300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b)); \
41300f19dcSKumar Kartikeya Dwivedi if (!b) { \
42300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f2); \
43300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f1); \
44300f19dcSKumar Kartikeya Dwivedi return 0; \
45300f19dcSKumar Kartikeya Dwivedi }
46300f19dcSKumar Kartikeya Dwivedi
47300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, hexpr) \
48300f19dcSKumar Kartikeya Dwivedi SEC("?tc") \
49300f19dcSKumar Kartikeya Dwivedi int test##_missing_lock_##op(void *ctx) \
50300f19dcSKumar Kartikeya Dwivedi { \
51300f19dcSKumar Kartikeya Dwivedi INIT; \
52300f19dcSKumar Kartikeya Dwivedi void (*p)(void *) = (void *)&bpf_list_##op; \
53300f19dcSKumar Kartikeya Dwivedi p(hexpr); \
54300f19dcSKumar Kartikeya Dwivedi return 0; \
55300f19dcSKumar Kartikeya Dwivedi }
56300f19dcSKumar Kartikeya Dwivedi
57300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_front, &f->head);
58300f19dcSKumar Kartikeya Dwivedi CHECK(kptr, pop_back, &f->head);
59300f19dcSKumar Kartikeya Dwivedi
60300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_front, &ghead);
61300f19dcSKumar Kartikeya Dwivedi CHECK(global, pop_back, &ghead);
62300f19dcSKumar Kartikeya Dwivedi
63300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_front, &v->head);
64300f19dcSKumar Kartikeya Dwivedi CHECK(map, pop_back, &v->head);
65300f19dcSKumar Kartikeya Dwivedi
66300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_front, &iv->head);
67300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map, pop_back, &iv->head);
68300f19dcSKumar Kartikeya Dwivedi
69300f19dcSKumar Kartikeya Dwivedi #undef CHECK
70300f19dcSKumar Kartikeya Dwivedi
716a3cd331SDave Marchevsky #define CHECK(test, op, hexpr, nexpr) \
726a3cd331SDave Marchevsky SEC("?tc") \
736a3cd331SDave Marchevsky int test##_missing_lock_##op(void *ctx) \
746a3cd331SDave Marchevsky { \
756a3cd331SDave Marchevsky INIT; \
76de67ba39SDave Marchevsky bpf_list_##op(hexpr, nexpr); \
776a3cd331SDave Marchevsky return 0; \
786a3cd331SDave Marchevsky }
796a3cd331SDave Marchevsky
80de67ba39SDave Marchevsky CHECK(kptr, push_front, &f->head, &b->node);
81de67ba39SDave Marchevsky CHECK(kptr, push_back, &f->head, &b->node);
826a3cd331SDave Marchevsky
83de67ba39SDave Marchevsky CHECK(global, push_front, &ghead, &f->node2);
84de67ba39SDave Marchevsky CHECK(global, push_back, &ghead, &f->node2);
856a3cd331SDave Marchevsky
86de67ba39SDave Marchevsky CHECK(map, push_front, &v->head, &f->node2);
87de67ba39SDave Marchevsky CHECK(map, push_back, &v->head, &f->node2);
886a3cd331SDave Marchevsky
89de67ba39SDave Marchevsky CHECK(inner_map, push_front, &iv->head, &f->node2);
90de67ba39SDave Marchevsky CHECK(inner_map, push_back, &iv->head, &f->node2);
916a3cd331SDave Marchevsky
926a3cd331SDave Marchevsky #undef CHECK
936a3cd331SDave Marchevsky
94300f19dcSKumar Kartikeya Dwivedi #define CHECK(test, op, lexpr, hexpr) \
95300f19dcSKumar Kartikeya Dwivedi SEC("?tc") \
96300f19dcSKumar Kartikeya Dwivedi int test##_incorrect_lock_##op(void *ctx) \
97300f19dcSKumar Kartikeya Dwivedi { \
98300f19dcSKumar Kartikeya Dwivedi INIT; \
99300f19dcSKumar Kartikeya Dwivedi void (*p)(void *) = (void *)&bpf_list_##op; \
100300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(lexpr); \
101300f19dcSKumar Kartikeya Dwivedi p(hexpr); \
102300f19dcSKumar Kartikeya Dwivedi return 0; \
103300f19dcSKumar Kartikeya Dwivedi }
104300f19dcSKumar Kartikeya Dwivedi
105300f19dcSKumar Kartikeya Dwivedi #define CHECK_OP(op) \
106300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_kptr, op, &f1->lock, &f2->head); \
1070b2971a2SAlexei Starovoitov CHECK(kptr_global, op, &f1->lock, &ghead); \
108300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_map, op, &f1->lock, &v->head); \
109300f19dcSKumar Kartikeya Dwivedi CHECK(kptr_inner_map, op, &f1->lock, &iv->head); \
110300f19dcSKumar Kartikeya Dwivedi \
1110b2971a2SAlexei Starovoitov CHECK(global_global, op, &glock2, &ghead); \
1120b2971a2SAlexei Starovoitov CHECK(global_kptr, op, &glock, &f1->head); \
1130b2971a2SAlexei Starovoitov CHECK(global_map, op, &glock, &v->head); \
1140b2971a2SAlexei Starovoitov CHECK(global_inner_map, op, &glock, &iv->head); \
1150b2971a2SAlexei Starovoitov \
116300f19dcSKumar Kartikeya Dwivedi CHECK(map_map, op, &v->lock, &v2->head); \
117300f19dcSKumar Kartikeya Dwivedi CHECK(map_kptr, op, &v->lock, &f2->head); \
1180b2971a2SAlexei Starovoitov CHECK(map_global, op, &v->lock, &ghead); \
119300f19dcSKumar Kartikeya Dwivedi CHECK(map_inner_map, op, &v->lock, &iv->head); \
120300f19dcSKumar Kartikeya Dwivedi \
121300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head); \
122300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_kptr, op, &iv->lock, &f2->head); \
1230b2971a2SAlexei Starovoitov CHECK(inner_map_global, op, &iv->lock, &ghead); \
124300f19dcSKumar Kartikeya Dwivedi CHECK(inner_map_map, op, &iv->lock, &v->head);
125300f19dcSKumar Kartikeya Dwivedi
126300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_front);
127300f19dcSKumar Kartikeya Dwivedi CHECK_OP(pop_back);
128300f19dcSKumar Kartikeya Dwivedi
129300f19dcSKumar Kartikeya Dwivedi #undef CHECK
130300f19dcSKumar Kartikeya Dwivedi #undef CHECK_OP
1316a3cd331SDave Marchevsky
1326a3cd331SDave Marchevsky #define CHECK(test, op, lexpr, hexpr, nexpr) \
1336a3cd331SDave Marchevsky SEC("?tc") \
1346a3cd331SDave Marchevsky int test##_incorrect_lock_##op(void *ctx) \
1356a3cd331SDave Marchevsky { \
1366a3cd331SDave Marchevsky INIT; \
1376a3cd331SDave Marchevsky bpf_spin_lock(lexpr); \
138de67ba39SDave Marchevsky bpf_list_##op(hexpr, nexpr); \
1396a3cd331SDave Marchevsky return 0; \
1406a3cd331SDave Marchevsky }
1416a3cd331SDave Marchevsky
1426a3cd331SDave Marchevsky #define CHECK_OP(op) \
143de67ba39SDave Marchevsky CHECK(kptr_kptr, op, &f1->lock, &f2->head, &b->node); \
144de67ba39SDave Marchevsky CHECK(kptr_global, op, &f1->lock, &ghead, &f->node2); \
145de67ba39SDave Marchevsky CHECK(kptr_map, op, &f1->lock, &v->head, &f->node2); \
146de67ba39SDave Marchevsky CHECK(kptr_inner_map, op, &f1->lock, &iv->head, &f->node2); \
1476a3cd331SDave Marchevsky \
148de67ba39SDave Marchevsky CHECK(global_global, op, &glock2, &ghead, &f->node2); \
149de67ba39SDave Marchevsky CHECK(global_kptr, op, &glock, &f1->head, &b->node); \
150de67ba39SDave Marchevsky CHECK(global_map, op, &glock, &v->head, &f->node2); \
151de67ba39SDave Marchevsky CHECK(global_inner_map, op, &glock, &iv->head, &f->node2); \
1526a3cd331SDave Marchevsky \
153de67ba39SDave Marchevsky CHECK(map_map, op, &v->lock, &v2->head, &f->node2); \
154de67ba39SDave Marchevsky CHECK(map_kptr, op, &v->lock, &f2->head, &b->node); \
155de67ba39SDave Marchevsky CHECK(map_global, op, &v->lock, &ghead, &f->node2); \
156de67ba39SDave Marchevsky CHECK(map_inner_map, op, &v->lock, &iv->head, &f->node2); \
1576a3cd331SDave Marchevsky \
158de67ba39SDave Marchevsky CHECK(inner_map_inner_map, op, &iv->lock, &iv2->head, &f->node2);\
159de67ba39SDave Marchevsky CHECK(inner_map_kptr, op, &iv->lock, &f2->head, &b->node); \
160de67ba39SDave Marchevsky CHECK(inner_map_global, op, &iv->lock, &ghead, &f->node2); \
161de67ba39SDave Marchevsky CHECK(inner_map_map, op, &iv->lock, &v->head, &f->node2);
1626a3cd331SDave Marchevsky
1636a3cd331SDave Marchevsky CHECK_OP(push_front);
1646a3cd331SDave Marchevsky CHECK_OP(push_back);
1656a3cd331SDave Marchevsky
1666a3cd331SDave Marchevsky #undef CHECK
1676a3cd331SDave Marchevsky #undef CHECK_OP
168300f19dcSKumar Kartikeya Dwivedi #undef INIT
169300f19dcSKumar Kartikeya Dwivedi
170300f19dcSKumar Kartikeya Dwivedi SEC("?kprobe/xyz")
map_compat_kprobe(void * ctx)171300f19dcSKumar Kartikeya Dwivedi int map_compat_kprobe(void *ctx)
172300f19dcSKumar Kartikeya Dwivedi {
173300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL);
174300f19dcSKumar Kartikeya Dwivedi return 0;
175300f19dcSKumar Kartikeya Dwivedi }
176300f19dcSKumar Kartikeya Dwivedi
177300f19dcSKumar Kartikeya Dwivedi SEC("?kretprobe/xyz")
map_compat_kretprobe(void * ctx)178300f19dcSKumar Kartikeya Dwivedi int map_compat_kretprobe(void *ctx)
179300f19dcSKumar Kartikeya Dwivedi {
180300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL);
181300f19dcSKumar Kartikeya Dwivedi return 0;
182300f19dcSKumar Kartikeya Dwivedi }
183300f19dcSKumar Kartikeya Dwivedi
184300f19dcSKumar Kartikeya Dwivedi SEC("?tracepoint/xyz")
map_compat_tp(void * ctx)185300f19dcSKumar Kartikeya Dwivedi int map_compat_tp(void *ctx)
186300f19dcSKumar Kartikeya Dwivedi {
187300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL);
188300f19dcSKumar Kartikeya Dwivedi return 0;
189300f19dcSKumar Kartikeya Dwivedi }
190300f19dcSKumar Kartikeya Dwivedi
191300f19dcSKumar Kartikeya Dwivedi SEC("?perf_event")
map_compat_perf(void * ctx)192300f19dcSKumar Kartikeya Dwivedi int map_compat_perf(void *ctx)
193300f19dcSKumar Kartikeya Dwivedi {
194300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL);
195300f19dcSKumar Kartikeya Dwivedi return 0;
196300f19dcSKumar Kartikeya Dwivedi }
197300f19dcSKumar Kartikeya Dwivedi
198300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp/xyz")
map_compat_raw_tp(void * ctx)199300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp(void *ctx)
200300f19dcSKumar Kartikeya Dwivedi {
201300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL);
202300f19dcSKumar Kartikeya Dwivedi return 0;
203300f19dcSKumar Kartikeya Dwivedi }
204300f19dcSKumar Kartikeya Dwivedi
205300f19dcSKumar Kartikeya Dwivedi SEC("?raw_tp.w/xyz")
map_compat_raw_tp_w(void * ctx)206300f19dcSKumar Kartikeya Dwivedi int map_compat_raw_tp_w(void *ctx)
207300f19dcSKumar Kartikeya Dwivedi {
208300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, NULL);
209300f19dcSKumar Kartikeya Dwivedi return 0;
210300f19dcSKumar Kartikeya Dwivedi }
211300f19dcSKumar Kartikeya Dwivedi
212300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
obj_type_id_oor(void * ctx)213300f19dcSKumar Kartikeya Dwivedi int obj_type_id_oor(void *ctx)
214300f19dcSKumar Kartikeya Dwivedi {
215300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(~0UL, NULL);
216300f19dcSKumar Kartikeya Dwivedi return 0;
217300f19dcSKumar Kartikeya Dwivedi }
218300f19dcSKumar Kartikeya Dwivedi
219300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
obj_new_no_composite(void * ctx)220300f19dcSKumar Kartikeya Dwivedi int obj_new_no_composite(void *ctx)
221300f19dcSKumar Kartikeya Dwivedi {
222300f19dcSKumar Kartikeya Dwivedi bpf_obj_new_impl(bpf_core_type_id_local(int), (void *)42);
223300f19dcSKumar Kartikeya Dwivedi return 0;
224300f19dcSKumar Kartikeya Dwivedi }
225300f19dcSKumar Kartikeya Dwivedi
226300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
obj_new_no_struct(void * ctx)227300f19dcSKumar Kartikeya Dwivedi int obj_new_no_struct(void *ctx)
228300f19dcSKumar Kartikeya Dwivedi {
229300f19dcSKumar Kartikeya Dwivedi
230300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(union { int data; unsigned udata; });
231300f19dcSKumar Kartikeya Dwivedi return 0;
232300f19dcSKumar Kartikeya Dwivedi }
233300f19dcSKumar Kartikeya Dwivedi
234300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
obj_drop_non_zero_off(void * ctx)235300f19dcSKumar Kartikeya Dwivedi int obj_drop_non_zero_off(void *ctx)
236300f19dcSKumar Kartikeya Dwivedi {
237300f19dcSKumar Kartikeya Dwivedi void *f;
238300f19dcSKumar Kartikeya Dwivedi
239300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(struct foo);
240300f19dcSKumar Kartikeya Dwivedi if (!f)
241300f19dcSKumar Kartikeya Dwivedi return 0;
242300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f+1);
243300f19dcSKumar Kartikeya Dwivedi return 0;
244300f19dcSKumar Kartikeya Dwivedi }
245300f19dcSKumar Kartikeya Dwivedi
246300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
new_null_ret(void * ctx)247300f19dcSKumar Kartikeya Dwivedi int new_null_ret(void *ctx)
248300f19dcSKumar Kartikeya Dwivedi {
249300f19dcSKumar Kartikeya Dwivedi return bpf_obj_new(struct foo)->data;
250300f19dcSKumar Kartikeya Dwivedi }
251300f19dcSKumar Kartikeya Dwivedi
252300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
obj_new_acq(void * ctx)253300f19dcSKumar Kartikeya Dwivedi int obj_new_acq(void *ctx)
254300f19dcSKumar Kartikeya Dwivedi {
255300f19dcSKumar Kartikeya Dwivedi bpf_obj_new(struct foo);
256300f19dcSKumar Kartikeya Dwivedi return 0;
257300f19dcSKumar Kartikeya Dwivedi }
258300f19dcSKumar Kartikeya Dwivedi
259300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
use_after_drop(void * ctx)260300f19dcSKumar Kartikeya Dwivedi int use_after_drop(void *ctx)
261300f19dcSKumar Kartikeya Dwivedi {
262300f19dcSKumar Kartikeya Dwivedi struct foo *f;
263300f19dcSKumar Kartikeya Dwivedi
264300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
265300f19dcSKumar Kartikeya Dwivedi if (!f)
266300f19dcSKumar Kartikeya Dwivedi return 0;
267300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f);
268300f19dcSKumar Kartikeya Dwivedi return f->data;
269300f19dcSKumar Kartikeya Dwivedi }
270300f19dcSKumar Kartikeya Dwivedi
271300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
ptr_walk_scalar(void * ctx)272300f19dcSKumar Kartikeya Dwivedi int ptr_walk_scalar(void *ctx)
273300f19dcSKumar Kartikeya Dwivedi {
274300f19dcSKumar Kartikeya Dwivedi struct test1 {
275300f19dcSKumar Kartikeya Dwivedi struct test2 {
276300f19dcSKumar Kartikeya Dwivedi struct test2 *next;
277300f19dcSKumar Kartikeya Dwivedi } *ptr;
278300f19dcSKumar Kartikeya Dwivedi } *p;
279300f19dcSKumar Kartikeya Dwivedi
280300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p));
281300f19dcSKumar Kartikeya Dwivedi if (!p)
282300f19dcSKumar Kartikeya Dwivedi return 0;
283300f19dcSKumar Kartikeya Dwivedi bpf_this_cpu_ptr(p->ptr);
284300f19dcSKumar Kartikeya Dwivedi return 0;
285300f19dcSKumar Kartikeya Dwivedi }
286300f19dcSKumar Kartikeya Dwivedi
287300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
direct_read_lock(void * ctx)288300f19dcSKumar Kartikeya Dwivedi int direct_read_lock(void *ctx)
289300f19dcSKumar Kartikeya Dwivedi {
290300f19dcSKumar Kartikeya Dwivedi struct foo *f;
291300f19dcSKumar Kartikeya Dwivedi
292300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
293300f19dcSKumar Kartikeya Dwivedi if (!f)
294300f19dcSKumar Kartikeya Dwivedi return 0;
295300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->lock;
296300f19dcSKumar Kartikeya Dwivedi }
297300f19dcSKumar Kartikeya Dwivedi
298300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
direct_write_lock(void * ctx)299300f19dcSKumar Kartikeya Dwivedi int direct_write_lock(void *ctx)
300300f19dcSKumar Kartikeya Dwivedi {
301300f19dcSKumar Kartikeya Dwivedi struct foo *f;
302300f19dcSKumar Kartikeya Dwivedi
303300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
304300f19dcSKumar Kartikeya Dwivedi if (!f)
305300f19dcSKumar Kartikeya Dwivedi return 0;
306300f19dcSKumar Kartikeya Dwivedi *(int *)&f->lock = 0;
307300f19dcSKumar Kartikeya Dwivedi return 0;
308300f19dcSKumar Kartikeya Dwivedi }
309300f19dcSKumar Kartikeya Dwivedi
310300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
direct_read_head(void * ctx)311300f19dcSKumar Kartikeya Dwivedi int direct_read_head(void *ctx)
312300f19dcSKumar Kartikeya Dwivedi {
313300f19dcSKumar Kartikeya Dwivedi struct foo *f;
314300f19dcSKumar Kartikeya Dwivedi
315300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
316300f19dcSKumar Kartikeya Dwivedi if (!f)
317300f19dcSKumar Kartikeya Dwivedi return 0;
318300f19dcSKumar Kartikeya Dwivedi return *(int *)&f->head;
319300f19dcSKumar Kartikeya Dwivedi }
320300f19dcSKumar Kartikeya Dwivedi
321300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
direct_write_head(void * ctx)322300f19dcSKumar Kartikeya Dwivedi int direct_write_head(void *ctx)
323300f19dcSKumar Kartikeya Dwivedi {
324300f19dcSKumar Kartikeya Dwivedi struct foo *f;
325300f19dcSKumar Kartikeya Dwivedi
326300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
327300f19dcSKumar Kartikeya Dwivedi if (!f)
328300f19dcSKumar Kartikeya Dwivedi return 0;
329300f19dcSKumar Kartikeya Dwivedi *(int *)&f->head = 0;
330300f19dcSKumar Kartikeya Dwivedi return 0;
331300f19dcSKumar Kartikeya Dwivedi }
332300f19dcSKumar Kartikeya Dwivedi
333300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
direct_read_node(void * ctx)334300f19dcSKumar Kartikeya Dwivedi int direct_read_node(void *ctx)
335300f19dcSKumar Kartikeya Dwivedi {
336300f19dcSKumar Kartikeya Dwivedi struct foo *f;
337300f19dcSKumar Kartikeya Dwivedi
338300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
339300f19dcSKumar Kartikeya Dwivedi if (!f)
340300f19dcSKumar Kartikeya Dwivedi return 0;
341de67ba39SDave Marchevsky return *(int *)&f->node2;
342300f19dcSKumar Kartikeya Dwivedi }
343300f19dcSKumar Kartikeya Dwivedi
344300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
direct_write_node(void * ctx)345300f19dcSKumar Kartikeya Dwivedi int direct_write_node(void *ctx)
346300f19dcSKumar Kartikeya Dwivedi {
347300f19dcSKumar Kartikeya Dwivedi struct foo *f;
348300f19dcSKumar Kartikeya Dwivedi
349300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
350300f19dcSKumar Kartikeya Dwivedi if (!f)
351300f19dcSKumar Kartikeya Dwivedi return 0;
352de67ba39SDave Marchevsky *(int *)&f->node2 = 0;
353300f19dcSKumar Kartikeya Dwivedi return 0;
354300f19dcSKumar Kartikeya Dwivedi }
355300f19dcSKumar Kartikeya Dwivedi
356300f19dcSKumar Kartikeya Dwivedi static __always_inline
use_after_unlock(bool push_front)357de67ba39SDave Marchevsky int use_after_unlock(bool push_front)
358300f19dcSKumar Kartikeya Dwivedi {
359300f19dcSKumar Kartikeya Dwivedi struct foo *f;
360300f19dcSKumar Kartikeya Dwivedi
361300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
362300f19dcSKumar Kartikeya Dwivedi if (!f)
363300f19dcSKumar Kartikeya Dwivedi return 0;
364300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
365300f19dcSKumar Kartikeya Dwivedi f->data = 42;
366de67ba39SDave Marchevsky if (push_front)
367de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node2);
368de67ba39SDave Marchevsky else
369de67ba39SDave Marchevsky bpf_list_push_back(&ghead, &f->node2);
370300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
371300f19dcSKumar Kartikeya Dwivedi
372300f19dcSKumar Kartikeya Dwivedi return f->data;
373300f19dcSKumar Kartikeya Dwivedi }
374300f19dcSKumar Kartikeya Dwivedi
375300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
use_after_unlock_push_front(void * ctx)376300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_front(void *ctx)
377300f19dcSKumar Kartikeya Dwivedi {
378de67ba39SDave Marchevsky return use_after_unlock(true);
379300f19dcSKumar Kartikeya Dwivedi }
380300f19dcSKumar Kartikeya Dwivedi
381300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
use_after_unlock_push_back(void * ctx)382300f19dcSKumar Kartikeya Dwivedi int use_after_unlock_push_back(void *ctx)
383300f19dcSKumar Kartikeya Dwivedi {
384de67ba39SDave Marchevsky return use_after_unlock(false);
385300f19dcSKumar Kartikeya Dwivedi }
386300f19dcSKumar Kartikeya Dwivedi
387300f19dcSKumar Kartikeya Dwivedi static __always_inline
list_double_add(bool push_front)388de67ba39SDave Marchevsky int list_double_add(bool push_front)
389300f19dcSKumar Kartikeya Dwivedi {
390300f19dcSKumar Kartikeya Dwivedi struct foo *f;
391300f19dcSKumar Kartikeya Dwivedi
392300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
393300f19dcSKumar Kartikeya Dwivedi if (!f)
394300f19dcSKumar Kartikeya Dwivedi return 0;
395300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
396de67ba39SDave Marchevsky if (push_front) {
397de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node2);
398de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node2);
399de67ba39SDave Marchevsky } else {
400de67ba39SDave Marchevsky bpf_list_push_back(&ghead, &f->node2);
401de67ba39SDave Marchevsky bpf_list_push_back(&ghead, &f->node2);
402de67ba39SDave Marchevsky }
403300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
404300f19dcSKumar Kartikeya Dwivedi
405300f19dcSKumar Kartikeya Dwivedi return 0;
406300f19dcSKumar Kartikeya Dwivedi }
407300f19dcSKumar Kartikeya Dwivedi
408300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
double_push_front(void * ctx)409300f19dcSKumar Kartikeya Dwivedi int double_push_front(void *ctx)
410300f19dcSKumar Kartikeya Dwivedi {
411de67ba39SDave Marchevsky return list_double_add(true);
412300f19dcSKumar Kartikeya Dwivedi }
413300f19dcSKumar Kartikeya Dwivedi
414300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
double_push_back(void * ctx)415300f19dcSKumar Kartikeya Dwivedi int double_push_back(void *ctx)
416300f19dcSKumar Kartikeya Dwivedi {
417de67ba39SDave Marchevsky return list_double_add(false);
418300f19dcSKumar Kartikeya Dwivedi }
419300f19dcSKumar Kartikeya Dwivedi
420300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
no_node_value_type(void * ctx)421300f19dcSKumar Kartikeya Dwivedi int no_node_value_type(void *ctx)
422300f19dcSKumar Kartikeya Dwivedi {
423300f19dcSKumar Kartikeya Dwivedi void *p;
424300f19dcSKumar Kartikeya Dwivedi
425300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(struct { int data; });
426300f19dcSKumar Kartikeya Dwivedi if (!p)
427300f19dcSKumar Kartikeya Dwivedi return 0;
428300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
429300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, p);
430300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
431300f19dcSKumar Kartikeya Dwivedi
432300f19dcSKumar Kartikeya Dwivedi return 0;
433300f19dcSKumar Kartikeya Dwivedi }
434300f19dcSKumar Kartikeya Dwivedi
435300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_value_type(void * ctx)436300f19dcSKumar Kartikeya Dwivedi int incorrect_value_type(void *ctx)
437300f19dcSKumar Kartikeya Dwivedi {
438300f19dcSKumar Kartikeya Dwivedi struct bar *b;
439300f19dcSKumar Kartikeya Dwivedi
440300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b));
441300f19dcSKumar Kartikeya Dwivedi if (!b)
442300f19dcSKumar Kartikeya Dwivedi return 0;
443300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
444300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(&ghead, &b->node);
445300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
446300f19dcSKumar Kartikeya Dwivedi
447300f19dcSKumar Kartikeya Dwivedi return 0;
448300f19dcSKumar Kartikeya Dwivedi }
449300f19dcSKumar Kartikeya Dwivedi
450300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_node_var_off(struct __sk_buff * ctx)451300f19dcSKumar Kartikeya Dwivedi int incorrect_node_var_off(struct __sk_buff *ctx)
452300f19dcSKumar Kartikeya Dwivedi {
453300f19dcSKumar Kartikeya Dwivedi struct foo *f;
454300f19dcSKumar Kartikeya Dwivedi
455300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
456300f19dcSKumar Kartikeya Dwivedi if (!f)
457300f19dcSKumar Kartikeya Dwivedi return 0;
458300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
459de67ba39SDave Marchevsky bpf_list_push_front(&ghead, (void *)&f->node2 + ctx->protocol);
460300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
461300f19dcSKumar Kartikeya Dwivedi
462300f19dcSKumar Kartikeya Dwivedi return 0;
463300f19dcSKumar Kartikeya Dwivedi }
464300f19dcSKumar Kartikeya Dwivedi
465300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_node_off1(void * ctx)466300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off1(void *ctx)
467300f19dcSKumar Kartikeya Dwivedi {
468300f19dcSKumar Kartikeya Dwivedi struct foo *f;
469300f19dcSKumar Kartikeya Dwivedi
470300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
471300f19dcSKumar Kartikeya Dwivedi if (!f)
472300f19dcSKumar Kartikeya Dwivedi return 0;
473300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
474de67ba39SDave Marchevsky bpf_list_push_front(&ghead, (void *)&f->node2 + 1);
475300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
476300f19dcSKumar Kartikeya Dwivedi
477300f19dcSKumar Kartikeya Dwivedi return 0;
478300f19dcSKumar Kartikeya Dwivedi }
479300f19dcSKumar Kartikeya Dwivedi
480300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_node_off2(void * ctx)481300f19dcSKumar Kartikeya Dwivedi int incorrect_node_off2(void *ctx)
482300f19dcSKumar Kartikeya Dwivedi {
483300f19dcSKumar Kartikeya Dwivedi struct foo *f;
484300f19dcSKumar Kartikeya Dwivedi
485300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
486300f19dcSKumar Kartikeya Dwivedi if (!f)
487300f19dcSKumar Kartikeya Dwivedi return 0;
488300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
489de67ba39SDave Marchevsky bpf_list_push_front(&ghead, &f->node);
490300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
491300f19dcSKumar Kartikeya Dwivedi
492300f19dcSKumar Kartikeya Dwivedi return 0;
493300f19dcSKumar Kartikeya Dwivedi }
494300f19dcSKumar Kartikeya Dwivedi
495300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
no_head_type(void * ctx)496300f19dcSKumar Kartikeya Dwivedi int no_head_type(void *ctx)
497300f19dcSKumar Kartikeya Dwivedi {
498300f19dcSKumar Kartikeya Dwivedi void *p;
499300f19dcSKumar Kartikeya Dwivedi
500300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(struct { int data; }));
501300f19dcSKumar Kartikeya Dwivedi if (!p)
502300f19dcSKumar Kartikeya Dwivedi return 0;
503300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
504300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front(p, NULL);
505300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
506300f19dcSKumar Kartikeya Dwivedi
507300f19dcSKumar Kartikeya Dwivedi return 0;
508300f19dcSKumar Kartikeya Dwivedi }
509300f19dcSKumar Kartikeya Dwivedi
510300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_head_var_off1(struct __sk_buff * ctx)511300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off1(struct __sk_buff *ctx)
512300f19dcSKumar Kartikeya Dwivedi {
513300f19dcSKumar Kartikeya Dwivedi struct foo *f;
514300f19dcSKumar Kartikeya Dwivedi
515300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
516300f19dcSKumar Kartikeya Dwivedi if (!f)
517300f19dcSKumar Kartikeya Dwivedi return 0;
518300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
519de67ba39SDave Marchevsky bpf_list_push_front((void *)&ghead + ctx->protocol, &f->node2);
520300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
521300f19dcSKumar Kartikeya Dwivedi
522300f19dcSKumar Kartikeya Dwivedi return 0;
523300f19dcSKumar Kartikeya Dwivedi }
524300f19dcSKumar Kartikeya Dwivedi
525300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_head_var_off2(struct __sk_buff * ctx)526300f19dcSKumar Kartikeya Dwivedi int incorrect_head_var_off2(struct __sk_buff *ctx)
527300f19dcSKumar Kartikeya Dwivedi {
528300f19dcSKumar Kartikeya Dwivedi struct foo *f;
529300f19dcSKumar Kartikeya Dwivedi
530300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
531300f19dcSKumar Kartikeya Dwivedi if (!f)
532300f19dcSKumar Kartikeya Dwivedi return 0;
533300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
534de67ba39SDave Marchevsky bpf_list_push_front((void *)&f->head + ctx->protocol, &f->node2);
535300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
536300f19dcSKumar Kartikeya Dwivedi
537300f19dcSKumar Kartikeya Dwivedi return 0;
538300f19dcSKumar Kartikeya Dwivedi }
539300f19dcSKumar Kartikeya Dwivedi
540300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_head_off1(void * ctx)541300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off1(void *ctx)
542300f19dcSKumar Kartikeya Dwivedi {
543300f19dcSKumar Kartikeya Dwivedi struct foo *f;
544300f19dcSKumar Kartikeya Dwivedi struct bar *b;
545300f19dcSKumar Kartikeya Dwivedi
546300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
547300f19dcSKumar Kartikeya Dwivedi if (!f)
548300f19dcSKumar Kartikeya Dwivedi return 0;
549300f19dcSKumar Kartikeya Dwivedi b = bpf_obj_new(typeof(*b));
550300f19dcSKumar Kartikeya Dwivedi if (!b) {
551300f19dcSKumar Kartikeya Dwivedi bpf_obj_drop(f);
552300f19dcSKumar Kartikeya Dwivedi return 0;
553300f19dcSKumar Kartikeya Dwivedi }
554300f19dcSKumar Kartikeya Dwivedi
555300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&f->lock);
556300f19dcSKumar Kartikeya Dwivedi bpf_list_push_front((void *)&f->head + 1, &b->node);
557300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&f->lock);
558300f19dcSKumar Kartikeya Dwivedi
559300f19dcSKumar Kartikeya Dwivedi return 0;
560300f19dcSKumar Kartikeya Dwivedi }
561300f19dcSKumar Kartikeya Dwivedi
562300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
incorrect_head_off2(void * ctx)563300f19dcSKumar Kartikeya Dwivedi int incorrect_head_off2(void *ctx)
564300f19dcSKumar Kartikeya Dwivedi {
565300f19dcSKumar Kartikeya Dwivedi struct foo *f;
566300f19dcSKumar Kartikeya Dwivedi
567300f19dcSKumar Kartikeya Dwivedi f = bpf_obj_new(typeof(*f));
568300f19dcSKumar Kartikeya Dwivedi if (!f)
569300f19dcSKumar Kartikeya Dwivedi return 0;
570300f19dcSKumar Kartikeya Dwivedi
571300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&glock);
572de67ba39SDave Marchevsky bpf_list_push_front((void *)&ghead + 1, &f->node2);
573300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&glock);
574300f19dcSKumar Kartikeya Dwivedi
575300f19dcSKumar Kartikeya Dwivedi return 0;
576300f19dcSKumar Kartikeya Dwivedi }
577300f19dcSKumar Kartikeya Dwivedi
578300f19dcSKumar Kartikeya Dwivedi static __always_inline
pop_ptr_off(void * (* op)(void * head))579300f19dcSKumar Kartikeya Dwivedi int pop_ptr_off(void *(*op)(void *head))
580300f19dcSKumar Kartikeya Dwivedi {
581300f19dcSKumar Kartikeya Dwivedi struct {
582300f19dcSKumar Kartikeya Dwivedi struct bpf_list_head head __contains(foo, node2);
583300f19dcSKumar Kartikeya Dwivedi struct bpf_spin_lock lock;
584300f19dcSKumar Kartikeya Dwivedi } *p;
585300f19dcSKumar Kartikeya Dwivedi struct bpf_list_node *n;
586300f19dcSKumar Kartikeya Dwivedi
587300f19dcSKumar Kartikeya Dwivedi p = bpf_obj_new(typeof(*p));
588300f19dcSKumar Kartikeya Dwivedi if (!p)
589300f19dcSKumar Kartikeya Dwivedi return 0;
590300f19dcSKumar Kartikeya Dwivedi bpf_spin_lock(&p->lock);
591300f19dcSKumar Kartikeya Dwivedi n = op(&p->head);
592300f19dcSKumar Kartikeya Dwivedi bpf_spin_unlock(&p->lock);
593300f19dcSKumar Kartikeya Dwivedi
594*67d9e6b2SKumar Kartikeya Dwivedi if (!n)
595*67d9e6b2SKumar Kartikeya Dwivedi return 0;
596*67d9e6b2SKumar Kartikeya Dwivedi bpf_spin_lock((void *)n);
597300f19dcSKumar Kartikeya Dwivedi return 0;
598300f19dcSKumar Kartikeya Dwivedi }
599300f19dcSKumar Kartikeya Dwivedi
600300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
pop_front_off(void * ctx)601300f19dcSKumar Kartikeya Dwivedi int pop_front_off(void *ctx)
602300f19dcSKumar Kartikeya Dwivedi {
603300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_front);
604300f19dcSKumar Kartikeya Dwivedi }
605300f19dcSKumar Kartikeya Dwivedi
606300f19dcSKumar Kartikeya Dwivedi SEC("?tc")
pop_back_off(void * ctx)607300f19dcSKumar Kartikeya Dwivedi int pop_back_off(void *ctx)
608300f19dcSKumar Kartikeya Dwivedi {
609300f19dcSKumar Kartikeya Dwivedi return pop_ptr_off((void *)bpf_list_pop_back);
610300f19dcSKumar Kartikeya Dwivedi }
611300f19dcSKumar Kartikeya Dwivedi
612300f19dcSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL";
613