xref: /openbmc/linux/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1*5a8ea82fSAndrii Nakryiko /* SPDX-License-Identifier: GPL-2.0 */
2*5a8ea82fSAndrii Nakryiko /* Copyright (c) 2021 Facebook */
3*5a8ea82fSAndrii Nakryiko 
4*5a8ea82fSAndrii Nakryiko #include <test_progs.h>
5*5a8ea82fSAndrii Nakryiko #include <bpf/btf.h>
6*5a8ea82fSAndrii Nakryiko 
test_libbpf_probe_prog_types(void)7*5a8ea82fSAndrii Nakryiko void test_libbpf_probe_prog_types(void)
8*5a8ea82fSAndrii Nakryiko {
9*5a8ea82fSAndrii Nakryiko 	struct btf *btf;
10*5a8ea82fSAndrii Nakryiko 	const struct btf_type *t;
11*5a8ea82fSAndrii Nakryiko 	const struct btf_enum *e;
12*5a8ea82fSAndrii Nakryiko 	int i, n, id;
13*5a8ea82fSAndrii Nakryiko 
14*5a8ea82fSAndrii Nakryiko 	btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
15*5a8ea82fSAndrii Nakryiko 	if (!ASSERT_OK_PTR(btf, "btf_parse"))
16*5a8ea82fSAndrii Nakryiko 		return;
17*5a8ea82fSAndrii Nakryiko 
18*5a8ea82fSAndrii Nakryiko 	/* find enum bpf_prog_type and enumerate each value */
19*5a8ea82fSAndrii Nakryiko 	id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM);
20*5a8ea82fSAndrii Nakryiko 	if (!ASSERT_GT(id, 0, "bpf_prog_type_id"))
21*5a8ea82fSAndrii Nakryiko 		goto cleanup;
22*5a8ea82fSAndrii Nakryiko 	t = btf__type_by_id(btf, id);
23*5a8ea82fSAndrii Nakryiko 	if (!ASSERT_OK_PTR(t, "bpf_prog_type_enum"))
24*5a8ea82fSAndrii Nakryiko 		goto cleanup;
25*5a8ea82fSAndrii Nakryiko 
26*5a8ea82fSAndrii Nakryiko 	for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
27*5a8ea82fSAndrii Nakryiko 		const char *prog_type_name = btf__str_by_offset(btf, e->name_off);
28*5a8ea82fSAndrii Nakryiko 		enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val;
29*5a8ea82fSAndrii Nakryiko 		int res;
30*5a8ea82fSAndrii Nakryiko 
31*5a8ea82fSAndrii Nakryiko 		if (prog_type == BPF_PROG_TYPE_UNSPEC)
32*5a8ea82fSAndrii Nakryiko 			continue;
33*5a8ea82fSAndrii Nakryiko 
34*5a8ea82fSAndrii Nakryiko 		if (!test__start_subtest(prog_type_name))
35*5a8ea82fSAndrii Nakryiko 			continue;
36*5a8ea82fSAndrii Nakryiko 
37*5a8ea82fSAndrii Nakryiko 		res = libbpf_probe_bpf_prog_type(prog_type, NULL);
38*5a8ea82fSAndrii Nakryiko 		ASSERT_EQ(res, 1, prog_type_name);
39*5a8ea82fSAndrii Nakryiko 	}
40*5a8ea82fSAndrii Nakryiko 
41*5a8ea82fSAndrii Nakryiko cleanup:
42*5a8ea82fSAndrii Nakryiko 	btf__free(btf);
43*5a8ea82fSAndrii Nakryiko }
44*5a8ea82fSAndrii Nakryiko 
test_libbpf_probe_map_types(void)45*5a8ea82fSAndrii Nakryiko void test_libbpf_probe_map_types(void)
46*5a8ea82fSAndrii Nakryiko {
47*5a8ea82fSAndrii Nakryiko 	struct btf *btf;
48*5a8ea82fSAndrii Nakryiko 	const struct btf_type *t;
49*5a8ea82fSAndrii Nakryiko 	const struct btf_enum *e;
50*5a8ea82fSAndrii Nakryiko 	int i, n, id;
51*5a8ea82fSAndrii Nakryiko 
52*5a8ea82fSAndrii Nakryiko 	btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
53*5a8ea82fSAndrii Nakryiko 	if (!ASSERT_OK_PTR(btf, "btf_parse"))
54*5a8ea82fSAndrii Nakryiko 		return;
55*5a8ea82fSAndrii Nakryiko 
56*5a8ea82fSAndrii Nakryiko 	/* find enum bpf_map_type and enumerate each value */
57*5a8ea82fSAndrii Nakryiko 	id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM);
58*5a8ea82fSAndrii Nakryiko 	if (!ASSERT_GT(id, 0, "bpf_map_type_id"))
59*5a8ea82fSAndrii Nakryiko 		goto cleanup;
60*5a8ea82fSAndrii Nakryiko 	t = btf__type_by_id(btf, id);
61*5a8ea82fSAndrii Nakryiko 	if (!ASSERT_OK_PTR(t, "bpf_map_type_enum"))
62*5a8ea82fSAndrii Nakryiko 		goto cleanup;
63*5a8ea82fSAndrii Nakryiko 
64*5a8ea82fSAndrii Nakryiko 	for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) {
65*5a8ea82fSAndrii Nakryiko 		const char *map_type_name = btf__str_by_offset(btf, e->name_off);
66*5a8ea82fSAndrii Nakryiko 		enum bpf_map_type map_type = (enum bpf_map_type)e->val;
67*5a8ea82fSAndrii Nakryiko 		int res;
68*5a8ea82fSAndrii Nakryiko 
69*5a8ea82fSAndrii Nakryiko 		if (map_type == BPF_MAP_TYPE_UNSPEC)
70*5a8ea82fSAndrii Nakryiko 			continue;
71*5a8ea82fSAndrii Nakryiko 
72*5a8ea82fSAndrii Nakryiko 		if (!test__start_subtest(map_type_name))
73*5a8ea82fSAndrii Nakryiko 			continue;
74*5a8ea82fSAndrii Nakryiko 
75*5a8ea82fSAndrii Nakryiko 		res = libbpf_probe_bpf_map_type(map_type, NULL);
76*5a8ea82fSAndrii Nakryiko 		ASSERT_EQ(res, 1, map_type_name);
77*5a8ea82fSAndrii Nakryiko 	}
78*5a8ea82fSAndrii Nakryiko 
79*5a8ea82fSAndrii Nakryiko cleanup:
80*5a8ea82fSAndrii Nakryiko 	btf__free(btf);
81*5a8ea82fSAndrii Nakryiko }
82*5a8ea82fSAndrii Nakryiko 
test_libbpf_probe_helpers(void)83*5a8ea82fSAndrii Nakryiko void test_libbpf_probe_helpers(void)
84*5a8ea82fSAndrii Nakryiko {
85*5a8ea82fSAndrii Nakryiko #define CASE(prog, helper, supp) {			\
86*5a8ea82fSAndrii Nakryiko 	.prog_type_name = "BPF_PROG_TYPE_" # prog,	\
87*5a8ea82fSAndrii Nakryiko 	.helper_name = "bpf_" # helper,			\
88*5a8ea82fSAndrii Nakryiko 	.prog_type = BPF_PROG_TYPE_ ## prog,		\
89*5a8ea82fSAndrii Nakryiko 	.helper_id = BPF_FUNC_ ## helper,		\
90*5a8ea82fSAndrii Nakryiko 	.supported = supp,				\
91*5a8ea82fSAndrii Nakryiko }
92*5a8ea82fSAndrii Nakryiko 	const struct case_def {
93*5a8ea82fSAndrii Nakryiko 		const char *prog_type_name;
94*5a8ea82fSAndrii Nakryiko 		const char *helper_name;
95*5a8ea82fSAndrii Nakryiko 		enum bpf_prog_type prog_type;
96*5a8ea82fSAndrii Nakryiko 		enum bpf_func_id helper_id;
97*5a8ea82fSAndrii Nakryiko 		bool supported;
98*5a8ea82fSAndrii Nakryiko 	} cases[] = {
99*5a8ea82fSAndrii Nakryiko 		CASE(KPROBE, unspec, false),
100*5a8ea82fSAndrii Nakryiko 		CASE(KPROBE, map_lookup_elem, true),
101*5a8ea82fSAndrii Nakryiko 		CASE(KPROBE, loop, true),
102*5a8ea82fSAndrii Nakryiko 
103*5a8ea82fSAndrii Nakryiko 		CASE(KPROBE, ktime_get_coarse_ns, false),
104*5a8ea82fSAndrii Nakryiko 		CASE(SOCKET_FILTER, ktime_get_coarse_ns, true),
105*5a8ea82fSAndrii Nakryiko 
106*5a8ea82fSAndrii Nakryiko 		CASE(KPROBE, sys_bpf, false),
107*5a8ea82fSAndrii Nakryiko 		CASE(SYSCALL, sys_bpf, true),
108*5a8ea82fSAndrii Nakryiko 	};
109*5a8ea82fSAndrii Nakryiko 	size_t case_cnt = ARRAY_SIZE(cases), i;
110*5a8ea82fSAndrii Nakryiko 	char buf[128];
111*5a8ea82fSAndrii Nakryiko 
112*5a8ea82fSAndrii Nakryiko 	for (i = 0; i < case_cnt; i++) {
113*5a8ea82fSAndrii Nakryiko 		const struct case_def *d = &cases[i];
114*5a8ea82fSAndrii Nakryiko 		int res;
115*5a8ea82fSAndrii Nakryiko 
116*5a8ea82fSAndrii Nakryiko 		snprintf(buf, sizeof(buf), "%s+%s", d->prog_type_name, d->helper_name);
117*5a8ea82fSAndrii Nakryiko 
118*5a8ea82fSAndrii Nakryiko 		if (!test__start_subtest(buf))
119*5a8ea82fSAndrii Nakryiko 			continue;
120*5a8ea82fSAndrii Nakryiko 
121*5a8ea82fSAndrii Nakryiko 		res = libbpf_probe_bpf_helper(d->prog_type, d->helper_id, NULL);
122*5a8ea82fSAndrii Nakryiko 		ASSERT_EQ(res, d->supported, buf);
123*5a8ea82fSAndrii Nakryiko 	}
124*5a8ea82fSAndrii Nakryiko }
125