selftests/bpf: Fix erroneous bitmask operation
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / progs / cgrp_kfunc_success.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3
4 #include <vmlinux.h>
5 #include <bpf/bpf_tracing.h>
6 #include <bpf/bpf_helpers.h>
7
8 #include "cgrp_kfunc_common.h"
9
10 char _license[] SEC("license") = "GPL";
11
12 int err, pid, invocations;
13
14 /* Prototype for all of the program trace events below:
15  *
16  * TRACE_EVENT(cgroup_mkdir,
17  *         TP_PROTO(struct cgroup *cgrp, const char *path),
18  *         TP_ARGS(cgrp, path)
19  */
20
21 static bool is_test_kfunc_task(void)
22 {
23         int cur_pid = bpf_get_current_pid_tgid() >> 32;
24         bool same = pid == cur_pid;
25
26         if (same)
27                 __sync_fetch_and_add(&invocations, 1);
28
29         return same;
30 }
31
32 SEC("tp_btf/cgroup_mkdir")
33 int BPF_PROG(test_cgrp_acquire_release_argument, struct cgroup *cgrp, const char *path)
34 {
35         struct cgroup *acquired;
36
37         if (!is_test_kfunc_task())
38                 return 0;
39
40         acquired = bpf_cgroup_acquire(cgrp);
41         if (!acquired)
42                 err = 1;
43         else
44                 bpf_cgroup_release(acquired);
45
46         return 0;
47 }
48
49 SEC("tp_btf/cgroup_mkdir")
50 int BPF_PROG(test_cgrp_acquire_leave_in_map, struct cgroup *cgrp, const char *path)
51 {
52         long status;
53
54         if (!is_test_kfunc_task())
55                 return 0;
56
57         status = cgrps_kfunc_map_insert(cgrp);
58         if (status)
59                 err = 1;
60
61         return 0;
62 }
63
64 SEC("tp_btf/cgroup_mkdir")
65 int BPF_PROG(test_cgrp_xchg_release, struct cgroup *cgrp, const char *path)
66 {
67         struct cgroup *kptr, *cg;
68         struct __cgrps_kfunc_map_value *v;
69         long status;
70
71         if (!is_test_kfunc_task())
72                 return 0;
73
74         status = cgrps_kfunc_map_insert(cgrp);
75         if (status) {
76                 err = 1;
77                 return 0;
78         }
79
80         v = cgrps_kfunc_map_value_lookup(cgrp);
81         if (!v) {
82                 err = 2;
83                 return 0;
84         }
85
86         kptr = v->cgrp;
87         if (!kptr) {
88                 err = 4;
89                 return 0;
90         }
91
92         cg = bpf_cgroup_ancestor(kptr, 1);
93         if (cg) /* verifier only check */
94                 bpf_cgroup_release(cg);
95
96         kptr = bpf_kptr_xchg(&v->cgrp, NULL);
97         if (!kptr) {
98                 err = 3;
99                 return 0;
100         }
101
102         bpf_cgroup_release(kptr);
103
104         return 0;
105 }
106
107 SEC("tp_btf/cgroup_mkdir")
108 int BPF_PROG(test_cgrp_get_release, struct cgroup *cgrp, const char *path)
109 {
110         struct cgroup *kptr;
111         struct __cgrps_kfunc_map_value *v;
112         long status;
113
114         if (!is_test_kfunc_task())
115                 return 0;
116
117         status = cgrps_kfunc_map_insert(cgrp);
118         if (status) {
119                 err = 1;
120                 return 0;
121         }
122
123         v = cgrps_kfunc_map_value_lookup(cgrp);
124         if (!v) {
125                 err = 2;
126                 return 0;
127         }
128
129         bpf_rcu_read_lock();
130         kptr = v->cgrp;
131         if (!kptr)
132                 err = 3;
133         bpf_rcu_read_unlock();
134
135         return 0;
136 }
137
138 SEC("tp_btf/cgroup_mkdir")
139 int BPF_PROG(test_cgrp_get_ancestors, struct cgroup *cgrp, const char *path)
140 {
141         struct cgroup *self, *ancestor1, *invalid;
142
143         if (!is_test_kfunc_task())
144                 return 0;
145
146         self = bpf_cgroup_ancestor(cgrp, cgrp->level);
147         if (!self) {
148                 err = 1;
149                 return 0;
150         }
151
152         if (self->self.id != cgrp->self.id) {
153                 bpf_cgroup_release(self);
154                 err = 2;
155                 return 0;
156         }
157         bpf_cgroup_release(self);
158
159         ancestor1 = bpf_cgroup_ancestor(cgrp, cgrp->level - 1);
160         if (!ancestor1) {
161                 err = 3;
162                 return 0;
163         }
164         bpf_cgroup_release(ancestor1);
165
166         invalid = bpf_cgroup_ancestor(cgrp, 10000);
167         if (invalid) {
168                 bpf_cgroup_release(invalid);
169                 err = 4;
170                 return 0;
171         }
172
173         invalid = bpf_cgroup_ancestor(cgrp, -1);
174         if (invalid) {
175                 bpf_cgroup_release(invalid);
176                 err = 5;
177                 return 0;
178         }
179
180         return 0;
181 }
182
183 SEC("tp_btf/cgroup_mkdir")
184 int BPF_PROG(test_cgrp_from_id, struct cgroup *cgrp, const char *path)
185 {
186         struct cgroup *parent, *res;
187         u64 parent_cgid;
188
189         if (!is_test_kfunc_task())
190                 return 0;
191
192         /* @cgrp's ID is not visible yet, let's test with the parent */
193         parent = bpf_cgroup_ancestor(cgrp, cgrp->level - 1);
194         if (!parent) {
195                 err = 1;
196                 return 0;
197         }
198
199         parent_cgid = parent->kn->id;
200         bpf_cgroup_release(parent);
201
202         res = bpf_cgroup_from_id(parent_cgid);
203         if (!res) {
204                 err = 2;
205                 return 0;
206         }
207
208         bpf_cgroup_release(res);
209
210         if (res != parent) {
211                 err = 3;
212                 return 0;
213         }
214
215         res = bpf_cgroup_from_id((u64)-1);
216         if (res) {
217                 bpf_cgroup_release(res);
218                 err = 4;
219                 return 0;
220         }
221
222         return 0;
223 }