xref: /linux/tools/testing/selftests/bpf/prog_tests/sleepable_tracepoints.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
3 
4 #include <test_progs.h>
5 #include <unistd.h>
6 #include "test_sleepable_tracepoints.skel.h"
7 #include "test_sleepable_tracepoints_fail.skel.h"
8 
9 static void run_test(struct test_sleepable_tracepoints *skel)
10 {
11 	char buf[PATH_MAX] = "/";
12 
13 	skel->bss->target_pid = getpid();
14 	skel->bss->prog_triggered = 0;
15 	skel->bss->err = 0;
16 	skel->bss->copied_byte = 0;
17 
18 	syscall(__NR_getcwd, buf, sizeof(buf));
19 
20 	ASSERT_EQ(skel->bss->prog_triggered, 1, "prog_triggered");
21 	ASSERT_EQ(skel->bss->err, 0, "err");
22 	ASSERT_EQ(skel->bss->copied_byte, '/', "copied_byte");
23 }
24 
25 static void run_auto_attach_test(struct bpf_program *prog,
26 				 struct test_sleepable_tracepoints *skel)
27 {
28 	struct bpf_link *link;
29 
30 	link = bpf_program__attach(prog);
31 	if (!ASSERT_OK_PTR(link, "prog_attach"))
32 		return;
33 
34 	run_test(skel);
35 	bpf_link__destroy(link);
36 }
37 
38 static void test_attach_only(struct bpf_program *prog)
39 {
40 	struct bpf_link *link;
41 
42 	link = bpf_program__attach(prog);
43 	if (ASSERT_OK_PTR(link, "attach"))
44 		bpf_link__destroy(link);
45 }
46 
47 static void test_attach_reject(struct bpf_program *prog)
48 {
49 	struct bpf_link *link;
50 
51 	link = bpf_program__attach(prog);
52 	if (!ASSERT_ERR_PTR(link, "attach_should_fail"))
53 		bpf_link__destroy(link);
54 }
55 
56 static void test_raw_tp_bare(struct test_sleepable_tracepoints *skel)
57 {
58 	struct bpf_link *link;
59 
60 	link = bpf_program__attach_raw_tracepoint(skel->progs.handle_raw_tp_bare,
61 						  "sys_enter");
62 	if (ASSERT_OK_PTR(link, "attach"))
63 		bpf_link__destroy(link);
64 }
65 
66 static void test_tp_bare(struct test_sleepable_tracepoints *skel)
67 {
68 	struct bpf_link *link;
69 
70 	link = bpf_program__attach_tracepoint(skel->progs.handle_tp_bare,
71 					      "syscalls", "sys_enter_getcwd");
72 	if (ASSERT_OK_PTR(link, "attach"))
73 		bpf_link__destroy(link);
74 }
75 
76 static void test_test_run(struct test_sleepable_tracepoints *skel)
77 {
78 	__u64 args[2] = {0x1234ULL, 0x5678ULL};
79 	LIBBPF_OPTS(bpf_test_run_opts, topts,
80 		.ctx_in = args,
81 		.ctx_size_in = sizeof(args),
82 	);
83 	int fd, err;
84 
85 	fd = bpf_program__fd(skel->progs.handle_test_run);
86 	err = bpf_prog_test_run_opts(fd, &topts);
87 	ASSERT_OK(err, "test_run");
88 	ASSERT_EQ(topts.retval, args[0] + args[1], "test_run_retval");
89 }
90 
91 static void test_test_run_on_cpu_reject(struct test_sleepable_tracepoints *skel)
92 {
93 	__u64 args[2] = {};
94 	LIBBPF_OPTS(bpf_test_run_opts, topts,
95 		.ctx_in = args,
96 		.ctx_size_in = sizeof(args),
97 		.flags = BPF_F_TEST_RUN_ON_CPU,
98 	);
99 	int fd, err;
100 
101 	fd = bpf_program__fd(skel->progs.handle_test_run);
102 	err = bpf_prog_test_run_opts(fd, &topts);
103 	ASSERT_ERR(err, "test_run_on_cpu_reject");
104 }
105 
106 void test_sleepable_tracepoints(void)
107 {
108 	struct test_sleepable_tracepoints *skel;
109 
110 	skel = test_sleepable_tracepoints__open_and_load();
111 	if (!ASSERT_OK_PTR(skel, "open_and_load"))
112 		return;
113 
114 	if (test__start_subtest("tp_btf"))
115 		run_auto_attach_test(skel->progs.handle_sys_enter_tp_btf, skel);
116 	if (test__start_subtest("raw_tp"))
117 		run_auto_attach_test(skel->progs.handle_sys_enter_raw_tp, skel);
118 	if (test__start_subtest("tracepoint"))
119 		run_auto_attach_test(skel->progs.handle_sys_enter_tp, skel);
120 	if (test__start_subtest("sys_exit"))
121 		run_auto_attach_test(skel->progs.handle_sys_exit_tp, skel);
122 	if (test__start_subtest("tracepoint_alias"))
123 		test_attach_only(skel->progs.handle_sys_enter_tp_alias);
124 	if (test__start_subtest("raw_tracepoint_alias"))
125 		test_attach_only(skel->progs.handle_sys_enter_raw_tp_alias);
126 	if (test__start_subtest("raw_tp_bare"))
127 		test_raw_tp_bare(skel);
128 	if (test__start_subtest("tp_bare"))
129 		test_tp_bare(skel);
130 	if (test__start_subtest("test_run"))
131 		test_test_run(skel);
132 	if (test__start_subtest("test_run_on_cpu_reject"))
133 		test_test_run_on_cpu_reject(skel);
134 	if (test__start_subtest("raw_tp_non_faultable"))
135 		test_attach_reject(skel->progs.handle_raw_tp_non_faultable);
136 	if (test__start_subtest("tp_non_syscall"))
137 		test_attach_reject(skel->progs.handle_tp_non_syscall);
138 	if (test__start_subtest("tp_btf_non_faultable_reject"))
139 		RUN_TESTS(test_sleepable_tracepoints_fail);
140 
141 	test_sleepable_tracepoints__destroy(skel);
142 }
143