1f7a11eecSJiri Olsa // SPDX-License-Identifier: GPL-2.0
2f7a11eecSJiri Olsa #include <test_progs.h>
3f7a11eecSJiri Olsa #include "kprobe_multi.skel.h"
4f7a11eecSJiri Olsa #include "trace_helpers.h"
55b6c7e5cSJiri Olsa #include "kprobe_multi_empty.skel.h"
67182e564SJiri Olsa #include "kprobe_multi_override.skel.h"
70983b169SJiri Olsa #include "kprobe_multi_session.skel.h"
8*a3a51133SJiri Olsa #include "kprobe_multi_session_cookie.skel.h"
95b6c7e5cSJiri Olsa #include "bpf/libbpf_internal.h"
105b6c7e5cSJiri Olsa #include "bpf/hashmap.h"
11f7a11eecSJiri Olsa
kprobe_multi_test_run(struct kprobe_multi * skel,bool test_return)129271a0c7SJiri Olsa static void kprobe_multi_test_run(struct kprobe_multi *skel, bool test_return)
13f7a11eecSJiri Olsa {
14f7a11eecSJiri Olsa LIBBPF_OPTS(bpf_test_run_opts, topts);
15f7a11eecSJiri Olsa int err, prog_fd;
16f7a11eecSJiri Olsa
17f7a11eecSJiri Olsa prog_fd = bpf_program__fd(skel->progs.trigger);
18f7a11eecSJiri Olsa err = bpf_prog_test_run_opts(prog_fd, &topts);
19f7a11eecSJiri Olsa ASSERT_OK(err, "test_run");
20f7a11eecSJiri Olsa ASSERT_EQ(topts.retval, 0, "test_run");
21f7a11eecSJiri Olsa
22f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test1_result, 1, "kprobe_test1_result");
23f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test2_result, 1, "kprobe_test2_result");
24f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test3_result, 1, "kprobe_test3_result");
25f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test4_result, 1, "kprobe_test4_result");
26f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test5_result, 1, "kprobe_test5_result");
27f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test6_result, 1, "kprobe_test6_result");
28f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test7_result, 1, "kprobe_test7_result");
29f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kprobe_test8_result, 1, "kprobe_test8_result");
30f7a11eecSJiri Olsa
319271a0c7SJiri Olsa if (test_return) {
32f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test1_result, 1, "kretprobe_test1_result");
33f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test2_result, 1, "kretprobe_test2_result");
34f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test3_result, 1, "kretprobe_test3_result");
35f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test4_result, 1, "kretprobe_test4_result");
36f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test5_result, 1, "kretprobe_test5_result");
37f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test6_result, 1, "kretprobe_test6_result");
38f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test7_result, 1, "kretprobe_test7_result");
39f7a11eecSJiri Olsa ASSERT_EQ(skel->bss->kretprobe_test8_result, 1, "kretprobe_test8_result");
40f7a11eecSJiri Olsa }
419271a0c7SJiri Olsa }
42f7a11eecSJiri Olsa
test_skel_api(void)43f7a11eecSJiri Olsa static void test_skel_api(void)
44f7a11eecSJiri Olsa {
45f7a11eecSJiri Olsa struct kprobe_multi *skel = NULL;
46f7a11eecSJiri Olsa int err;
47f7a11eecSJiri Olsa
48f7a11eecSJiri Olsa skel = kprobe_multi__open_and_load();
49f7a11eecSJiri Olsa if (!ASSERT_OK_PTR(skel, "kprobe_multi__open_and_load"))
50f7a11eecSJiri Olsa goto cleanup;
51f7a11eecSJiri Olsa
52f7a11eecSJiri Olsa skel->bss->pid = getpid();
53f7a11eecSJiri Olsa err = kprobe_multi__attach(skel);
54f7a11eecSJiri Olsa if (!ASSERT_OK(err, "kprobe_multi__attach"))
55f7a11eecSJiri Olsa goto cleanup;
56f7a11eecSJiri Olsa
579271a0c7SJiri Olsa kprobe_multi_test_run(skel, true);
58f7a11eecSJiri Olsa
59f7a11eecSJiri Olsa cleanup:
60f7a11eecSJiri Olsa kprobe_multi__destroy(skel);
61f7a11eecSJiri Olsa }
62f7a11eecSJiri Olsa
test_link_api(struct bpf_link_create_opts * opts)63f7a11eecSJiri Olsa static void test_link_api(struct bpf_link_create_opts *opts)
64f7a11eecSJiri Olsa {
65f7a11eecSJiri Olsa int prog_fd, link1_fd = -1, link2_fd = -1;
66f7a11eecSJiri Olsa struct kprobe_multi *skel = NULL;
67f7a11eecSJiri Olsa
68f7a11eecSJiri Olsa skel = kprobe_multi__open_and_load();
69f7a11eecSJiri Olsa if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
70f7a11eecSJiri Olsa goto cleanup;
71f7a11eecSJiri Olsa
72f7a11eecSJiri Olsa skel->bss->pid = getpid();
73f7a11eecSJiri Olsa prog_fd = bpf_program__fd(skel->progs.test_kprobe);
74f7a11eecSJiri Olsa link1_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, opts);
75f7a11eecSJiri Olsa if (!ASSERT_GE(link1_fd, 0, "link_fd"))
76f7a11eecSJiri Olsa goto cleanup;
77f7a11eecSJiri Olsa
78f7a11eecSJiri Olsa opts->kprobe_multi.flags = BPF_F_KPROBE_MULTI_RETURN;
79f7a11eecSJiri Olsa prog_fd = bpf_program__fd(skel->progs.test_kretprobe);
80f7a11eecSJiri Olsa link2_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, opts);
81f7a11eecSJiri Olsa if (!ASSERT_GE(link2_fd, 0, "link_fd"))
82f7a11eecSJiri Olsa goto cleanup;
83f7a11eecSJiri Olsa
849271a0c7SJiri Olsa kprobe_multi_test_run(skel, true);
85f7a11eecSJiri Olsa
86f7a11eecSJiri Olsa cleanup:
87f7a11eecSJiri Olsa if (link1_fd != -1)
88f7a11eecSJiri Olsa close(link1_fd);
89f7a11eecSJiri Olsa if (link2_fd != -1)
90f7a11eecSJiri Olsa close(link2_fd);
91f7a11eecSJiri Olsa kprobe_multi__destroy(skel);
92f7a11eecSJiri Olsa }
93f7a11eecSJiri Olsa
94f7a11eecSJiri Olsa #define GET_ADDR(__sym, __addr) ({ \
95f7a11eecSJiri Olsa __addr = ksym_get_addr(__sym); \
96f7a11eecSJiri Olsa if (!ASSERT_NEQ(__addr, 0, "kallsyms load failed for " #__sym)) \
97f7a11eecSJiri Olsa return; \
98f7a11eecSJiri Olsa })
99f7a11eecSJiri Olsa
test_link_api_addrs(void)100f7a11eecSJiri Olsa static void test_link_api_addrs(void)
101f7a11eecSJiri Olsa {
102f7a11eecSJiri Olsa LIBBPF_OPTS(bpf_link_create_opts, opts);
103f7a11eecSJiri Olsa unsigned long long addrs[8];
104f7a11eecSJiri Olsa
105f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test1", addrs[0]);
106f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test2", addrs[1]);
107f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test3", addrs[2]);
108f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test4", addrs[3]);
109f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test5", addrs[4]);
110f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test6", addrs[5]);
111f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test7", addrs[6]);
112f7a11eecSJiri Olsa GET_ADDR("bpf_fentry_test8", addrs[7]);
113f7a11eecSJiri Olsa
114f7a11eecSJiri Olsa opts.kprobe_multi.addrs = (const unsigned long*) addrs;
115f7a11eecSJiri Olsa opts.kprobe_multi.cnt = ARRAY_SIZE(addrs);
116f7a11eecSJiri Olsa test_link_api(&opts);
117f7a11eecSJiri Olsa }
118f7a11eecSJiri Olsa
test_link_api_syms(void)119f7a11eecSJiri Olsa static void test_link_api_syms(void)
120f7a11eecSJiri Olsa {
121f7a11eecSJiri Olsa LIBBPF_OPTS(bpf_link_create_opts, opts);
122f7a11eecSJiri Olsa const char *syms[8] = {
123f7a11eecSJiri Olsa "bpf_fentry_test1",
124f7a11eecSJiri Olsa "bpf_fentry_test2",
125f7a11eecSJiri Olsa "bpf_fentry_test3",
126f7a11eecSJiri Olsa "bpf_fentry_test4",
127f7a11eecSJiri Olsa "bpf_fentry_test5",
128f7a11eecSJiri Olsa "bpf_fentry_test6",
129f7a11eecSJiri Olsa "bpf_fentry_test7",
130f7a11eecSJiri Olsa "bpf_fentry_test8",
131f7a11eecSJiri Olsa };
132f7a11eecSJiri Olsa
133f7a11eecSJiri Olsa opts.kprobe_multi.syms = syms;
134f7a11eecSJiri Olsa opts.kprobe_multi.cnt = ARRAY_SIZE(syms);
135f7a11eecSJiri Olsa test_link_api(&opts);
136f7a11eecSJiri Olsa }
137f7a11eecSJiri Olsa
1389271a0c7SJiri Olsa static void
test_attach_api(const char * pattern,struct bpf_kprobe_multi_opts * opts)1399271a0c7SJiri Olsa test_attach_api(const char *pattern, struct bpf_kprobe_multi_opts *opts)
1409271a0c7SJiri Olsa {
1419271a0c7SJiri Olsa struct bpf_link *link1 = NULL, *link2 = NULL;
1429271a0c7SJiri Olsa struct kprobe_multi *skel = NULL;
1439271a0c7SJiri Olsa
1449271a0c7SJiri Olsa skel = kprobe_multi__open_and_load();
1459271a0c7SJiri Olsa if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
1469271a0c7SJiri Olsa goto cleanup;
1479271a0c7SJiri Olsa
1489271a0c7SJiri Olsa skel->bss->pid = getpid();
14932c03c49SAndrii Nakryiko link1 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
1509271a0c7SJiri Olsa pattern, opts);
1519271a0c7SJiri Olsa if (!ASSERT_OK_PTR(link1, "bpf_program__attach_kprobe_multi_opts"))
1529271a0c7SJiri Olsa goto cleanup;
1539271a0c7SJiri Olsa
1549271a0c7SJiri Olsa if (opts) {
1559271a0c7SJiri Olsa opts->retprobe = true;
15632c03c49SAndrii Nakryiko link2 = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kretprobe_manual,
1579271a0c7SJiri Olsa pattern, opts);
1589271a0c7SJiri Olsa if (!ASSERT_OK_PTR(link2, "bpf_program__attach_kprobe_multi_opts"))
1599271a0c7SJiri Olsa goto cleanup;
1609271a0c7SJiri Olsa }
1619271a0c7SJiri Olsa
1629271a0c7SJiri Olsa kprobe_multi_test_run(skel, !!opts);
1639271a0c7SJiri Olsa
1649271a0c7SJiri Olsa cleanup:
1659271a0c7SJiri Olsa bpf_link__destroy(link2);
1669271a0c7SJiri Olsa bpf_link__destroy(link1);
1679271a0c7SJiri Olsa kprobe_multi__destroy(skel);
1689271a0c7SJiri Olsa }
1699271a0c7SJiri Olsa
test_attach_api_pattern(void)1709271a0c7SJiri Olsa static void test_attach_api_pattern(void)
1719271a0c7SJiri Olsa {
1729271a0c7SJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
1739271a0c7SJiri Olsa
1749271a0c7SJiri Olsa test_attach_api("bpf_fentry_test*", &opts);
1759271a0c7SJiri Olsa test_attach_api("bpf_fentry_test?", NULL);
1769271a0c7SJiri Olsa }
1779271a0c7SJiri Olsa
test_attach_api_addrs(void)1789271a0c7SJiri Olsa static void test_attach_api_addrs(void)
1799271a0c7SJiri Olsa {
1809271a0c7SJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
1819271a0c7SJiri Olsa unsigned long long addrs[8];
1829271a0c7SJiri Olsa
1839271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test1", addrs[0]);
1849271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test2", addrs[1]);
1859271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test3", addrs[2]);
1869271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test4", addrs[3]);
1879271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test5", addrs[4]);
1889271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test6", addrs[5]);
1899271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test7", addrs[6]);
1909271a0c7SJiri Olsa GET_ADDR("bpf_fentry_test8", addrs[7]);
1919271a0c7SJiri Olsa
1929271a0c7SJiri Olsa opts.addrs = (const unsigned long *) addrs;
1939271a0c7SJiri Olsa opts.cnt = ARRAY_SIZE(addrs);
1949271a0c7SJiri Olsa test_attach_api(NULL, &opts);
1959271a0c7SJiri Olsa }
1969271a0c7SJiri Olsa
test_attach_api_syms(void)1979271a0c7SJiri Olsa static void test_attach_api_syms(void)
1989271a0c7SJiri Olsa {
1999271a0c7SJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
2009271a0c7SJiri Olsa const char *syms[8] = {
2019271a0c7SJiri Olsa "bpf_fentry_test1",
2029271a0c7SJiri Olsa "bpf_fentry_test2",
2039271a0c7SJiri Olsa "bpf_fentry_test3",
2049271a0c7SJiri Olsa "bpf_fentry_test4",
2059271a0c7SJiri Olsa "bpf_fentry_test5",
2069271a0c7SJiri Olsa "bpf_fentry_test6",
2079271a0c7SJiri Olsa "bpf_fentry_test7",
2089271a0c7SJiri Olsa "bpf_fentry_test8",
2099271a0c7SJiri Olsa };
2109271a0c7SJiri Olsa
2119271a0c7SJiri Olsa opts.syms = syms;
2129271a0c7SJiri Olsa opts.cnt = ARRAY_SIZE(syms);
2139271a0c7SJiri Olsa test_attach_api(NULL, &opts);
2149271a0c7SJiri Olsa }
2159271a0c7SJiri Olsa
test_attach_api_fails(void)2169271a0c7SJiri Olsa static void test_attach_api_fails(void)
2179271a0c7SJiri Olsa {
2189271a0c7SJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
2199271a0c7SJiri Olsa struct kprobe_multi *skel = NULL;
2209271a0c7SJiri Olsa struct bpf_link *link = NULL;
2219271a0c7SJiri Olsa unsigned long long addrs[2];
2229271a0c7SJiri Olsa const char *syms[2] = {
2239271a0c7SJiri Olsa "bpf_fentry_test1",
2249271a0c7SJiri Olsa "bpf_fentry_test2",
2259271a0c7SJiri Olsa };
2269271a0c7SJiri Olsa __u64 cookies[2];
22700cdcd29SHou Tao int saved_error;
2289271a0c7SJiri Olsa
2299271a0c7SJiri Olsa addrs[0] = ksym_get_addr("bpf_fentry_test1");
2309271a0c7SJiri Olsa addrs[1] = ksym_get_addr("bpf_fentry_test2");
2319271a0c7SJiri Olsa
2329271a0c7SJiri Olsa if (!ASSERT_FALSE(!addrs[0] || !addrs[1], "ksym_get_addr"))
2339271a0c7SJiri Olsa goto cleanup;
2349271a0c7SJiri Olsa
2359271a0c7SJiri Olsa skel = kprobe_multi__open_and_load();
2369271a0c7SJiri Olsa if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
2379271a0c7SJiri Olsa goto cleanup;
2389271a0c7SJiri Olsa
2399271a0c7SJiri Olsa skel->bss->pid = getpid();
2409271a0c7SJiri Olsa
2419271a0c7SJiri Olsa /* fail_1 - pattern and opts NULL */
24232c03c49SAndrii Nakryiko link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
2439271a0c7SJiri Olsa NULL, NULL);
24400cdcd29SHou Tao saved_error = -errno;
2459271a0c7SJiri Olsa if (!ASSERT_ERR_PTR(link, "fail_1"))
2469271a0c7SJiri Olsa goto cleanup;
2479271a0c7SJiri Olsa
24800cdcd29SHou Tao if (!ASSERT_EQ(saved_error, -EINVAL, "fail_1_error"))
2499271a0c7SJiri Olsa goto cleanup;
2509271a0c7SJiri Olsa
2519271a0c7SJiri Olsa /* fail_2 - both addrs and syms set */
2529271a0c7SJiri Olsa opts.addrs = (const unsigned long *) addrs;
2539271a0c7SJiri Olsa opts.syms = syms;
2549271a0c7SJiri Olsa opts.cnt = ARRAY_SIZE(syms);
2559271a0c7SJiri Olsa opts.cookies = NULL;
2569271a0c7SJiri Olsa
25732c03c49SAndrii Nakryiko link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
2589271a0c7SJiri Olsa NULL, &opts);
25900cdcd29SHou Tao saved_error = -errno;
2609271a0c7SJiri Olsa if (!ASSERT_ERR_PTR(link, "fail_2"))
2619271a0c7SJiri Olsa goto cleanup;
2629271a0c7SJiri Olsa
26300cdcd29SHou Tao if (!ASSERT_EQ(saved_error, -EINVAL, "fail_2_error"))
2649271a0c7SJiri Olsa goto cleanup;
2659271a0c7SJiri Olsa
2669271a0c7SJiri Olsa /* fail_3 - pattern and addrs set */
2679271a0c7SJiri Olsa opts.addrs = (const unsigned long *) addrs;
2689271a0c7SJiri Olsa opts.syms = NULL;
2699271a0c7SJiri Olsa opts.cnt = ARRAY_SIZE(syms);
2709271a0c7SJiri Olsa opts.cookies = NULL;
2719271a0c7SJiri Olsa
27232c03c49SAndrii Nakryiko link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
2739271a0c7SJiri Olsa "ksys_*", &opts);
27400cdcd29SHou Tao saved_error = -errno;
2759271a0c7SJiri Olsa if (!ASSERT_ERR_PTR(link, "fail_3"))
2769271a0c7SJiri Olsa goto cleanup;
2779271a0c7SJiri Olsa
27800cdcd29SHou Tao if (!ASSERT_EQ(saved_error, -EINVAL, "fail_3_error"))
2799271a0c7SJiri Olsa goto cleanup;
2809271a0c7SJiri Olsa
2819271a0c7SJiri Olsa /* fail_4 - pattern and cnt set */
2829271a0c7SJiri Olsa opts.addrs = NULL;
2839271a0c7SJiri Olsa opts.syms = NULL;
2849271a0c7SJiri Olsa opts.cnt = ARRAY_SIZE(syms);
2859271a0c7SJiri Olsa opts.cookies = NULL;
2869271a0c7SJiri Olsa
28732c03c49SAndrii Nakryiko link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
2889271a0c7SJiri Olsa "ksys_*", &opts);
28900cdcd29SHou Tao saved_error = -errno;
2909271a0c7SJiri Olsa if (!ASSERT_ERR_PTR(link, "fail_4"))
2919271a0c7SJiri Olsa goto cleanup;
2929271a0c7SJiri Olsa
29300cdcd29SHou Tao if (!ASSERT_EQ(saved_error, -EINVAL, "fail_4_error"))
2949271a0c7SJiri Olsa goto cleanup;
2959271a0c7SJiri Olsa
2969271a0c7SJiri Olsa /* fail_5 - pattern and cookies */
2979271a0c7SJiri Olsa opts.addrs = NULL;
2989271a0c7SJiri Olsa opts.syms = NULL;
2999271a0c7SJiri Olsa opts.cnt = 0;
3009271a0c7SJiri Olsa opts.cookies = cookies;
3019271a0c7SJiri Olsa
30232c03c49SAndrii Nakryiko link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
3039271a0c7SJiri Olsa "ksys_*", &opts);
30400cdcd29SHou Tao saved_error = -errno;
3059271a0c7SJiri Olsa if (!ASSERT_ERR_PTR(link, "fail_5"))
3069271a0c7SJiri Olsa goto cleanup;
3079271a0c7SJiri Olsa
30800cdcd29SHou Tao if (!ASSERT_EQ(saved_error, -EINVAL, "fail_5_error"))
3099271a0c7SJiri Olsa goto cleanup;
3109271a0c7SJiri Olsa
3111467affdSHou Tao /* fail_6 - abnormal cnt */
3121467affdSHou Tao opts.addrs = (const unsigned long *) addrs;
3131467affdSHou Tao opts.syms = NULL;
3141467affdSHou Tao opts.cnt = INT_MAX;
3151467affdSHou Tao opts.cookies = NULL;
3161467affdSHou Tao
3171467affdSHou Tao link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_manual,
3181467affdSHou Tao NULL, &opts);
3191467affdSHou Tao saved_error = -errno;
3201467affdSHou Tao if (!ASSERT_ERR_PTR(link, "fail_6"))
3211467affdSHou Tao goto cleanup;
3221467affdSHou Tao
3231467affdSHou Tao if (!ASSERT_EQ(saved_error, -E2BIG, "fail_6_error"))
3241467affdSHou Tao goto cleanup;
3251467affdSHou Tao
3269271a0c7SJiri Olsa cleanup:
3279271a0c7SJiri Olsa bpf_link__destroy(link);
3289271a0c7SJiri Olsa kprobe_multi__destroy(skel);
3299271a0c7SJiri Olsa }
3309271a0c7SJiri Olsa
test_session_skel_api(void)3310983b169SJiri Olsa static void test_session_skel_api(void)
3320983b169SJiri Olsa {
3330983b169SJiri Olsa struct kprobe_multi_session *skel = NULL;
3340983b169SJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
3350983b169SJiri Olsa LIBBPF_OPTS(bpf_test_run_opts, topts);
3360983b169SJiri Olsa struct bpf_link *link = NULL;
3370983b169SJiri Olsa int i, err, prog_fd;
3380983b169SJiri Olsa
3390983b169SJiri Olsa skel = kprobe_multi_session__open_and_load();
3400983b169SJiri Olsa if (!ASSERT_OK_PTR(skel, "kprobe_multi_session__open_and_load"))
3410983b169SJiri Olsa return;
3420983b169SJiri Olsa
3430983b169SJiri Olsa skel->bss->pid = getpid();
3440983b169SJiri Olsa
3450983b169SJiri Olsa err = kprobe_multi_session__attach(skel);
3460983b169SJiri Olsa if (!ASSERT_OK(err, " kprobe_multi_session__attach"))
3470983b169SJiri Olsa goto cleanup;
3480983b169SJiri Olsa
3490983b169SJiri Olsa prog_fd = bpf_program__fd(skel->progs.trigger);
3500983b169SJiri Olsa err = bpf_prog_test_run_opts(prog_fd, &topts);
3510983b169SJiri Olsa ASSERT_OK(err, "test_run");
3520983b169SJiri Olsa ASSERT_EQ(topts.retval, 0, "test_run");
3530983b169SJiri Olsa
3540983b169SJiri Olsa /* bpf_fentry_test1-4 trigger return probe, result is 2 */
3550983b169SJiri Olsa for (i = 0; i < 4; i++)
3560983b169SJiri Olsa ASSERT_EQ(skel->bss->kprobe_session_result[i], 2, "kprobe_session_result");
3570983b169SJiri Olsa
3580983b169SJiri Olsa /* bpf_fentry_test5-8 trigger only entry probe, result is 1 */
3590983b169SJiri Olsa for (i = 4; i < 8; i++)
3600983b169SJiri Olsa ASSERT_EQ(skel->bss->kprobe_session_result[i], 1, "kprobe_session_result");
3610983b169SJiri Olsa
3620983b169SJiri Olsa cleanup:
3630983b169SJiri Olsa bpf_link__destroy(link);
3640983b169SJiri Olsa kprobe_multi_session__destroy(skel);
3650983b169SJiri Olsa }
3660983b169SJiri Olsa
test_session_cookie_skel_api(void)367*a3a51133SJiri Olsa static void test_session_cookie_skel_api(void)
368*a3a51133SJiri Olsa {
369*a3a51133SJiri Olsa struct kprobe_multi_session_cookie *skel = NULL;
370*a3a51133SJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
371*a3a51133SJiri Olsa LIBBPF_OPTS(bpf_test_run_opts, topts);
372*a3a51133SJiri Olsa struct bpf_link *link = NULL;
373*a3a51133SJiri Olsa int err, prog_fd;
374*a3a51133SJiri Olsa
375*a3a51133SJiri Olsa skel = kprobe_multi_session_cookie__open_and_load();
376*a3a51133SJiri Olsa if (!ASSERT_OK_PTR(skel, "fentry_raw_skel_load"))
377*a3a51133SJiri Olsa return;
378*a3a51133SJiri Olsa
379*a3a51133SJiri Olsa skel->bss->pid = getpid();
380*a3a51133SJiri Olsa
381*a3a51133SJiri Olsa err = kprobe_multi_session_cookie__attach(skel);
382*a3a51133SJiri Olsa if (!ASSERT_OK(err, " kprobe_multi_wrapper__attach"))
383*a3a51133SJiri Olsa goto cleanup;
384*a3a51133SJiri Olsa
385*a3a51133SJiri Olsa prog_fd = bpf_program__fd(skel->progs.trigger);
386*a3a51133SJiri Olsa err = bpf_prog_test_run_opts(prog_fd, &topts);
387*a3a51133SJiri Olsa ASSERT_OK(err, "test_run");
388*a3a51133SJiri Olsa ASSERT_EQ(topts.retval, 0, "test_run");
389*a3a51133SJiri Olsa
390*a3a51133SJiri Olsa ASSERT_EQ(skel->bss->test_kprobe_1_result, 1, "test_kprobe_1_result");
391*a3a51133SJiri Olsa ASSERT_EQ(skel->bss->test_kprobe_2_result, 2, "test_kprobe_2_result");
392*a3a51133SJiri Olsa ASSERT_EQ(skel->bss->test_kprobe_3_result, 3, "test_kprobe_3_result");
393*a3a51133SJiri Olsa
394*a3a51133SJiri Olsa cleanup:
395*a3a51133SJiri Olsa bpf_link__destroy(link);
396*a3a51133SJiri Olsa kprobe_multi_session_cookie__destroy(skel);
397*a3a51133SJiri Olsa }
398*a3a51133SJiri Olsa
symbol_hash(long key,void * ctx __maybe_unused)399c302378bSEduard Zingerman static size_t symbol_hash(long key, void *ctx __maybe_unused)
4005b6c7e5cSJiri Olsa {
4015b6c7e5cSJiri Olsa return str_hash((const char *) key);
4025b6c7e5cSJiri Olsa }
4035b6c7e5cSJiri Olsa
symbol_equal(long key1,long key2,void * ctx __maybe_unused)404c302378bSEduard Zingerman static bool symbol_equal(long key1, long key2, void *ctx __maybe_unused)
4055b6c7e5cSJiri Olsa {
4065b6c7e5cSJiri Olsa return strcmp((const char *) key1, (const char *) key2) == 0;
4075b6c7e5cSJiri Olsa }
4085b6c7e5cSJiri Olsa
is_invalid_entry(char * buf,bool kernel)409d1320649SYonghong Song static bool is_invalid_entry(char *buf, bool kernel)
410d1320649SYonghong Song {
411d1320649SYonghong Song if (kernel && strchr(buf, '['))
412d1320649SYonghong Song return true;
413d1320649SYonghong Song if (!kernel && !strchr(buf, '['))
414d1320649SYonghong Song return true;
415d1320649SYonghong Song return false;
416d1320649SYonghong Song }
417d1320649SYonghong Song
skip_entry(char * name)418d1320649SYonghong Song static bool skip_entry(char *name)
419d1320649SYonghong Song {
420d1320649SYonghong Song /*
421d1320649SYonghong Song * We attach to almost all kernel functions and some of them
422d1320649SYonghong Song * will cause 'suspicious RCU usage' when fprobe is attached
423d1320649SYonghong Song * to them. Filter out the current culprits - arch_cpu_idle
424d1320649SYonghong Song * default_idle and rcu_* functions.
425d1320649SYonghong Song */
426d1320649SYonghong Song if (!strcmp(name, "arch_cpu_idle"))
427d1320649SYonghong Song return true;
428d1320649SYonghong Song if (!strcmp(name, "default_idle"))
429d1320649SYonghong Song return true;
430d1320649SYonghong Song if (!strncmp(name, "rcu_", 4))
431d1320649SYonghong Song return true;
432d1320649SYonghong Song if (!strcmp(name, "bpf_dispatcher_xdp_func"))
433d1320649SYonghong Song return true;
434d1320649SYonghong Song if (!strncmp(name, "__ftrace_invalid_address__",
435d1320649SYonghong Song sizeof("__ftrace_invalid_address__") - 1))
436d1320649SYonghong Song return true;
437d1320649SYonghong Song return false;
438d1320649SYonghong Song }
439d1320649SYonghong Song
4409edaafadSYonghong Song /* Do comparision by ignoring '.llvm.<hash>' suffixes. */
compare_name(const char * name1,const char * name2)4419edaafadSYonghong Song static int compare_name(const char *name1, const char *name2)
4429edaafadSYonghong Song {
4439edaafadSYonghong Song const char *res1, *res2;
4449edaafadSYonghong Song int len1, len2;
4459edaafadSYonghong Song
4469edaafadSYonghong Song res1 = strstr(name1, ".llvm.");
4479edaafadSYonghong Song res2 = strstr(name2, ".llvm.");
4489edaafadSYonghong Song len1 = res1 ? res1 - name1 : strlen(name1);
4499edaafadSYonghong Song len2 = res2 ? res2 - name2 : strlen(name2);
4509edaafadSYonghong Song
4519edaafadSYonghong Song if (len1 == len2)
4529edaafadSYonghong Song return strncmp(name1, name2, len1);
4539edaafadSYonghong Song if (len1 < len2)
4549edaafadSYonghong Song return strncmp(name1, name2, len1) <= 0 ? -1 : 1;
4559edaafadSYonghong Song return strncmp(name1, name2, len2) >= 0 ? 1 : -1;
4569edaafadSYonghong Song }
4579edaafadSYonghong Song
load_kallsyms_compare(const void * p1,const void * p2)4589edaafadSYonghong Song static int load_kallsyms_compare(const void *p1, const void *p2)
4599edaafadSYonghong Song {
4609edaafadSYonghong Song return compare_name(((const struct ksym *)p1)->name, ((const struct ksym *)p2)->name);
4619edaafadSYonghong Song }
4629edaafadSYonghong Song
search_kallsyms_compare(const void * p1,const struct ksym * p2)4639edaafadSYonghong Song static int search_kallsyms_compare(const void *p1, const struct ksym *p2)
4649edaafadSYonghong Song {
4659edaafadSYonghong Song return compare_name(p1, p2->name);
4669edaafadSYonghong Song }
4679edaafadSYonghong Song
get_syms(char *** symsp,size_t * cntp,bool kernel)468edac4b5bSJiri Olsa static int get_syms(char ***symsp, size_t *cntp, bool kernel)
4695b6c7e5cSJiri Olsa {
4709edaafadSYonghong Song size_t cap = 0, cnt = 0;
4719edaafadSYonghong Song char *name = NULL, *ksym_name, **syms = NULL;
4725b6c7e5cSJiri Olsa struct hashmap *map;
4739edaafadSYonghong Song struct ksyms *ksyms;
4749edaafadSYonghong Song struct ksym *ks;
4755b6c7e5cSJiri Olsa char buf[256];
4765b6c7e5cSJiri Olsa FILE *f;
477c46a1220SAndrii Nakryiko int err = 0;
4785b6c7e5cSJiri Olsa
4799edaafadSYonghong Song ksyms = load_kallsyms_custom_local(load_kallsyms_compare);
4809edaafadSYonghong Song if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_custom_local"))
4819edaafadSYonghong Song return -EINVAL;
4829edaafadSYonghong Song
4835b6c7e5cSJiri Olsa /*
4845b6c7e5cSJiri Olsa * The available_filter_functions contains many duplicates,
4855b6c7e5cSJiri Olsa * but other than that all symbols are usable in kprobe multi
4865b6c7e5cSJiri Olsa * interface.
4875b6c7e5cSJiri Olsa * Filtering out duplicates by using hashmap__add, which won't
4885b6c7e5cSJiri Olsa * add existing entry.
4895b6c7e5cSJiri Olsa */
490ab4c15feSRoss Zwisler
491ab4c15feSRoss Zwisler if (access("/sys/kernel/tracing/trace", F_OK) == 0)
492ab4c15feSRoss Zwisler f = fopen("/sys/kernel/tracing/available_filter_functions", "r");
493ab4c15feSRoss Zwisler else
4945b6c7e5cSJiri Olsa f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r");
495ab4c15feSRoss Zwisler
4965b6c7e5cSJiri Olsa if (!f)
4975b6c7e5cSJiri Olsa return -EINVAL;
4985b6c7e5cSJiri Olsa
4995b6c7e5cSJiri Olsa map = hashmap__new(symbol_hash, symbol_equal, NULL);
500fd0ad6f1SYonghong Song if (IS_ERR(map)) {
501fd0ad6f1SYonghong Song err = libbpf_get_error(map);
5025b6c7e5cSJiri Olsa goto error;
503fd0ad6f1SYonghong Song }
5045b6c7e5cSJiri Olsa
5055b6c7e5cSJiri Olsa while (fgets(buf, sizeof(buf), f)) {
506d1320649SYonghong Song if (is_invalid_entry(buf, kernel))
5075b6c7e5cSJiri Olsa continue;
5086d2e21dcSXu Kuohai
5096d2e21dcSXu Kuohai free(name);
5105b6c7e5cSJiri Olsa if (sscanf(buf, "%ms$*[^\n]\n", &name) != 1)
5115b6c7e5cSJiri Olsa continue;
512d1320649SYonghong Song if (skip_entry(name))
51373006702SJiri Olsa continue;
5146d2e21dcSXu Kuohai
5159edaafadSYonghong Song ks = search_kallsyms_custom_local(ksyms, name, search_kallsyms_compare);
5169edaafadSYonghong Song if (!ks) {
5179edaafadSYonghong Song err = -EINVAL;
5189edaafadSYonghong Song goto error;
5199edaafadSYonghong Song }
5209edaafadSYonghong Song
5219edaafadSYonghong Song ksym_name = ks->name;
5229edaafadSYonghong Song err = hashmap__add(map, ksym_name, 0);
523c4d3b488SManu Bretelle if (err == -EEXIST) {
524c4d3b488SManu Bretelle err = 0;
5255b6c7e5cSJiri Olsa continue;
526c4d3b488SManu Bretelle }
5276d2e21dcSXu Kuohai if (err)
5285b6c7e5cSJiri Olsa goto error;
5296d2e21dcSXu Kuohai
5305b6c7e5cSJiri Olsa err = libbpf_ensure_mem((void **) &syms, &cap,
5315b6c7e5cSJiri Olsa sizeof(*syms), cnt + 1);
5326d2e21dcSXu Kuohai if (err)
5335b6c7e5cSJiri Olsa goto error;
5346d2e21dcSXu Kuohai
5359edaafadSYonghong Song syms[cnt++] = ksym_name;
5365b6c7e5cSJiri Olsa }
5375b6c7e5cSJiri Olsa
5385b6c7e5cSJiri Olsa *symsp = syms;
5395b6c7e5cSJiri Olsa *cntp = cnt;
5405b6c7e5cSJiri Olsa
5415b6c7e5cSJiri Olsa error:
5426d2e21dcSXu Kuohai free(name);
5435b6c7e5cSJiri Olsa fclose(f);
5445b6c7e5cSJiri Olsa hashmap__free(map);
5459edaafadSYonghong Song if (err)
5465b6c7e5cSJiri Olsa free(syms);
5475b6c7e5cSJiri Olsa return err;
5485b6c7e5cSJiri Olsa }
5495b6c7e5cSJiri Olsa
get_addrs(unsigned long ** addrsp,size_t * cntp,bool kernel)5506302bdebSYonghong Song static int get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel)
5516302bdebSYonghong Song {
5526302bdebSYonghong Song unsigned long *addr, *addrs, *tmp_addrs;
5536302bdebSYonghong Song int err = 0, max_cnt, inc_cnt;
5546302bdebSYonghong Song char *name = NULL;
5556302bdebSYonghong Song size_t cnt = 0;
5566302bdebSYonghong Song char buf[256];
5576302bdebSYonghong Song FILE *f;
5586302bdebSYonghong Song
5596302bdebSYonghong Song if (access("/sys/kernel/tracing/trace", F_OK) == 0)
5606302bdebSYonghong Song f = fopen("/sys/kernel/tracing/available_filter_functions_addrs", "r");
5616302bdebSYonghong Song else
5626302bdebSYonghong Song f = fopen("/sys/kernel/debug/tracing/available_filter_functions_addrs", "r");
5636302bdebSYonghong Song
5646302bdebSYonghong Song if (!f)
5656302bdebSYonghong Song return -ENOENT;
5666302bdebSYonghong Song
5676302bdebSYonghong Song /* In my local setup, the number of entries is 50k+ so Let us initially
5686302bdebSYonghong Song * allocate space to hold 64k entries. If 64k is not enough, incrementally
5696302bdebSYonghong Song * increase 1k each time.
5706302bdebSYonghong Song */
5716302bdebSYonghong Song max_cnt = 65536;
5726302bdebSYonghong Song inc_cnt = 1024;
5736302bdebSYonghong Song addrs = malloc(max_cnt * sizeof(long));
5746302bdebSYonghong Song if (addrs == NULL) {
5756302bdebSYonghong Song err = -ENOMEM;
5766302bdebSYonghong Song goto error;
5776302bdebSYonghong Song }
5786302bdebSYonghong Song
5796302bdebSYonghong Song while (fgets(buf, sizeof(buf), f)) {
5806302bdebSYonghong Song if (is_invalid_entry(buf, kernel))
5816302bdebSYonghong Song continue;
5826302bdebSYonghong Song
5836302bdebSYonghong Song free(name);
5846302bdebSYonghong Song if (sscanf(buf, "%p %ms$*[^\n]\n", &addr, &name) != 2)
5856302bdebSYonghong Song continue;
5866302bdebSYonghong Song if (skip_entry(name))
5876302bdebSYonghong Song continue;
5886302bdebSYonghong Song
5896302bdebSYonghong Song if (cnt == max_cnt) {
5906302bdebSYonghong Song max_cnt += inc_cnt;
5916302bdebSYonghong Song tmp_addrs = realloc(addrs, max_cnt);
5926302bdebSYonghong Song if (!tmp_addrs) {
5936302bdebSYonghong Song err = -ENOMEM;
5946302bdebSYonghong Song goto error;
5956302bdebSYonghong Song }
5966302bdebSYonghong Song addrs = tmp_addrs;
5976302bdebSYonghong Song }
5986302bdebSYonghong Song
5996302bdebSYonghong Song addrs[cnt++] = (unsigned long)addr;
6006302bdebSYonghong Song }
6016302bdebSYonghong Song
6026302bdebSYonghong Song *addrsp = addrs;
6036302bdebSYonghong Song *cntp = cnt;
6046302bdebSYonghong Song
6056302bdebSYonghong Song error:
6066302bdebSYonghong Song free(name);
6076302bdebSYonghong Song fclose(f);
6086302bdebSYonghong Song if (err)
6096302bdebSYonghong Song free(addrs);
6106302bdebSYonghong Song return err;
6116302bdebSYonghong Song }
6126302bdebSYonghong Song
do_bench_test(struct kprobe_multi_empty * skel,struct bpf_kprobe_multi_opts * opts)613d1320649SYonghong Song static void do_bench_test(struct kprobe_multi_empty *skel, struct bpf_kprobe_multi_opts *opts)
6145b6c7e5cSJiri Olsa {
6155b6c7e5cSJiri Olsa long attach_start_ns, attach_end_ns;
6165b6c7e5cSJiri Olsa long detach_start_ns, detach_end_ns;
6175b6c7e5cSJiri Olsa double attach_delta, detach_delta;
6185b6c7e5cSJiri Olsa struct bpf_link *link = NULL;
619d1320649SYonghong Song
620d1320649SYonghong Song attach_start_ns = get_time_ns();
621d1320649SYonghong Song link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_kprobe_empty,
622d1320649SYonghong Song NULL, opts);
623d1320649SYonghong Song attach_end_ns = get_time_ns();
624d1320649SYonghong Song
625d1320649SYonghong Song if (!ASSERT_OK_PTR(link, "bpf_program__attach_kprobe_multi_opts"))
626d1320649SYonghong Song return;
627d1320649SYonghong Song
628d1320649SYonghong Song detach_start_ns = get_time_ns();
629d1320649SYonghong Song bpf_link__destroy(link);
630d1320649SYonghong Song detach_end_ns = get_time_ns();
631d1320649SYonghong Song
632d1320649SYonghong Song attach_delta = (attach_end_ns - attach_start_ns) / 1000000000.0;
633d1320649SYonghong Song detach_delta = (detach_end_ns - detach_start_ns) / 1000000000.0;
634d1320649SYonghong Song
635d1320649SYonghong Song printf("%s: found %lu functions\n", __func__, opts->cnt);
636d1320649SYonghong Song printf("%s: attached in %7.3lfs\n", __func__, attach_delta);
637d1320649SYonghong Song printf("%s: detached in %7.3lfs\n", __func__, detach_delta);
638d1320649SYonghong Song }
639d1320649SYonghong Song
test_kprobe_multi_bench_attach(bool kernel)640d1320649SYonghong Song static void test_kprobe_multi_bench_attach(bool kernel)
641d1320649SYonghong Song {
642d1320649SYonghong Song LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
643d1320649SYonghong Song struct kprobe_multi_empty *skel = NULL;
6445b6c7e5cSJiri Olsa char **syms = NULL;
6459edaafadSYonghong Song size_t cnt = 0;
6465b6c7e5cSJiri Olsa
647edac4b5bSJiri Olsa if (!ASSERT_OK(get_syms(&syms, &cnt, kernel), "get_syms"))
6485b6c7e5cSJiri Olsa return;
6495b6c7e5cSJiri Olsa
6505b6c7e5cSJiri Olsa skel = kprobe_multi_empty__open_and_load();
6515b6c7e5cSJiri Olsa if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
6525b6c7e5cSJiri Olsa goto cleanup;
6535b6c7e5cSJiri Olsa
6545b6c7e5cSJiri Olsa opts.syms = (const char **) syms;
6555b6c7e5cSJiri Olsa opts.cnt = cnt;
6565b6c7e5cSJiri Olsa
657d1320649SYonghong Song do_bench_test(skel, &opts);
6585b6c7e5cSJiri Olsa
6595b6c7e5cSJiri Olsa cleanup:
6605b6c7e5cSJiri Olsa kprobe_multi_empty__destroy(skel);
6619edaafadSYonghong Song if (syms)
6625b6c7e5cSJiri Olsa free(syms);
6635b6c7e5cSJiri Olsa }
6645b6c7e5cSJiri Olsa
test_kprobe_multi_bench_attach_addr(bool kernel)6656302bdebSYonghong Song static void test_kprobe_multi_bench_attach_addr(bool kernel)
6666302bdebSYonghong Song {
6676302bdebSYonghong Song LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
6686302bdebSYonghong Song struct kprobe_multi_empty *skel = NULL;
6696302bdebSYonghong Song unsigned long *addrs = NULL;
6706302bdebSYonghong Song size_t cnt = 0;
6716302bdebSYonghong Song int err;
6726302bdebSYonghong Song
6736302bdebSYonghong Song err = get_addrs(&addrs, &cnt, kernel);
6746302bdebSYonghong Song if (err == -ENOENT) {
6756302bdebSYonghong Song test__skip();
6766302bdebSYonghong Song return;
6776302bdebSYonghong Song }
6786302bdebSYonghong Song
6796302bdebSYonghong Song if (!ASSERT_OK(err, "get_addrs"))
6806302bdebSYonghong Song return;
6816302bdebSYonghong Song
6826302bdebSYonghong Song skel = kprobe_multi_empty__open_and_load();
6836302bdebSYonghong Song if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
6846302bdebSYonghong Song goto cleanup;
6856302bdebSYonghong Song
6866302bdebSYonghong Song opts.addrs = addrs;
6876302bdebSYonghong Song opts.cnt = cnt;
6886302bdebSYonghong Song
6896302bdebSYonghong Song do_bench_test(skel, &opts);
6906302bdebSYonghong Song
6916302bdebSYonghong Song cleanup:
6926302bdebSYonghong Song kprobe_multi_empty__destroy(skel);
6936302bdebSYonghong Song free(addrs);
6946302bdebSYonghong Song }
6956302bdebSYonghong Song
test_attach_override(void)6968a19edd4SJiri Olsa static void test_attach_override(void)
6977182e564SJiri Olsa {
6987182e564SJiri Olsa struct kprobe_multi_override *skel = NULL;
6997182e564SJiri Olsa struct bpf_link *link = NULL;
7007182e564SJiri Olsa
7017182e564SJiri Olsa skel = kprobe_multi_override__open_and_load();
7027182e564SJiri Olsa if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
7037182e564SJiri Olsa goto cleanup;
7047182e564SJiri Olsa
7057182e564SJiri Olsa /* The test_override calls bpf_override_return so it should fail
7067182e564SJiri Olsa * to attach to bpf_fentry_test1 function, which is not on error
7077182e564SJiri Olsa * injection list.
7087182e564SJiri Olsa */
7097182e564SJiri Olsa link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,
7107182e564SJiri Olsa "bpf_fentry_test1", NULL);
7117182e564SJiri Olsa if (!ASSERT_ERR_PTR(link, "override_attached_bpf_fentry_test1")) {
7127182e564SJiri Olsa bpf_link__destroy(link);
7137182e564SJiri Olsa goto cleanup;
7147182e564SJiri Olsa }
7157182e564SJiri Olsa
7167182e564SJiri Olsa /* The should_fail_bio function is on error injection list,
7177182e564SJiri Olsa * attach should succeed.
7187182e564SJiri Olsa */
7197182e564SJiri Olsa link = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,
7207182e564SJiri Olsa "should_fail_bio", NULL);
7217182e564SJiri Olsa if (!ASSERT_OK_PTR(link, "override_attached_should_fail_bio"))
7227182e564SJiri Olsa goto cleanup;
7237182e564SJiri Olsa
7247182e564SJiri Olsa bpf_link__destroy(link);
7257182e564SJiri Olsa
7267182e564SJiri Olsa cleanup:
7277182e564SJiri Olsa kprobe_multi_override__destroy(skel);
7287182e564SJiri Olsa }
7297182e564SJiri Olsa
serial_test_kprobe_multi_bench_attach(void)730edac4b5bSJiri Olsa void serial_test_kprobe_multi_bench_attach(void)
731edac4b5bSJiri Olsa {
732edac4b5bSJiri Olsa if (test__start_subtest("kernel"))
733edac4b5bSJiri Olsa test_kprobe_multi_bench_attach(true);
734edac4b5bSJiri Olsa if (test__start_subtest("modules"))
735edac4b5bSJiri Olsa test_kprobe_multi_bench_attach(false);
7366302bdebSYonghong Song if (test__start_subtest("kernel"))
7376302bdebSYonghong Song test_kprobe_multi_bench_attach_addr(true);
7386302bdebSYonghong Song if (test__start_subtest("modules"))
7396302bdebSYonghong Song test_kprobe_multi_bench_attach_addr(false);
740edac4b5bSJiri Olsa }
741edac4b5bSJiri Olsa
test_kprobe_multi_test(void)742f7a11eecSJiri Olsa void test_kprobe_multi_test(void)
743f7a11eecSJiri Olsa {
744f7a11eecSJiri Olsa if (!ASSERT_OK(load_kallsyms(), "load_kallsyms"))
745f7a11eecSJiri Olsa return;
746f7a11eecSJiri Olsa
747f7a11eecSJiri Olsa if (test__start_subtest("skel_api"))
748f7a11eecSJiri Olsa test_skel_api();
749f7a11eecSJiri Olsa if (test__start_subtest("link_api_addrs"))
750f7a11eecSJiri Olsa test_link_api_syms();
751f7a11eecSJiri Olsa if (test__start_subtest("link_api_syms"))
752f7a11eecSJiri Olsa test_link_api_addrs();
7539271a0c7SJiri Olsa if (test__start_subtest("attach_api_pattern"))
7549271a0c7SJiri Olsa test_attach_api_pattern();
7559271a0c7SJiri Olsa if (test__start_subtest("attach_api_addrs"))
7569271a0c7SJiri Olsa test_attach_api_addrs();
7579271a0c7SJiri Olsa if (test__start_subtest("attach_api_syms"))
7589271a0c7SJiri Olsa test_attach_api_syms();
7599271a0c7SJiri Olsa if (test__start_subtest("attach_api_fails"))
7609271a0c7SJiri Olsa test_attach_api_fails();
7617182e564SJiri Olsa if (test__start_subtest("attach_override"))
7627182e564SJiri Olsa test_attach_override();
7630983b169SJiri Olsa if (test__start_subtest("session"))
7640983b169SJiri Olsa test_session_skel_api();
765*a3a51133SJiri Olsa if (test__start_subtest("session_cookie"))
766*a3a51133SJiri Olsa test_session_cookie_skel_api();
767f7a11eecSJiri Olsa }
768