Skip to content

Commit 95226f5

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
selftests/bpf: add __arg_ctx BTF rewrite test
Add a test validating that libbpf uploads BTF and func_info with rewritten type information for arguments of global subprogs that are marked with __arg_ctx tag. Suggested-by: Eduard Zingerman <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 67fe459 commit 95226f5

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

tools/testing/selftests/bpf/prog_tests/test_global_funcs.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,109 @@
2020
#include "test_global_func17.skel.h"
2121
#include "test_global_func_ctx_args.skel.h"
2222

23+
#include "bpf/libbpf_internal.h"
24+
#include "btf_helpers.h"
25+
26+
static void check_ctx_arg_type(const struct btf *btf, const struct btf_param *p)
27+
{
28+
const struct btf_type *t;
29+
const char *s;
30+
31+
t = btf__type_by_id(btf, p->type);
32+
if (!ASSERT_EQ(btf_kind(t), BTF_KIND_PTR, "ptr_t"))
33+
return;
34+
35+
s = btf_type_raw_dump(btf, t->type);
36+
if (!ASSERT_HAS_SUBSTR(s, "STRUCT 'bpf_perf_event_data' size=0 vlen=0",
37+
"ctx_struct_t"))
38+
return;
39+
}
40+
41+
static void subtest_ctx_arg_rewrite(void)
42+
{
43+
struct test_global_func_ctx_args *skel = NULL;
44+
struct bpf_prog_info info;
45+
char func_info_buf[1024] __attribute__((aligned(8)));
46+
struct bpf_func_info_min *rec;
47+
struct btf *btf = NULL;
48+
__u32 info_len = sizeof(info);
49+
int err, fd, i;
50+
51+
skel = test_global_func_ctx_args__open();
52+
if (!ASSERT_OK_PTR(skel, "skel_open"))
53+
return;
54+
55+
bpf_program__set_autoload(skel->progs.arg_tag_ctx_perf, true);
56+
57+
err = test_global_func_ctx_args__load(skel);
58+
if (!ASSERT_OK(err, "skel_load"))
59+
goto out;
60+
61+
memset(&info, 0, sizeof(info));
62+
info.func_info = ptr_to_u64(&func_info_buf);
63+
info.nr_func_info = 3;
64+
info.func_info_rec_size = sizeof(struct bpf_func_info_min);
65+
66+
fd = bpf_program__fd(skel->progs.arg_tag_ctx_perf);
67+
err = bpf_prog_get_info_by_fd(fd, &info, &info_len);
68+
if (!ASSERT_OK(err, "prog_info"))
69+
goto out;
70+
71+
if (!ASSERT_EQ(info.nr_func_info, 3, "nr_func_info"))
72+
goto out;
73+
74+
btf = btf__load_from_kernel_by_id(info.btf_id);
75+
if (!ASSERT_OK_PTR(btf, "obj_kern_btf"))
76+
goto out;
77+
78+
rec = (struct bpf_func_info_min *)func_info_buf;
79+
for (i = 0; i < info.nr_func_info; i++, rec = (void *)rec + info.func_info_rec_size) {
80+
const struct btf_type *fn_t, *proto_t;
81+
const char *name;
82+
83+
if (rec->insn_off == 0)
84+
continue; /* main prog, skip */
85+
86+
fn_t = btf__type_by_id(btf, rec->type_id);
87+
if (!ASSERT_OK_PTR(fn_t, "fn_type"))
88+
goto out;
89+
if (!ASSERT_EQ(btf_kind(fn_t), BTF_KIND_FUNC, "fn_type_kind"))
90+
goto out;
91+
proto_t = btf__type_by_id(btf, fn_t->type);
92+
if (!ASSERT_OK_PTR(proto_t, "proto_type"))
93+
goto out;
94+
95+
name = btf__name_by_offset(btf, fn_t->name_off);
96+
if (strcmp(name, "subprog_ctx_tag") == 0) {
97+
/* int subprog_ctx_tag(void *ctx __arg_ctx) */
98+
if (!ASSERT_EQ(btf_vlen(proto_t), 1, "arg_cnt"))
99+
goto out;
100+
101+
/* arg 0 is PTR -> STRUCT bpf_perf_event_data */
102+
check_ctx_arg_type(btf, &btf_params(proto_t)[0]);
103+
} else if (strcmp(name, "subprog_multi_ctx_tags") == 0) {
104+
/* int subprog_multi_ctx_tags(void *ctx1 __arg_ctx,
105+
* struct my_struct *mem,
106+
* void *ctx2 __arg_ctx)
107+
*/
108+
if (!ASSERT_EQ(btf_vlen(proto_t), 3, "arg_cnt"))
109+
goto out;
110+
111+
/* arg 0 is PTR -> STRUCT bpf_perf_event_data */
112+
check_ctx_arg_type(btf, &btf_params(proto_t)[0]);
113+
/* arg 2 is PTR -> STRUCT bpf_perf_event_data */
114+
check_ctx_arg_type(btf, &btf_params(proto_t)[2]);
115+
} else {
116+
ASSERT_FAIL("unexpected subprog %s", name);
117+
goto out;
118+
}
119+
}
120+
121+
out:
122+
btf__free(btf);
123+
test_global_func_ctx_args__destroy(skel);
124+
}
125+
23126
void test_test_global_funcs(void)
24127
{
25128
RUN_TESTS(test_global_func1);
@@ -40,4 +143,7 @@ void test_test_global_funcs(void)
40143
RUN_TESTS(test_global_func16);
41144
RUN_TESTS(test_global_func17);
42145
RUN_TESTS(test_global_func_ctx_args);
146+
147+
if (test__start_subtest("ctx_arg_rewrite"))
148+
subtest_ctx_arg_rewrite();
43149
}

0 commit comments

Comments
 (0)