1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */
3
4 #include <test_progs.h>
5 #include "pro_epilogue.skel.h"
6 #include "epilogue_tailcall.skel.h"
7 #include "pro_epilogue_goto_start.skel.h"
8 #include "epilogue_exit.skel.h"
9 #include "pro_epilogue_with_kfunc.skel.h"
10
11 struct st_ops_args {
12 __u64 a;
13 };
14
test_tailcall(void)15 static void test_tailcall(void)
16 {
17 LIBBPF_OPTS(bpf_test_run_opts, topts);
18 struct epilogue_tailcall *skel;
19 struct st_ops_args args;
20 int err, prog_fd;
21
22 skel = epilogue_tailcall__open_and_load();
23 if (!ASSERT_OK_PTR(skel, "epilogue_tailcall__open_and_load"))
24 return;
25
26 topts.ctx_in = &args;
27 topts.ctx_size_in = sizeof(args);
28
29 skel->links.epilogue_tailcall =
30 bpf_map__attach_struct_ops(skel->maps.epilogue_tailcall);
31 if (!ASSERT_OK_PTR(skel->links.epilogue_tailcall, "attach_struct_ops"))
32 goto done;
33
34 /* Both test_epilogue_tailcall and test_epilogue_subprog are
35 * patched with epilogue. When syscall_epilogue_tailcall()
36 * is run, test_epilogue_tailcall() is triggered.
37 * It executes a tail call and control is transferred to
38 * test_epilogue_subprog(). Only test_epilogue_subprog()
39 * does args->a += 1, thus final args.a value of 10001
40 * guarantees that only the epilogue of the
41 * test_epilogue_subprog is executed.
42 */
43 memset(&args, 0, sizeof(args));
44 prog_fd = bpf_program__fd(skel->progs.syscall_epilogue_tailcall);
45 err = bpf_prog_test_run_opts(prog_fd, &topts);
46 ASSERT_OK(err, "bpf_prog_test_run_opts");
47 ASSERT_EQ(args.a, 10001, "args.a");
48 ASSERT_EQ(topts.retval, 10001 * 2, "topts.retval");
49
50 done:
51 epilogue_tailcall__destroy(skel);
52 }
53
test_pro_epilogue(void)54 void test_pro_epilogue(void)
55 {
56 RUN_TESTS(pro_epilogue);
57 RUN_TESTS(pro_epilogue_goto_start);
58 RUN_TESTS(epilogue_exit);
59 RUN_TESTS(pro_epilogue_with_kfunc);
60 if (test__start_subtest("tailcall"))
61 test_tailcall();
62 }
63