Skip to content

Commit 75b3715

Browse files
olsajiriAlexei Starovoitov
authored andcommitted
selftests/bpf: Add uprobe_multi skel test
Adding uprobe_multi test for skeleton load/attach functions, to test skeleton auto attach for uprobe_multi link. Test that bpf_get_func_ip works properly for uprobe_multi attachment. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20230809083440.3209381-20-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent 3830d04 commit 75b3715

2 files changed

Lines changed: 167 additions & 0 deletions

File tree

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <unistd.h>
4+
#include <test_progs.h>
5+
#include "uprobe_multi.skel.h"
6+
7+
static char test_data[] = "test_data";
8+
9+
noinline void uprobe_multi_func_1(void)
10+
{
11+
asm volatile ("");
12+
}
13+
14+
noinline void uprobe_multi_func_2(void)
15+
{
16+
asm volatile ("");
17+
}
18+
19+
noinline void uprobe_multi_func_3(void)
20+
{
21+
asm volatile ("");
22+
}
23+
24+
static void uprobe_multi_test_run(struct uprobe_multi *skel)
25+
{
26+
skel->bss->uprobe_multi_func_1_addr = (__u64) uprobe_multi_func_1;
27+
skel->bss->uprobe_multi_func_2_addr = (__u64) uprobe_multi_func_2;
28+
skel->bss->uprobe_multi_func_3_addr = (__u64) uprobe_multi_func_3;
29+
30+
skel->bss->user_ptr = test_data;
31+
skel->bss->pid = getpid();
32+
33+
/* trigger all probes */
34+
uprobe_multi_func_1();
35+
uprobe_multi_func_2();
36+
uprobe_multi_func_3();
37+
38+
/*
39+
* There are 2 entry and 2 exit probe called for each uprobe_multi_func_[123]
40+
* function and each slepable probe (6) increments uprobe_multi_sleep_result.
41+
*/
42+
ASSERT_EQ(skel->bss->uprobe_multi_func_1_result, 2, "uprobe_multi_func_1_result");
43+
ASSERT_EQ(skel->bss->uprobe_multi_func_2_result, 2, "uprobe_multi_func_2_result");
44+
ASSERT_EQ(skel->bss->uprobe_multi_func_3_result, 2, "uprobe_multi_func_3_result");
45+
46+
ASSERT_EQ(skel->bss->uretprobe_multi_func_1_result, 2, "uretprobe_multi_func_1_result");
47+
ASSERT_EQ(skel->bss->uretprobe_multi_func_2_result, 2, "uretprobe_multi_func_2_result");
48+
ASSERT_EQ(skel->bss->uretprobe_multi_func_3_result, 2, "uretprobe_multi_func_3_result");
49+
50+
ASSERT_EQ(skel->bss->uprobe_multi_sleep_result, 6, "uprobe_multi_sleep_result");
51+
}
52+
53+
static void test_skel_api(void)
54+
{
55+
struct uprobe_multi *skel = NULL;
56+
int err;
57+
58+
skel = uprobe_multi__open_and_load();
59+
if (!ASSERT_OK_PTR(skel, "uprobe_multi__open_and_load"))
60+
goto cleanup;
61+
62+
err = uprobe_multi__attach(skel);
63+
if (!ASSERT_OK(err, "uprobe_multi__attach"))
64+
goto cleanup;
65+
66+
uprobe_multi_test_run(skel);
67+
68+
cleanup:
69+
uprobe_multi__destroy(skel);
70+
}
71+
72+
void test_uprobe_multi_test(void)
73+
{
74+
if (test__start_subtest("skel_api"))
75+
test_skel_api();
76+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#include <linux/bpf.h>
3+
#include <bpf/bpf_helpers.h>
4+
#include <bpf/bpf_tracing.h>
5+
#include <stdbool.h>
6+
7+
char _license[] SEC("license") = "GPL";
8+
9+
__u64 uprobe_multi_func_1_addr = 0;
10+
__u64 uprobe_multi_func_2_addr = 0;
11+
__u64 uprobe_multi_func_3_addr = 0;
12+
13+
__u64 uprobe_multi_func_1_result = 0;
14+
__u64 uprobe_multi_func_2_result = 0;
15+
__u64 uprobe_multi_func_3_result = 0;
16+
17+
__u64 uretprobe_multi_func_1_result = 0;
18+
__u64 uretprobe_multi_func_2_result = 0;
19+
__u64 uretprobe_multi_func_3_result = 0;
20+
21+
__u64 uprobe_multi_sleep_result = 0;
22+
23+
int pid = 0;
24+
bool test_cookie = false;
25+
void *user_ptr = 0;
26+
27+
static __always_inline bool verify_sleepable_user_copy(void)
28+
{
29+
char data[9];
30+
31+
bpf_copy_from_user(data, sizeof(data), user_ptr);
32+
return bpf_strncmp(data, sizeof(data), "test_data") == 0;
33+
}
34+
35+
static void uprobe_multi_check(void *ctx, bool is_return, bool is_sleep)
36+
{
37+
if (bpf_get_current_pid_tgid() >> 32 != pid)
38+
return;
39+
40+
__u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
41+
__u64 addr = bpf_get_func_ip(ctx);
42+
43+
#define SET(__var, __addr, __cookie) ({ \
44+
if (addr == __addr && \
45+
(!test_cookie || (cookie == __cookie))) \
46+
__var += 1; \
47+
})
48+
49+
if (is_return) {
50+
SET(uretprobe_multi_func_1_result, uprobe_multi_func_1_addr, 2);
51+
SET(uretprobe_multi_func_2_result, uprobe_multi_func_2_addr, 3);
52+
SET(uretprobe_multi_func_3_result, uprobe_multi_func_3_addr, 1);
53+
} else {
54+
SET(uprobe_multi_func_1_result, uprobe_multi_func_1_addr, 3);
55+
SET(uprobe_multi_func_2_result, uprobe_multi_func_2_addr, 1);
56+
SET(uprobe_multi_func_3_result, uprobe_multi_func_3_addr, 2);
57+
}
58+
59+
#undef SET
60+
61+
if (is_sleep && verify_sleepable_user_copy())
62+
uprobe_multi_sleep_result += 1;
63+
}
64+
65+
SEC("uprobe.multi//proc/self/exe:uprobe_multi_func_*")
66+
int uprobe(struct pt_regs *ctx)
67+
{
68+
uprobe_multi_check(ctx, false, false);
69+
return 0;
70+
}
71+
72+
SEC("uretprobe.multi//proc/self/exe:uprobe_multi_func_*")
73+
int uretprobe(struct pt_regs *ctx)
74+
{
75+
uprobe_multi_check(ctx, true, false);
76+
return 0;
77+
}
78+
79+
SEC("uprobe.multi.s//proc/self/exe:uprobe_multi_func_*")
80+
int uprobe_sleep(struct pt_regs *ctx)
81+
{
82+
uprobe_multi_check(ctx, false, true);
83+
return 0;
84+
}
85+
86+
SEC("uretprobe.multi.s//proc/self/exe:uprobe_multi_func_*")
87+
int uretprobe_sleep(struct pt_regs *ctx)
88+
{
89+
uprobe_multi_check(ctx, true, true);
90+
return 0;
91+
}

0 commit comments

Comments
 (0)