xref: /linux/tools/testing/selftests/bpf/prog_tests/stacktrace_ips.c (revision cbba5d1b53fb82209feacb459edecb1ef8427119)
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