diff options
Diffstat (limited to 'tools/perf/tests/bpf.c')
-rw-r--r-- | tools/perf/tests/bpf.c | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index 33689a0cf821..199501c71e27 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c | |||
@@ -1,7 +1,11 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <sys/epoll.h> | 2 | #include <sys/epoll.h> |
3 | #include <util/util.h> | ||
3 | #include <util/bpf-loader.h> | 4 | #include <util/bpf-loader.h> |
4 | #include <util/evlist.h> | 5 | #include <util/evlist.h> |
6 | #include <linux/bpf.h> | ||
7 | #include <linux/filter.h> | ||
8 | #include <bpf/bpf.h> | ||
5 | #include "tests.h" | 9 | #include "tests.h" |
6 | #include "llvm.h" | 10 | #include "llvm.h" |
7 | #include "debug.h" | 11 | #include "debug.h" |
@@ -71,6 +75,15 @@ static struct { | |||
71 | (NR_ITERS + 1) / 4, | 75 | (NR_ITERS + 1) / 4, |
72 | }, | 76 | }, |
73 | #endif | 77 | #endif |
78 | { | ||
79 | LLVM_TESTCASE_BPF_RELOCATION, | ||
80 | "Test BPF relocation checker", | ||
81 | "[bpf_relocation_test]", | ||
82 | "fix 'perf test LLVM' first", | ||
83 | "libbpf error when dealing with relocation", | ||
84 | NULL, | ||
85 | 0, | ||
86 | }, | ||
74 | }; | 87 | }; |
75 | 88 | ||
76 | static int do_test(struct bpf_object *obj, int (*func)(void), | 89 | static int do_test(struct bpf_object *obj, int (*func)(void), |
@@ -99,7 +112,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), | |||
99 | parse_evlist.error = &parse_error; | 112 | parse_evlist.error = &parse_error; |
100 | INIT_LIST_HEAD(&parse_evlist.list); | 113 | INIT_LIST_HEAD(&parse_evlist.list); |
101 | 114 | ||
102 | err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj); | 115 | err = parse_events_load_bpf_obj(&parse_evlist, &parse_evlist.list, obj, NULL); |
103 | if (err || list_empty(&parse_evlist.list)) { | 116 | if (err || list_empty(&parse_evlist.list)) { |
104 | pr_debug("Failed to add events selected by BPF\n"); | 117 | pr_debug("Failed to add events selected by BPF\n"); |
105 | return TEST_FAIL; | 118 | return TEST_FAIL; |
@@ -190,7 +203,7 @@ static int __test__bpf(int idx) | |||
190 | 203 | ||
191 | ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, | 204 | ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, |
192 | bpf_testcase_table[idx].prog_id, | 205 | bpf_testcase_table[idx].prog_id, |
193 | true); | 206 | true, NULL); |
194 | if (ret != TEST_OK || !obj_buf || !obj_buf_sz) { | 207 | if (ret != TEST_OK || !obj_buf || !obj_buf_sz) { |
195 | pr_debug("Unable to get BPF object, %s\n", | 208 | pr_debug("Unable to get BPF object, %s\n", |
196 | bpf_testcase_table[idx].msg_compile_fail); | 209 | bpf_testcase_table[idx].msg_compile_fail); |
@@ -202,14 +215,21 @@ static int __test__bpf(int idx) | |||
202 | 215 | ||
203 | obj = prepare_bpf(obj_buf, obj_buf_sz, | 216 | obj = prepare_bpf(obj_buf, obj_buf_sz, |
204 | bpf_testcase_table[idx].name); | 217 | bpf_testcase_table[idx].name); |
205 | if (!obj) { | 218 | if ((!!bpf_testcase_table[idx].target_func) != (!!obj)) { |
219 | if (!obj) | ||
220 | pr_debug("Fail to load BPF object: %s\n", | ||
221 | bpf_testcase_table[idx].msg_load_fail); | ||
222 | else | ||
223 | pr_debug("Success unexpectedly: %s\n", | ||
224 | bpf_testcase_table[idx].msg_load_fail); | ||
206 | ret = TEST_FAIL; | 225 | ret = TEST_FAIL; |
207 | goto out; | 226 | goto out; |
208 | } | 227 | } |
209 | 228 | ||
210 | ret = do_test(obj, | 229 | if (obj) |
211 | bpf_testcase_table[idx].target_func, | 230 | ret = do_test(obj, |
212 | bpf_testcase_table[idx].expect_result); | 231 | bpf_testcase_table[idx].target_func, |
232 | bpf_testcase_table[idx].expect_result); | ||
213 | out: | 233 | out: |
214 | bpf__clear(); | 234 | bpf__clear(); |
215 | return ret; | 235 | return ret; |
@@ -227,6 +247,36 @@ const char *test__bpf_subtest_get_desc(int i) | |||
227 | return bpf_testcase_table[i].desc; | 247 | return bpf_testcase_table[i].desc; |
228 | } | 248 | } |
229 | 249 | ||
250 | static int check_env(void) | ||
251 | { | ||
252 | int err; | ||
253 | unsigned int kver_int; | ||
254 | char license[] = "GPL"; | ||
255 | |||
256 | struct bpf_insn insns[] = { | ||
257 | BPF_MOV64_IMM(BPF_REG_0, 1), | ||
258 | BPF_EXIT_INSN(), | ||
259 | }; | ||
260 | |||
261 | err = fetch_kernel_version(&kver_int, NULL, 0); | ||
262 | if (err) { | ||
263 | pr_debug("Unable to get kernel version\n"); | ||
264 | return err; | ||
265 | } | ||
266 | |||
267 | err = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns, | ||
268 | sizeof(insns) / sizeof(insns[0]), | ||
269 | license, kver_int, NULL, 0); | ||
270 | if (err < 0) { | ||
271 | pr_err("Missing basic BPF support, skip this test: %s\n", | ||
272 | strerror(errno)); | ||
273 | return err; | ||
274 | } | ||
275 | close(err); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
230 | int test__bpf(int i) | 280 | int test__bpf(int i) |
231 | { | 281 | { |
232 | int err; | 282 | int err; |
@@ -239,6 +289,9 @@ int test__bpf(int i) | |||
239 | return TEST_SKIP; | 289 | return TEST_SKIP; |
240 | } | 290 | } |
241 | 291 | ||
292 | if (check_env()) | ||
293 | return TEST_SKIP; | ||
294 | |||
242 | err = __test__bpf(i); | 295 | err = __test__bpf(i); |
243 | return err; | 296 | return err; |
244 | } | 297 | } |