mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Running api and link tests also with pid filter and checking the probe gets executed only for specific pid. Spawning extra process to trigger attached uprobes and checking we get correct counts from executed programs. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20230809083440.3209381-28-jolsa@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
95 lines
2.3 KiB
C
95 lines
2.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#include <stdbool.h>
|
|
|
|
char _license[] SEC("license") = "GPL";
|
|
|
|
__u64 uprobe_multi_func_1_addr = 0;
|
|
__u64 uprobe_multi_func_2_addr = 0;
|
|
__u64 uprobe_multi_func_3_addr = 0;
|
|
|
|
__u64 uprobe_multi_func_1_result = 0;
|
|
__u64 uprobe_multi_func_2_result = 0;
|
|
__u64 uprobe_multi_func_3_result = 0;
|
|
|
|
__u64 uretprobe_multi_func_1_result = 0;
|
|
__u64 uretprobe_multi_func_2_result = 0;
|
|
__u64 uretprobe_multi_func_3_result = 0;
|
|
|
|
__u64 uprobe_multi_sleep_result = 0;
|
|
|
|
int pid = 0;
|
|
int child_pid = 0;
|
|
|
|
bool test_cookie = false;
|
|
void *user_ptr = 0;
|
|
|
|
static __always_inline bool verify_sleepable_user_copy(void)
|
|
{
|
|
char data[9];
|
|
|
|
bpf_copy_from_user(data, sizeof(data), user_ptr);
|
|
return bpf_strncmp(data, sizeof(data), "test_data") == 0;
|
|
}
|
|
|
|
static void uprobe_multi_check(void *ctx, bool is_return, bool is_sleep)
|
|
{
|
|
child_pid = bpf_get_current_pid_tgid() >> 32;
|
|
|
|
if (pid && child_pid != pid)
|
|
return;
|
|
|
|
__u64 cookie = test_cookie ? bpf_get_attach_cookie(ctx) : 0;
|
|
__u64 addr = bpf_get_func_ip(ctx);
|
|
|
|
#define SET(__var, __addr, __cookie) ({ \
|
|
if (addr == __addr && \
|
|
(!test_cookie || (cookie == __cookie))) \
|
|
__var += 1; \
|
|
})
|
|
|
|
if (is_return) {
|
|
SET(uretprobe_multi_func_1_result, uprobe_multi_func_1_addr, 2);
|
|
SET(uretprobe_multi_func_2_result, uprobe_multi_func_2_addr, 3);
|
|
SET(uretprobe_multi_func_3_result, uprobe_multi_func_3_addr, 1);
|
|
} else {
|
|
SET(uprobe_multi_func_1_result, uprobe_multi_func_1_addr, 3);
|
|
SET(uprobe_multi_func_2_result, uprobe_multi_func_2_addr, 1);
|
|
SET(uprobe_multi_func_3_result, uprobe_multi_func_3_addr, 2);
|
|
}
|
|
|
|
#undef SET
|
|
|
|
if (is_sleep && verify_sleepable_user_copy())
|
|
uprobe_multi_sleep_result += 1;
|
|
}
|
|
|
|
SEC("uprobe.multi//proc/self/exe:uprobe_multi_func_*")
|
|
int uprobe(struct pt_regs *ctx)
|
|
{
|
|
uprobe_multi_check(ctx, false, false);
|
|
return 0;
|
|
}
|
|
|
|
SEC("uretprobe.multi//proc/self/exe:uprobe_multi_func_*")
|
|
int uretprobe(struct pt_regs *ctx)
|
|
{
|
|
uprobe_multi_check(ctx, true, false);
|
|
return 0;
|
|
}
|
|
|
|
SEC("uprobe.multi.s//proc/self/exe:uprobe_multi_func_*")
|
|
int uprobe_sleep(struct pt_regs *ctx)
|
|
{
|
|
uprobe_multi_check(ctx, false, true);
|
|
return 0;
|
|
}
|
|
|
|
SEC("uretprobe.multi.s//proc/self/exe:uprobe_multi_func_*")
|
|
int uretprobe_sleep(struct pt_regs *ctx)
|
|
{
|
|
uprobe_multi_check(ctx, true, true);
|
|
return 0;
|
|
}
|