aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2024-03-25 10:23:57 +0100
committerJiri Olsa <jolsa@kernel.org>2024-03-25 14:12:16 +0100
commitdca40c9ae5da8476bca12542f3a3ac97b059ea4a (patch)
tree49b75b120a4b29357b50f9039814409f4ff0272f
parent6505a8f9db0bbd5c04989647d4bff9723c453c52 (diff)
downloadperf-uretprobe_syscall_1.tar.gz
-rw-r--r--tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c5
-rw-r--r--tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c71
2 files changed, 72 insertions, 4 deletions
diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
index bdbac6863e4768..42145f36b7242a 100644
--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
@@ -349,6 +349,11 @@ uprobe_ret_handler(struct uprobe_consumer *self, unsigned long func,
struct pt_regs *regs)
{
+#ifdef __x86_64__
+ regs->ax = 0x123456678;
+ regs->cx = 0x1234;
+ regs->r11 = 0x5678;
+#endif
return true;
}
diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
index e63cad902e904d..57c3f003de3e45 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
@@ -86,7 +86,7 @@ __naked void uprobe_syscall_arch(struct pt_regs *before, struct pt_regs *after)
);
}
-static void test_uretprobe(void)
+static void test_uretprobe_regs_equal(void)
{
struct pt_regs before = {}, after = {};
unsigned long *pb = (unsigned long *) &before;
@@ -149,8 +149,69 @@ static void test_uretprobe(void)
cleanup:
uprobe_syscall__destroy(skel);
}
+
+#define BPF_TESTMOD_UPROBE_TEST_FILE "/sys/kernel/bpf_testmod_uprobe"
+
+static int write_bpf_testmod_uprobe(unsigned long offset)
+{
+ char buf[20];
+ int fd, err;
+ size_t n;
+
+ n = sprintf(buf, "%lu", offset);
+
+ fd = open(BPF_TESTMOD_UPROBE_TEST_FILE, O_WRONLY);
+ err = -errno;
+ if (!ASSERT_GE(fd, 0, "testmod_file_open"))
+ return err;
+
+ write(fd, buf, n);
+ close(fd);
+ return 0;
+}
+
+static void test_uretprobe_regs_change(void)
+{
+ struct pt_regs before = {}, after = {};
+ unsigned long *pb = (unsigned long *) &before;
+ unsigned long *pa = (unsigned long *) &after;
+ unsigned long cnt = sizeof(before)/sizeof(*pb);
+ unsigned int i, offset;
+
+ offset = get_uprobe_offset(uprobe_syscall_arch_test);
+ write_bpf_testmod_uprobe(offset);
+
+ uprobe_syscall_arch(&before, &after);
+
+ write_bpf_testmod_uprobe(0);
+
+ for (i = 0; i < cnt; i++) {
+ unsigned int offset = i * sizeof(unsigned long);
+
+ switch (offset) {
+ case offsetof(struct pt_regs, rax):
+ ASSERT_EQ(pa[i], 0x123456678, "rax");
+ break;
+ case offsetof(struct pt_regs, rcx):
+ ASSERT_EQ(pa[i], 0x1234, "rcx");
+ break;
+ case offsetof(struct pt_regs, r11):
+ ASSERT_EQ(pa[i], 0x5678, "r11");
+ break;
+ default:
+ if (!ASSERT_EQ(pa[i], pb[i], "register before-after value check"))
+ fprintf(stdout, "failed register offset %u\n", offset);
+ }
+ }
+}
+
#else
-static void test_uretprobe(void)
+static void test_uretprobe_regs_equal(void)
+{
+ test__skip();
+}
+
+static void test_uretprobe_regs_change(void)
{
test__skip();
}
@@ -158,6 +219,8 @@ static void test_uretprobe(void)
void test_uprobe_syscall(void)
{
- if (test__start_subtest("uretprobe"))
- test_uretprobe();
+ if (test__start_subtest("uretprobe_regs_equal"))
+ test_uretprobe_regs_equal();
+ if (test__start_subtest("uretprobe_regs_change"))
+ test_uretprobe_regs_change();
}