1c9e208faSJiri Olsa // SPDX-License-Identifier: GPL-2.0
2c9e208faSJiri Olsa #include <test_progs.h>
3c9e208faSJiri Olsa #include "stacktrace_ips.skel.h"
4c9e208faSJiri Olsa
5c9e208faSJiri Olsa #ifdef __x86_64__
check_stacktrace_ips(int fd,__u32 key,int cnt,...)6c9e208faSJiri Olsa static int check_stacktrace_ips(int fd, __u32 key, int cnt, ...)
7c9e208faSJiri Olsa {
8c9e208faSJiri Olsa __u64 ips[PERF_MAX_STACK_DEPTH];
9c9e208faSJiri Olsa struct ksyms *ksyms = NULL;
10c9e208faSJiri Olsa int i, err = 0;
11c9e208faSJiri Olsa va_list args;
12c9e208faSJiri Olsa
13c9e208faSJiri Olsa /* sorted by addr */
14c9e208faSJiri Olsa ksyms = load_kallsyms_local();
15c9e208faSJiri Olsa if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_local"))
16c9e208faSJiri Olsa return -1;
17c9e208faSJiri Olsa
18c9e208faSJiri Olsa /* unlikely, but... */
19c9e208faSJiri Olsa if (!ASSERT_LT(cnt, PERF_MAX_STACK_DEPTH, "check_max"))
20c9e208faSJiri Olsa return -1;
21c9e208faSJiri Olsa
22c9e208faSJiri Olsa err = bpf_map_lookup_elem(fd, &key, ips);
23c9e208faSJiri Olsa if (err)
24c9e208faSJiri Olsa goto out;
25c9e208faSJiri Olsa
26c9e208faSJiri Olsa /*
27c9e208faSJiri Olsa * Compare all symbols provided via arguments with stacktrace ips,
28c9e208faSJiri Olsa * and their related symbol addresses.t
29c9e208faSJiri Olsa */
30c9e208faSJiri Olsa va_start(args, cnt);
31c9e208faSJiri Olsa
32c9e208faSJiri Olsa for (i = 0; i < cnt; i++) {
33c9e208faSJiri Olsa unsigned long val;
34c9e208faSJiri Olsa struct ksym *ksym;
35c9e208faSJiri Olsa
36c9e208faSJiri Olsa val = va_arg(args, unsigned long);
37c9e208faSJiri Olsa ksym = ksym_search_local(ksyms, ips[i]);
38c9e208faSJiri Olsa if (!ASSERT_OK_PTR(ksym, "ksym_search_local"))
39c9e208faSJiri Olsa break;
40c9e208faSJiri Olsa ASSERT_EQ(ksym->addr, val, "stack_cmp");
41c9e208faSJiri Olsa }
42c9e208faSJiri Olsa
43c9e208faSJiri Olsa va_end(args);
44c9e208faSJiri Olsa
45c9e208faSJiri Olsa out:
46c9e208faSJiri Olsa free_kallsyms_local(ksyms);
47c9e208faSJiri Olsa return err;
48c9e208faSJiri Olsa }
49c9e208faSJiri Olsa
test_stacktrace_ips_kprobe_multi(bool retprobe)50c9e208faSJiri Olsa static void test_stacktrace_ips_kprobe_multi(bool retprobe)
51c9e208faSJiri Olsa {
52c9e208faSJiri Olsa LIBBPF_OPTS(bpf_kprobe_multi_opts, opts,
53c9e208faSJiri Olsa .retprobe = retprobe
54c9e208faSJiri Olsa );
55c9e208faSJiri Olsa LIBBPF_OPTS(bpf_test_run_opts, topts);
56c9e208faSJiri Olsa struct stacktrace_ips *skel;
57c9e208faSJiri Olsa
58c9e208faSJiri Olsa skel = stacktrace_ips__open_and_load();
59c9e208faSJiri Olsa if (!ASSERT_OK_PTR(skel, "stacktrace_ips__open_and_load"))
60c9e208faSJiri Olsa return;
61c9e208faSJiri Olsa
62c9e208faSJiri Olsa if (!skel->kconfig->CONFIG_UNWINDER_ORC) {
63c9e208faSJiri Olsa test__skip();
64c9e208faSJiri Olsa goto cleanup;
65c9e208faSJiri Olsa }
66c9e208faSJiri Olsa
67c9e208faSJiri Olsa skel->links.kprobe_multi_test = bpf_program__attach_kprobe_multi_opts(
68c9e208faSJiri Olsa skel->progs.kprobe_multi_test,
69c9e208faSJiri Olsa "bpf_testmod_stacktrace_test", &opts);
70c9e208faSJiri Olsa if (!ASSERT_OK_PTR(skel->links.kprobe_multi_test, "bpf_program__attach_kprobe_multi_opts"))
71c9e208faSJiri Olsa goto cleanup;
72c9e208faSJiri Olsa
73c9e208faSJiri Olsa trigger_module_test_read(1);
74c9e208faSJiri Olsa
75c9e208faSJiri Olsa load_kallsyms();
76c9e208faSJiri Olsa
77c9e208faSJiri Olsa check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 4,
78c9e208faSJiri Olsa ksym_get_addr("bpf_testmod_stacktrace_test_3"),
79c9e208faSJiri Olsa ksym_get_addr("bpf_testmod_stacktrace_test_2"),
80c9e208faSJiri Olsa ksym_get_addr("bpf_testmod_stacktrace_test_1"),
81c9e208faSJiri Olsa ksym_get_addr("bpf_testmod_test_read"));
82c9e208faSJiri Olsa
83c9e208faSJiri Olsa cleanup:
84c9e208faSJiri Olsa stacktrace_ips__destroy(skel);
85c9e208faSJiri Olsa }
86c9e208faSJiri Olsa
test_stacktrace_ips_raw_tp(void)87*3490d299SJiri Olsa static void test_stacktrace_ips_raw_tp(void)
88*3490d299SJiri Olsa {
89*3490d299SJiri Olsa __u32 info_len = sizeof(struct bpf_prog_info);
90*3490d299SJiri Olsa LIBBPF_OPTS(bpf_test_run_opts, topts);
91*3490d299SJiri Olsa struct bpf_prog_info info = {};
92*3490d299SJiri Olsa struct stacktrace_ips *skel;
93*3490d299SJiri Olsa __u64 bpf_prog_ksym = 0;
94*3490d299SJiri Olsa int err;
95*3490d299SJiri Olsa
96*3490d299SJiri Olsa skel = stacktrace_ips__open_and_load();
97*3490d299SJiri Olsa if (!ASSERT_OK_PTR(skel, "stacktrace_ips__open_and_load"))
98*3490d299SJiri Olsa return;
99*3490d299SJiri Olsa
100*3490d299SJiri Olsa if (!skel->kconfig->CONFIG_UNWINDER_ORC) {
101*3490d299SJiri Olsa test__skip();
102*3490d299SJiri Olsa goto cleanup;
103*3490d299SJiri Olsa }
104*3490d299SJiri Olsa
105*3490d299SJiri Olsa skel->links.rawtp_test = bpf_program__attach_raw_tracepoint(
106*3490d299SJiri Olsa skel->progs.rawtp_test,
107*3490d299SJiri Olsa "bpf_testmod_test_read");
108*3490d299SJiri Olsa if (!ASSERT_OK_PTR(skel->links.rawtp_test, "bpf_program__attach_raw_tracepoint"))
109*3490d299SJiri Olsa goto cleanup;
110*3490d299SJiri Olsa
111*3490d299SJiri Olsa /* get bpf program address */
112*3490d299SJiri Olsa info.jited_ksyms = ptr_to_u64(&bpf_prog_ksym);
113*3490d299SJiri Olsa info.nr_jited_ksyms = 1;
114*3490d299SJiri Olsa err = bpf_prog_get_info_by_fd(bpf_program__fd(skel->progs.rawtp_test),
115*3490d299SJiri Olsa &info, &info_len);
116*3490d299SJiri Olsa if (!ASSERT_OK(err, "bpf_prog_get_info_by_fd"))
117*3490d299SJiri Olsa goto cleanup;
118*3490d299SJiri Olsa
119*3490d299SJiri Olsa trigger_module_test_read(1);
120*3490d299SJiri Olsa
121*3490d299SJiri Olsa load_kallsyms();
122*3490d299SJiri Olsa
123*3490d299SJiri Olsa check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 2,
124*3490d299SJiri Olsa bpf_prog_ksym,
125*3490d299SJiri Olsa ksym_get_addr("bpf_trace_run2"));
126*3490d299SJiri Olsa
127*3490d299SJiri Olsa cleanup:
128*3490d299SJiri Olsa stacktrace_ips__destroy(skel);
129*3490d299SJiri Olsa }
130*3490d299SJiri Olsa
__test_stacktrace_ips(void)131c9e208faSJiri Olsa static void __test_stacktrace_ips(void)
132c9e208faSJiri Olsa {
133c9e208faSJiri Olsa if (test__start_subtest("kprobe_multi"))
134c9e208faSJiri Olsa test_stacktrace_ips_kprobe_multi(false);
135c9e208faSJiri Olsa if (test__start_subtest("kretprobe_multi"))
136c9e208faSJiri Olsa test_stacktrace_ips_kprobe_multi(true);
137*3490d299SJiri Olsa if (test__start_subtest("raw_tp"))
138*3490d299SJiri Olsa test_stacktrace_ips_raw_tp();
139c9e208faSJiri Olsa }
140c9e208faSJiri Olsa #else
__test_stacktrace_ips(void)141c9e208faSJiri Olsa static void __test_stacktrace_ips(void)
142c9e208faSJiri Olsa {
143c9e208faSJiri Olsa test__skip();
144c9e208faSJiri Olsa }
145c9e208faSJiri Olsa #endif
146c9e208faSJiri Olsa
test_stacktrace_ips(void)147c9e208faSJiri Olsa void test_stacktrace_ips(void)
148c9e208faSJiri Olsa {
149c9e208faSJiri Olsa __test_stacktrace_ips();
150c9e208faSJiri Olsa }
151