1 // SPDX-License-Identifier: GPL-2.0
2 #include <errno.h>
3 #include <sys/prctl.h>
4 #include <test_progs.h>
5 #include "kprobe_multi.skel.h"
6 #include "trace_helpers.h"
7 #include "kprobe_multi_empty.skel.h"
8 #include "kprobe_multi_override.skel.h"
9 #include "kprobe_multi_session.skel.h"
10 #include "kprobe_multi_session_cookie.skel.h"
11 #include "kprobe_multi_verifier.skel.h"
12 #include "kprobe_write_ctx.skel.h"
13 #include "bpf/libbpf_internal.h"
14 #include "bpf/hashmap.h"
15
kprobe_multi_test_run(struct kprobe_multi * skel,bool test_return)16 static void kprobe_multi_test_run(struct kprobe_multi *skel, bool test_return)
17 {
18 LIBBPF_OPTS(bpf_test_run_opts, topts);
19 int err, prog_fd;
20
21 prog_fd = bpf_program__fd(skel->progs.trigger);
22 err = bpf_prog_test_run_opts(prog_fd, &topts);
23 ASSERT_OK(err, "test_run");
24 ASSERT_EQ(topts.retval, 0, "test_run");
25
26 ASSERT_EQ(skel->bss->kprobe_test1_result, 1, "kprobe_test1_result");
27 ASSERT_EQ(skel->bss->kprobe_test2_result, 1, "kprobe_test2_result");
28 ASSERT_EQ(skel->bss->kprobe_test3_result, 1, "kprobe_test3_result");
29 ASSERT_EQ(skel->bss->kprobe_test4_result, 1, "kprobe_test4_result");
30 ASSERT_EQ(skel->bss->kprobe_test5_result, 1, "kprobe_test5_result");
31 ASSERT_EQ(skel->bss->kprobe_test6_result, 1, "kprobe_test6_result");
32 ASSERT_EQ(skel->bss->kprobe_test7_result, 1, "kprobe_test7_result");
33 ASSERT_EQ(skel->bss->kprobe_test8_result, 1, "kprobe_test8_result");
34
35 if (test_return) {
36 ASSERT_EQ(skel->bss->kretprobe_test1_result, 1, "kretprobe_test1_result");
37 ASSERT_EQ(skel->bss->kretprobe_test2_result, 1, "kretprobe_test2_result");
38 ASSERT_EQ(skel->bss->kretprobe_test3_result, 1, "kretprobe_test3_result");
39 ASSERT_EQ(skel->bss->kretprobe_test4_result, 1, "kretprobe_test4_result");
40 ASSERT_EQ(skel->bss->kretprobe_test5_result, 1, "kretprobe_test5_result");
41 ASSERT_EQ(skel->bss->kretprobe_test6_result, 1, "kretprobe_test6_result");
42 ASSERT_EQ(skel->bss->kretprobe_test7_result, 1, "kretprobe_test7_result");
43 ASSERT_EQ(skel->bss->kretprobe_test8_result, 1, "kretprobe_test8_result");
44 }
45 }
46
test_skel_api(void)47 static void test_skel_api(void)
48 {
49 struct kprobe_multi *skel = NULL;
50 int err;
51
52 skel = kprobe_multi__open_and_load();
53 if (!ASSERT_OK_PTR(skel, "kprobe_multi__open_and_load"))
54 goto cleanup;
55
56 skel->bss->pid = getpid();
57 err = kprobe_multi__attach(skel);
58 if (!ASSERT_OK(err, "kprobe_multi__attach"))
59 goto cleanup;
60
61 kprobe_multi_test_run(skel, true);
62
63 cleanup:
64 kprobe_multi__destroy(skel);
65 }
66
test_link_api(struct bpf_link_create_opts * opts)67 static void test_link_api(struct bpf_link_create_opts *opts)
68 {
69 int prog_fd, link1_fd = -1, link2_fd = -1;
70 struct kprobe_multi *skel = NULL;
71
72 skel = kprobe_multi__open_and_load();
73 if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
74 goto cleanup;
75
76 skel->bss->pid = getpid();
77 prog_fd = bpf_program__fd(skel->progs.test_kprobe);
78 link1_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, opts);
79 if (!ASSERT_GE(link1_fd, 0, "link_fd"))
80 goto cleanup;
81
82 opts->kprobe_multi.flags = BPF_F_KPROBE_MULTI_RETURN;
83 prog_fd = bpf_program__fd(skel->progs.test_kretprobe);
84 link2_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, opts);
85 if (!ASSERT_GE(link2_fd, 0, "link_fd"))
86 goto cleanup;
87
88 kprobe_multi_test_run(skel, true);
89
90 cleanup:
91 if (link1_fd != -1)
92 close(link1_fd);
93 if (link2_fd != -1)
94 close(link2_fd);
95 kprobe_multi__destroy(skel);
96 }
97
98 #define GET_ADDR(__sym, __addr) ({ \
99 __addr = ksym_get_addr(__sym); \
100 if (!ASSERT_NEQ(__addr, 0, "kallsyms load failed for " #__sym)) \
101 return; \
102 })
103
test_link_api_addrs(void)104 static void test_link_api_addrs(void)
105 {
106 LIBBPF_OPTS(bpf_link_create_opts, opts);
107 unsigned long long addrs[8];
108
109 GET_ADDR("bpf_fentry_test1", addrs[0]);
110 GET_ADDR("bpf_fentry_test2", addrs[1]);
111 GET_ADDR("bpf_fentry_test3", addrs[2]);
112 GET_ADDR("bpf_fentry_test4", addrs[3]);
113 GET_ADDR("bpf_fentry_test5", addrs[4]);
114 GET_ADDR("bpf_fentry_test6", addrs[5]);
115 GET_ADDR("bpf_fentry_test7", addrs[6]);
116 GET_ADDR("bpf_fentry_test8", addrs[7]);
117
118 opts.kprobe_multi.addrs = (const unsigned long*) addrs;
119 opts.kprobe_multi.cnt = ARRAY_SIZE(addrs);
120 test_link_api(&opts);
121 }
122
test_link_api_syms(void)123 static void test_link_api_syms(void)
124 {
125 LIBBPF_OPTS(bpf_link_create_opts, opts);
126 const char *syms[8] = {
127 "bpf_fentry_test1",
128 "bpf_fentry_test2",
129 "bpf_fentry_test3",
130 "bpf_fentry_test4",
131 "bpf_fentry_test5",
132 "bpf_fentry_test6",
133 "bpf_fentry_test7",
134 "bpf_fentry_test8",
135 };
136
137 opts.kprobe_multi.syms = syms;
138 opts.kprobe_multi.cnt = ARRAY_SIZE(syms);
139 test_link_api(&opts);
140 }
141
142 static void
test_attach_api(const char * pattern,struct bpf_kprobe_multi_opts * opts)143 test_attach_api(const char *pattern, struct bpf_kprobe_multi_opts *opts)
144 {
145 struct bpf_link *link1 = NULL, *link2 = NULL;
146 struct kprobe_multi *skel = NULL;
147
148 skel = kprobe_multi__open_and_load();
149 if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
150 goto cleanup;
151
152 skel->bss->pid = getpid();
153 link1 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
154 pattern, opts);
155 if (!ASSERT_OK_PTR(link1, "bpf_program__attach_kprobe_multi_opts"))
156 goto cleanup;
157
158 if (opts) {
159 opts->retprobe = true;
160 link2 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kretprobe_manual,
161 pattern, opts);
162 if (!ASSERT_OK_PTR(link2, "bpf_program__attach_kprobe_multi_opts"))
163 goto cleanup;
164 }
165
166 kprobe_multi_test_run(skel, !!opts);
167
168 cleanup:
169 bpf_link__destroy(link2);
170 bpf_link__destroy(link1);
171 kprobe_multi__destroy(skel);
172 }
173
test_attach_api_pattern(void)174 static void test_attach_api_pattern(void)
175 {
176 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
177
178 test_attach_api("bpf_fentry_test*", &opts);
179 test_attach_api("bpf_fentry_test?", NULL);
180 }
181
test_attach_api_addrs(void)182 static void test_attach_api_addrs(void)
183 {
184 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
185 unsigned long long addrs[8];
186
187 GET_ADDR("bpf_fentry_test1", addrs[0]);
188 GET_ADDR("bpf_fentry_test2", addrs[1]);
189 GET_ADDR("bpf_fentry_test3", addrs[2]);
190 GET_ADDR("bpf_fentry_test4", addrs[3]);
191 GET_ADDR("bpf_fentry_test5", addrs[4]);
192 GET_ADDR("bpf_fentry_test6", addrs[5]);
193 GET_ADDR("bpf_fentry_test7", addrs[6]);
194 GET_ADDR("bpf_fentry_test8", addrs[7]);
195
196 opts.addrs = (const unsigned long *) addrs;
197 opts.cnt = ARRAY_SIZE(addrs);
198 test_attach_api(NULL, &opts);
199 }
200
test_attach_api_syms(void)201 static void test_attach_api_syms(void)
202 {
203 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
204 const char *syms[8] = {
205 "bpf_fentry_test1",
206 "bpf_fentry_test2",
207 "bpf_fentry_test3",
208 "bpf_fentry_test4",
209 "bpf_fentry_test5",
210 "bpf_fentry_test6",
211 "bpf_fentry_test7",
212 "bpf_fentry_test8",
213 };
214
215 opts.syms = syms;
216 opts.cnt = ARRAY_SIZE(syms);
217 test_attach_api(NULL, &opts);
218 }
219
test_attach_api_fails(void)220 static void test_attach_api_fails(void)
221 {
222 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
223 struct kprobe_multi *skel = NULL;
224 struct bpf_link *link = NULL;
225 unsigned long long addrs[2];
226 const char *syms[2] = {
227 "bpf_fentry_test1",
228 "bpf_fentry_test2",
229 };
230 __u64 cookies[2];
231 int saved_error;
232
233 addrs[0] = ksym_get_addr("bpf_fentry_test1");
234 addrs[1] = ksym_get_addr("bpf_fentry_test2");
235
236 if (!ASSERT_FALSE(!addrs[0] || !addrs[1], "ksym_get_addr"))
237 goto cleanup;
238
239 skel = kprobe_multi__open_and_load();
240 if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
241 goto cleanup;
242
243 skel->bss->pid = getpid();
244
245 /* fail_1 - pattern and opts NULL */
246 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
247 NULL, NULL);
248 saved_error = -errno;
249 if (!ASSERT_ERR_PTR(link, "fail_1"))
250 goto cleanup;
251
252 if (!ASSERT_EQ(saved_error, -EINVAL, "fail_1_error"))
253 goto cleanup;
254
255 /* fail_2 - both addrs and syms set */
256 opts.addrs = (const unsigned long *) addrs;
257 opts.syms = syms;
258 opts.cnt = ARRAY_SIZE(syms);
259 opts.cookies = NULL;
260
261 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
262 NULL, &opts);
263 saved_error = -errno;
264 if (!ASSERT_ERR_PTR(link, "fail_2"))
265 goto cleanup;
266
267 if (!ASSERT_EQ(saved_error, -EINVAL, "fail_2_error"))
268 goto cleanup;
269
270 /* fail_3 - pattern and addrs set */
271 opts.addrs = (const unsigned long *) addrs;
272 opts.syms = NULL;
273 opts.cnt = ARRAY_SIZE(syms);
274 opts.cookies = NULL;
275
276 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
277 "ksys_*", &opts);
278 saved_error = -errno;
279 if (!ASSERT_ERR_PTR(link, "fail_3"))
280 goto cleanup;
281
282 if (!ASSERT_EQ(saved_error, -EINVAL, "fail_3_error"))
283 goto cleanup;
284
285 /* fail_4 - pattern and cnt set */
286 opts.addrs = NULL;
287 opts.syms = NULL;
288 opts.cnt = ARRAY_SIZE(syms);
289 opts.cookies = NULL;
290
291 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
292 "ksys_*", &opts);
293 saved_error = -errno;
294 if (!ASSERT_ERR_PTR(link, "fail_4"))
295 goto cleanup;
296
297 if (!ASSERT_EQ(saved_error, -EINVAL, "fail_4_error"))
298 goto cleanup;
299
300 /* fail_5 - pattern and cookies */
301 opts.addrs = NULL;
302 opts.syms = NULL;
303 opts.cnt = 0;
304 opts.cookies = cookies;
305
306 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
307 "ksys_*", &opts);
308 saved_error = -errno;
309 if (!ASSERT_ERR_PTR(link, "fail_5"))
310 goto cleanup;
311
312 if (!ASSERT_EQ(saved_error, -EINVAL, "fail_5_error"))
313 goto cleanup;
314
315 /* fail_6 - abnormal cnt */
316 opts.addrs = (const unsigned long *) addrs;
317 opts.syms = NULL;
318 opts.cnt = INT_MAX;
319 opts.cookies = NULL;
320
321 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
322 NULL, &opts);
323 saved_error = -errno;
324 if (!ASSERT_ERR_PTR(link, "fail_6"))
325 goto cleanup;
326
327 if (!ASSERT_EQ(saved_error, -E2BIG, "fail_6_error"))
328 goto cleanup;
329
330 cleanup:
331 bpf_link__destroy(link);
332 kprobe_multi__destroy(skel);
333 }
334
test_session_skel_api(void)335 static void test_session_skel_api(void)
336 {
337 struct kprobe_multi_session *skel = NULL;
338 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
339 LIBBPF_OPTS(bpf_test_run_opts, topts);
340 struct bpf_link *link = NULL;
341 int i, err, prog_fd;
342
343 skel = kprobe_multi_session__open_and_load();
344 if (!ASSERT_OK_PTR(skel, "kprobe_multi_session__open_and_load"))
345 return;
346
347 skel->bss->pid = getpid();
348
349 err = kprobe_multi_session__attach(skel);
350 if (!ASSERT_OK(err, " kprobe_multi_session__attach"))
351 goto cleanup;
352
353 prog_fd = bpf_program__fd(skel->progs.trigger);
354 err = bpf_prog_test_run_opts(prog_fd, &topts);
355 ASSERT_OK(err, "test_run");
356 ASSERT_EQ(topts.retval, 0, "test_run");
357
358 /* bpf_fentry_test1-4 trigger return probe, result is 2 */
359 for (i = 0; i < 4; i++)
360 ASSERT_EQ(skel->bss->kprobe_session_result[i], 2, "kprobe_session_result");
361
362 /* bpf_fentry_test5-8 trigger only entry probe, result is 1 */
363 for (i = 4; i < 8; i++)
364 ASSERT_EQ(skel->bss->kprobe_session_result[i], 1, "kprobe_session_result");
365
366 cleanup:
367 bpf_link__destroy(link);
368 kprobe_multi_session__destroy(skel);
369 }
370
test_session_cookie_skel_api(void)371 static void test_session_cookie_skel_api(void)
372 {
373 struct kprobe_multi_session_cookie *skel = NULL;
374 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
375 LIBBPF_OPTS(bpf_test_run_opts, topts);
376 struct bpf_link *link = NULL;
377 int err, prog_fd;
378
379 skel = kprobe_multi_session_cookie__open_and_load();
380 if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
381 return;
382
383 skel->bss->pid = getpid();
384
385 err = kprobe_multi_session_cookie__attach(skel);
386 if (!ASSERT_OK(err, " kprobe_multi_wrapper__attach"))
387 goto cleanup;
388
389 prog_fd = bpf_program__fd(skel->progs.trigger);
390 err = bpf_prog_test_run_opts(prog_fd, &topts);
391 ASSERT_OK(err, "test_run");
392 ASSERT_EQ(topts.retval, 0, "test_run");
393
394 ASSERT_EQ(skel->bss->test_kprobe_1_result, 1, "test_kprobe_1_result");
395 ASSERT_EQ(skel->bss->test_kprobe_2_result, 2, "test_kprobe_2_result");
396 ASSERT_EQ(skel->bss->test_kprobe_3_result, 3, "test_kprobe_3_result");
397
398 cleanup:
399 bpf_link__destroy(link);
400 kprobe_multi_session_cookie__destroy(skel);
401 }
402
test_unique_match(void)403 static void test_unique_match(void)
404 {
405 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
406 struct kprobe_multi *skel = NULL;
407 struct bpf_link *link = NULL;
408
409 skel = kprobe_multi__open_and_load();
410 if (!ASSERT_OK_PTR(skel, "kprobe_multi__open_and_load"))
411 return;
412
413 opts.unique_match = true;
414 skel->bss->pid = getpid();
415 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
416 "bpf_fentry_test*", &opts);
417 if (!ASSERT_ERR_PTR(link, "bpf_program__attach_kprobe_multi_opts"))
418 bpf_link__destroy(link);
419
420 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
421 "bpf_fentry_test8*", &opts);
422 if (ASSERT_OK_PTR(link, "bpf_program__attach_kprobe_multi_opts"))
423 bpf_link__destroy(link);
424
425 kprobe_multi__destroy(skel);
426 }
427
do_bench_test(struct kprobe_multi_empty * skel,struct bpf_kprobe_multi_opts * opts)428 static void do_bench_test(struct kprobe_multi_empty *skel, struct bpf_kprobe_multi_opts *opts)
429 {
430 long attach_start_ns, attach_end_ns;
431 long detach_start_ns, detach_end_ns;
432 double attach_delta, detach_delta;
433 struct bpf_link *link = NULL;
434
435 attach_start_ns = get_time_ns();
436 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_empty,
437 NULL, opts);
438 attach_end_ns = get_time_ns();
439
440 if (!ASSERT_OK_PTR(link, "bpf_program__attach_kprobe_multi_opts"))
441 return;
442
443 detach_start_ns = get_time_ns();
444 bpf_link__destroy(link);
445 detach_end_ns = get_time_ns();
446
447 attach_delta = (attach_end_ns - attach_start_ns) / 1000000000.0;
448 detach_delta = (detach_end_ns - detach_start_ns) / 1000000000.0;
449
450 printf("%s: found %lu functions\n", __func__, opts->cnt);
451 printf("%s: attached in %7.3lfs\n", __func__, attach_delta);
452 printf("%s: detached in %7.3lfs\n", __func__, detach_delta);
453 }
454
test_kprobe_multi_bench_attach(bool kernel)455 static void test_kprobe_multi_bench_attach(bool kernel)
456 {
457 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
458 struct kprobe_multi_empty *skel = NULL;
459 struct ksyms *ksyms = NULL;
460
461 if (!ASSERT_OK(bpf_get_ksyms(&ksyms, kernel), "bpf_get_ksyms"))
462 return;
463
464 skel = kprobe_multi_empty__open_and_load();
465 if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
466 goto cleanup;
467
468 opts.syms = (const char **)ksyms->filtered_syms;
469 opts.cnt = ksyms->filtered_cnt;
470
471 do_bench_test(skel, &opts);
472
473 cleanup:
474 kprobe_multi_empty__destroy(skel);
475 free_kallsyms_local(ksyms);
476 }
477
test_kprobe_multi_bench_attach_addr(bool kernel)478 static void test_kprobe_multi_bench_attach_addr(bool kernel)
479 {
480 LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
481 struct kprobe_multi_empty *skel = NULL;
482 unsigned long *addrs = NULL;
483 size_t cnt = 0;
484 int err;
485
486 err = bpf_get_addrs(&addrs, &cnt, kernel);
487 if (err == -ENOENT) {
488 test__skip();
489 return;
490 }
491
492 if (!ASSERT_OK(err, "bpf_get_addrs"))
493 return;
494
495 skel = kprobe_multi_empty__open_and_load();
496 if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
497 goto cleanup;
498
499 opts.addrs = addrs;
500 opts.cnt = cnt;
501
502 do_bench_test(skel, &opts);
503
504 cleanup:
505 kprobe_multi_empty__destroy(skel);
506 free(addrs);
507 }
508
test_attach_override(void)509 static void test_attach_override(void)
510 {
511 struct kprobe_multi_override *skel = NULL;
512 struct bpf_link *link = NULL;
513
514 skel = kprobe_multi_override__open_and_load();
515 if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
516 goto cleanup;
517
518 /* The test_override calls bpf_override_return so it should fail
519 * to attach to bpf_fentry_test1 function, which is not on error
520 * injection list.
521 */
522 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,
523 "bpf_fentry_test1", NULL);
524 if (!ASSERT_ERR_PTR(link, "override_attached_bpf_fentry_test1")) {
525 bpf_link__destroy(link);
526 goto cleanup;
527 }
528
529 /* The should_fail_bio function is on error injection list,
530 * attach should succeed.
531 */
532 link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,
533 "should_fail_bio", NULL);
534 if (!ASSERT_OK_PTR(link, "override_attached_should_fail_bio"))
535 goto cleanup;
536
537 bpf_link__destroy(link);
538
539 cleanup:
540 kprobe_multi_override__destroy(skel);
541 }
542
test_override(void)543 static void test_override(void)
544 {
545 struct kprobe_multi_override *skel = NULL;
546 int err;
547
548 skel = kprobe_multi_override__open_and_load();
549 if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
550 goto cleanup;
551
552 skel->bss->pid = getpid();
553
554 /* no override */
555 err = prctl(0xffff, 0);
556 ASSERT_EQ(err, -1, "err");
557
558 /* kprobe.multi override */
559 skel->links.test_override = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,
560 SYS_PREFIX "sys_prctl", NULL);
561 if (!ASSERT_OK_PTR(skel->links.test_override, "bpf_program__attach_kprobe_multi_opts"))
562 goto cleanup;
563
564 err = prctl(0xffff, 0);
565 ASSERT_EQ(err, 123, "err");
566
567 bpf_link__destroy(skel->links.test_override);
568 skel->links.test_override = NULL;
569
570 /* kprobe override */
571 skel->links.test_kprobe_override = bpf_program__attach_kprobe(skel->progs.test_kprobe_override,
572 false, SYS_PREFIX "sys_prctl");
573 if (!ASSERT_OK_PTR(skel->links.test_kprobe_override, "bpf_program__attach_kprobe"))
574 goto cleanup;
575
576 err = prctl(0xffff, 0);
577 ASSERT_EQ(err, 123, "err");
578
579 cleanup:
580 kprobe_multi_override__destroy(skel);
581 }
582
583 #ifdef __x86_64__
test_attach_write_ctx(void)584 static void test_attach_write_ctx(void)
585 {
586 struct kprobe_write_ctx *skel = NULL;
587 struct bpf_link *link = NULL;
588
589 skel = kprobe_write_ctx__open_and_load();
590 if (!ASSERT_OK_PTR(skel, "kprobe_write_ctx__open_and_load"))
591 return;
592
593 link = bpf_program__attach_kprobe_opts(skel->progs.kprobe_multi_write_ctx,
594 "bpf_fentry_test1", NULL);
595 if (!ASSERT_ERR_PTR(link, "bpf_program__attach_kprobe_opts"))
596 bpf_link__destroy(link);
597
598 kprobe_write_ctx__destroy(skel);
599 }
600 #else
test_attach_write_ctx(void)601 static void test_attach_write_ctx(void)
602 {
603 test__skip();
604 }
605 #endif
606
serial_test_kprobe_multi_bench_attach(void)607 void serial_test_kprobe_multi_bench_attach(void)
608 {
609 if (test__start_subtest("kernel"))
610 test_kprobe_multi_bench_attach(true);
611 if (test__start_subtest("modules"))
612 test_kprobe_multi_bench_attach(false);
613 if (test__start_subtest("kernel"))
614 test_kprobe_multi_bench_attach_addr(true);
615 if (test__start_subtest("modules"))
616 test_kprobe_multi_bench_attach_addr(false);
617 }
618
test_kprobe_multi_test(void)619 void test_kprobe_multi_test(void)
620 {
621 if (!ASSERT_OK(load_kallsyms(), "load_kallsyms"))
622 return;
623
624 if (test__start_subtest("skel_api"))
625 test_skel_api();
626 if (test__start_subtest("link_api_addrs"))
627 test_link_api_syms();
628 if (test__start_subtest("link_api_syms"))
629 test_link_api_addrs();
630 if (test__start_subtest("attach_api_pattern"))
631 test_attach_api_pattern();
632 if (test__start_subtest("attach_api_addrs"))
633 test_attach_api_addrs();
634 if (test__start_subtest("attach_api_syms"))
635 test_attach_api_syms();
636 if (test__start_subtest("attach_api_fails"))
637 test_attach_api_fails();
638 if (test__start_subtest("attach_override"))
639 test_attach_override();
640 if (test__start_subtest("override"))
641 test_override();
642 if (test__start_subtest("session"))
643 test_session_skel_api();
644 if (test__start_subtest("session_cookie"))
645 test_session_cookie_skel_api();
646 if (test__start_subtest("unique_match"))
647 test_unique_match();
648 if (test__start_subtest("attach_write_ctx"))
649 test_attach_write_ctx();
650 RUN_TESTS(kprobe_multi_verifier);
651 }
652