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