Adding test to check we can change common register values through
uprobe program.

It's x86_64 specific test.

Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 .../selftests/bpf/prog_tests/bpf_cookie.c     |   1 +
 .../bpf/prog_tests/uprobe_multi_test.c        | 107 ++++++++++++++++++
 .../selftests/bpf/progs/uprobe_multi.c        |  24 ++++
 3 files changed, 132 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c 
b/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c
index 4a0670c056ba..2425fd26d1ea 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpf_cookie.c
@@ -6,6 +6,7 @@
 #include <sys/syscall.h>
 #include <sys/mman.h>
 #include <unistd.h>
+#include <asm/ptrace.h>
 #include <test_progs.h>
 #include <network_helpers.h>
 #include <bpf/btf.h>
diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c 
b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
index 2ee17ef1dae2..012652b07399 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c
@@ -2,6 +2,7 @@
 
 #include <unistd.h>
 #include <pthread.h>
+#include <asm/ptrace.h>
 #include <test_progs.h>
 #include "uprobe_multi.skel.h"
 #include "uprobe_multi_bench.skel.h"
@@ -1340,6 +1341,111 @@ static void test_bench_attach_usdt(void)
        printf("%s: detached in %7.3lfs\n", __func__, detach_delta);
 }
 
+#ifdef __x86_64__
+__naked __maybe_unused unsigned long uprobe_regs_change_trigger(void)
+{
+       asm volatile (
+               "ret\n"
+       );
+}
+
+static __naked void uprobe_regs_change(struct pt_regs *before, struct pt_regs 
*after)
+{
+       asm volatile (
+               "movq %r11,  48(%rdi)\n"
+               "movq %r10,  56(%rdi)\n"
+               "movq  %r9,  64(%rdi)\n"
+               "movq  %r8,  72(%rdi)\n"
+               "movq %rax,  80(%rdi)\n"
+               "movq %rcx,  88(%rdi)\n"
+               "movq %rdx,  96(%rdi)\n"
+               "movq %rsi, 104(%rdi)\n"
+               "movq %rdi, 112(%rdi)\n"
+
+               /* save 2nd argument */
+               "pushq %rsi\n"
+               "call uprobe_regs_change_trigger\n"
+
+               /* save  return value and load 2nd argument pointer to rax */
+               "pushq %rax\n"
+               "movq 8(%rsp), %rax\n"
+
+               "movq %r11,  48(%rax)\n"
+               "movq %r10,  56(%rax)\n"
+               "movq  %r9,  64(%rax)\n"
+               "movq  %r8,  72(%rax)\n"
+               "movq %rcx,  88(%rax)\n"
+               "movq %rdx,  96(%rax)\n"
+               "movq %rsi, 104(%rax)\n"
+               "movq %rdi, 112(%rax)\n"
+
+               /* restore return value and 2nd argument */
+               "pop %rax\n"
+               "pop %rsi\n"
+
+               "movq %rax,  80(%rsi)\n"
+               "ret\n"
+       );
+}
+
+static void unique_regs_common(void)
+{
+       struct pt_regs before = {}, after = {}, expected = {
+               .rax = 0xc0ffe,
+               .rcx = 0xbad,
+               .rdx = 0xdead,
+               .r8  = 0x8,
+               .r9  = 0x9,
+               .r10 = 0x10,
+               .r11 = 0x11,
+               .rdi = 0x12,
+               .rsi = 0x13,
+       };
+       LIBBPF_OPTS(bpf_uprobe_multi_opts, opts,
+               .unique = true,
+       );
+       struct uprobe_multi *skel;
+
+       skel = uprobe_multi__open_and_load();
+       if (!ASSERT_OK_PTR(skel, "skel_open"))
+               return;
+
+       skel->bss->pid = getpid();
+       skel->bss->regs = expected;
+
+       skel->links.uprobe_change_regs = bpf_program__attach_uprobe_multi(
+                                               skel->progs.uprobe_change_regs,
+                                               -1, "/proc/self/exe",
+                                               "uprobe_regs_change_trigger",
+                                               &opts);
+       if (!ASSERT_OK_PTR(skel->links.uprobe_change_regs, 
"bpf_program__attach_uprobe_multi"))
+               goto cleanup;
+
+       uprobe_regs_change(&before, &after);
+
+       ASSERT_EQ(after.rax, expected.rax, "ax");
+       ASSERT_EQ(after.rcx, expected.rcx, "cx");
+       ASSERT_EQ(after.rdx, expected.rdx, "dx");
+       ASSERT_EQ(after.r8,  expected.r8,  "r8");
+       ASSERT_EQ(after.r9,  expected.r9,  "r9");
+       ASSERT_EQ(after.r10, expected.r10, "r10");
+       ASSERT_EQ(after.r11, expected.r11, "r11");
+       ASSERT_EQ(after.rdi, expected.rdi, "rdi");
+       ASSERT_EQ(after.rsi, expected.rsi, "rsi");
+
+cleanup:
+       uprobe_multi__destroy(skel);
+}
+
+static void test_unique(void)
+{
+       if (test__start_subtest("unique_regs_common"))
+               unique_regs_common();
+}
+#else
+static void test_unique(void) { }
+#endif
+
 void test_uprobe_multi_test(void)
 {
        if (test__start_subtest("skel_api"))
@@ -1372,5 +1478,6 @@ void test_uprobe_multi_test(void)
                test_session_cookie_skel_api();
        if (test__start_subtest("session_cookie_recursive"))
                test_session_recursive_skel_api();
+       test_unique();
        RUN_TESTS(uprobe_multi_verifier);
 }
diff --git a/tools/testing/selftests/bpf/progs/uprobe_multi.c 
b/tools/testing/selftests/bpf/progs/uprobe_multi.c
index 44190efcdba2..f26f8b840985 100644
--- a/tools/testing/selftests/bpf/progs/uprobe_multi.c
+++ b/tools/testing/selftests/bpf/progs/uprobe_multi.c
@@ -141,3 +141,27 @@ int usdt_extra(struct pt_regs *ctx)
        /* we need this one just to mix PID-filtered and global USDT probes */
        return 0;
 }
+
+#if defined(__TARGET_ARCH_x86)
+struct pt_regs regs;
+
+SEC("uprobe.unique")
+int BPF_UPROBE(uprobe_change_regs)
+{
+       pid_t cur_pid = bpf_get_current_pid_tgid() >> 32;
+
+       if (cur_pid != pid)
+               return 0;
+
+       ctx->ax  = regs.ax;
+       ctx->cx  = regs.cx;
+       ctx->dx  = regs.dx;
+       ctx->r8  = regs.r8;
+       ctx->r9  = regs.r9;
+       ctx->r10 = regs.r10;
+       ctx->r11 = regs.r11;
+       ctx->di  = regs.di;
+       ctx->si  = regs.si;
+       return 0;
+}
+#endif
-- 
2.51.0


Reply via email to