Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions arch/arm64/include/asm/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
return regs;
}

static __always_inline void
ftrace_partial_regs_fix(const struct ftrace_regs *fregs, struct pt_regs *regs)
{
struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);

if (afregs->pc != regs->pc) {
afregs->pc = regs->pc;
afregs->regs[0] = regs->regs[0];
}
}

#define arch_ftrace_fill_perf_regs(fregs, _regs) do { \
(_regs)->pc = arch_ftrace_regs(fregs)->pc; \
(_regs)->regs[29] = arch_ftrace_regs(fregs)->fp; \
Expand Down
3 changes: 3 additions & 0 deletions include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ ftrace_partial_regs(struct ftrace_regs *fregs, struct pt_regs *regs)
return &arch_ftrace_regs(fregs)->regs;
}

static __always_inline void
ftrace_partial_regs_fix(struct ftrace_regs *fregs, struct pt_regs *regs) { }

#endif /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS || CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */

#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
Expand Down
1 change: 1 addition & 0 deletions kernel/trace/bpf_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2564,6 +2564,7 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,
old_run_ctx = bpf_set_run_ctx(&run_ctx.session_ctx.run_ctx);
err = bpf_prog_run(link->link.prog, regs);
bpf_reset_run_ctx(old_run_ctx);
ftrace_partial_regs_fix(fregs, bpf_kprobe_multi_pt_regs_ptr());
rcu_read_unlock();

out:
Expand Down
61 changes: 61 additions & 0 deletions tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <sys/prctl.h>
#include <test_progs.h>
#include "kprobe_multi.skel.h"
#include "trace_helpers.h"
Expand Down Expand Up @@ -540,6 +542,63 @@ static void test_attach_override(void)
kprobe_multi_override__destroy(skel);
}

/* XXX I'll move this to common place and share with
* SYS_NANOSLEEP_KPROBE_NAME macro on repost.
*/
#ifdef __x86_64__
#define SYS_PREFIX "__x64_"
#elif defined(__s390x__)
#define SYS_PREFIX "__s390x_"
#elif defined(__aarch64__)
#define SYS_PREFIX "__arm64_"
#elif defined(__riscv)
#define SYS_PREFIX "__riscv_"
#else
#define SYS_PREFIX ""
#endif

static void test_override(void)
{
struct kprobe_multi_override *skel = NULL;
int err;

skel = kprobe_multi_override__open_and_load();
if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load"))
goto cleanup;

skel->bss->pid = getpid();

/* no override */
err = prctl(0xffff, 0);
ASSERT_EQ(err, -1, "err");

/* kprobe.multi override */
skel->links.test_override = bpf_program__attach_kprobe_multi_opts(skel->progs.test_override,
SYS_PREFIX "sys_prctl", NULL);
if (!ASSERT_OK_PTR(skel->links.test_override, "bpf_program__attach_kprobe_multi_opts")) {
goto cleanup;
}

err = prctl(0xffff, 0);
ASSERT_EQ(err, 123, "err");

bpf_link__destroy(skel->links.test_override);
skel->links.test_override = NULL;

/* kprobe override */
skel->links.test_kprobe_override = bpf_program__attach_kprobe(skel->progs.test_kprobe_override,
false, SYS_PREFIX "sys_prctl");
if (!ASSERT_OK_PTR(skel->links.test_kprobe_override, "bpf_program__attach_kprobe")) {
goto cleanup;
}

err = prctl(0xffff, 0);
ASSERT_EQ(err, 123, "err");

cleanup:
kprobe_multi_override__destroy(skel);
}

#ifdef __x86_64__
static void test_attach_write_ctx(void)
{
Expand Down Expand Up @@ -597,6 +656,8 @@ void test_kprobe_multi_test(void)
test_attach_api_fails();
if (test__start_subtest("attach_override"))
test_attach_override();
if (test__start_subtest("override"))
test_override();
if (test__start_subtest("session"))
test_session_skel_api();
if (test__start_subtest("session_cookie"))
Expand Down
15 changes: 15 additions & 0 deletions tools/testing/selftests/bpf/progs/kprobe_multi_override.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@

char _license[] SEC("license") = "GPL";

int pid = 0;

SEC("kprobe.multi")
int test_override(struct pt_regs *ctx)
{
if (bpf_get_current_pid_tgid() >> 32 != pid)
return 0;

bpf_override_return(ctx, 123);
return 0;
}

SEC("kprobe")
int test_kprobe_override(struct pt_regs *ctx)
{
if (bpf_get_current_pid_tgid() >> 32 != pid)
return 0;

bpf_override_return(ctx, 123);
return 0;
}
Loading