xref: /openbmc/linux/tools/testing/selftests/bpf/prog_tests/kfunc_call.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
17bd1590dSMartin KaFai Lau // SPDX-License-Identifier: GPL-2.0
27bd1590dSMartin KaFai Lau /* Copyright (c) 2021 Facebook */
37bd1590dSMartin KaFai Lau #include <test_progs.h>
47bd1590dSMartin KaFai Lau #include <network_helpers.h>
5fb66223aSBenjamin Tissoires #include "kfunc_call_fail.skel.h"
6012ba115SBenjamin Tissoires #include "kfunc_call_test.skel.h"
74d1b6298SAlexei Starovoitov #include "kfunc_call_test.lskel.h"
87bd1590dSMartin KaFai Lau #include "kfunc_call_test_subprog.skel.h"
9bc5f75daSAlexei Starovoitov #include "kfunc_call_test_subprog.lskel.h"
10e3389458SArtem Savkov #include "kfunc_call_destructive.skel.h"
11e3389458SArtem Savkov 
12e3389458SArtem Savkov #include "cap_helpers.h"
137bd1590dSMartin KaFai Lau 
14fb66223aSBenjamin Tissoires static size_t log_buf_sz = 1048576; /* 1 MB */
15fb66223aSBenjamin Tissoires static char obj_log_buf[1048576];
16fb66223aSBenjamin Tissoires 
17fb66223aSBenjamin Tissoires enum kfunc_test_type {
18fb66223aSBenjamin Tissoires 	tc_test = 0,
19fb66223aSBenjamin Tissoires 	syscall_test,
20fb66223aSBenjamin Tissoires 	syscall_null_ctx_test,
21fb66223aSBenjamin Tissoires };
22fb66223aSBenjamin Tissoires 
23012ba115SBenjamin Tissoires struct kfunc_test_params {
24012ba115SBenjamin Tissoires 	const char *prog_name;
25012ba115SBenjamin Tissoires 	unsigned long lskel_prog_desc_offset;
26012ba115SBenjamin Tissoires 	int retval;
27fb66223aSBenjamin Tissoires 	enum kfunc_test_type test_type;
28fb66223aSBenjamin Tissoires 	const char *expected_err_msg;
29012ba115SBenjamin Tissoires };
30012ba115SBenjamin Tissoires 
31fb66223aSBenjamin Tissoires #define __BPF_TEST_SUCCESS(name, __retval, type) \
32012ba115SBenjamin Tissoires 	{ \
33012ba115SBenjamin Tissoires 	  .prog_name = #name, \
34012ba115SBenjamin Tissoires 	  .lskel_prog_desc_offset = offsetof(struct kfunc_call_test_lskel, progs.name), \
35012ba115SBenjamin Tissoires 	  .retval = __retval, \
36fb66223aSBenjamin Tissoires 	  .test_type = type, \
37fb66223aSBenjamin Tissoires 	  .expected_err_msg = NULL, \
38012ba115SBenjamin Tissoires 	}
39012ba115SBenjamin Tissoires 
40fb66223aSBenjamin Tissoires #define __BPF_TEST_FAIL(name, __retval, type, error_msg) \
41fb66223aSBenjamin Tissoires 	{ \
42fb66223aSBenjamin Tissoires 	  .prog_name = #name, \
43fb66223aSBenjamin Tissoires 	  .lskel_prog_desc_offset = 0 /* unused when test is failing */, \
44fb66223aSBenjamin Tissoires 	  .retval = __retval, \
45fb66223aSBenjamin Tissoires 	  .test_type = type, \
46fb66223aSBenjamin Tissoires 	  .expected_err_msg = error_msg, \
47fb66223aSBenjamin Tissoires 	}
48fb66223aSBenjamin Tissoires 
49fb66223aSBenjamin Tissoires #define TC_TEST(name, retval) __BPF_TEST_SUCCESS(name, retval, tc_test)
50fb66223aSBenjamin Tissoires #define SYSCALL_TEST(name, retval) __BPF_TEST_SUCCESS(name, retval, syscall_test)
51fb66223aSBenjamin Tissoires #define SYSCALL_NULL_CTX_TEST(name, retval) __BPF_TEST_SUCCESS(name, retval, syscall_null_ctx_test)
52fb66223aSBenjamin Tissoires 
5322ed8d5aSBenjamin Tissoires #define TC_FAIL(name, retval, error_msg) __BPF_TEST_FAIL(name, retval, tc_test, error_msg)
54fb66223aSBenjamin Tissoires #define SYSCALL_NULL_CTX_FAIL(name, retval, error_msg) \
55fb66223aSBenjamin Tissoires 	__BPF_TEST_FAIL(name, retval, syscall_null_ctx_test, error_msg)
56fb66223aSBenjamin Tissoires 
57012ba115SBenjamin Tissoires static struct kfunc_test_params kfunc_tests[] = {
58fb66223aSBenjamin Tissoires 	/* failure cases:
59fb66223aSBenjamin Tissoires 	 * if retval is 0 -> the program will fail to load and the error message is an error
60fb66223aSBenjamin Tissoires 	 * if retval is not 0 -> the program can be loaded but running it will gives the
61fb66223aSBenjamin Tissoires 	 *                       provided return value. The error message is thus the one
62fb66223aSBenjamin Tissoires 	 *                       from a successful load
63fb66223aSBenjamin Tissoires 	 */
64fb66223aSBenjamin Tissoires 	SYSCALL_NULL_CTX_FAIL(kfunc_syscall_test_fail, -EINVAL, "processed 4 insns"),
65fb66223aSBenjamin Tissoires 	SYSCALL_NULL_CTX_FAIL(kfunc_syscall_test_null_fail, -EINVAL, "processed 4 insns"),
6622ed8d5aSBenjamin Tissoires 	TC_FAIL(kfunc_call_test_get_mem_fail_rdonly, 0, "R0 cannot write into rdonly_mem"),
6722ed8d5aSBenjamin Tissoires 	TC_FAIL(kfunc_call_test_get_mem_fail_use_after_free, 0, "invalid mem access 'scalar'"),
6822ed8d5aSBenjamin Tissoires 	TC_FAIL(kfunc_call_test_get_mem_fail_oob, 0, "min value is outside of the allowed memory range"),
6922ed8d5aSBenjamin Tissoires 	TC_FAIL(kfunc_call_test_get_mem_fail_not_const, 0, "is not a const"),
7022ed8d5aSBenjamin Tissoires 	TC_FAIL(kfunc_call_test_mem_acquire_fail, 0, "acquire kernel function does not return PTR_TO_BTF_ID"),
71fb66223aSBenjamin Tissoires 
72fb66223aSBenjamin Tissoires 	/* success cases */
73012ba115SBenjamin Tissoires 	TC_TEST(kfunc_call_test1, 12),
74012ba115SBenjamin Tissoires 	TC_TEST(kfunc_call_test2, 3),
75be6b5c10SIlya Leoshkevich 	TC_TEST(kfunc_call_test4, -1234),
76012ba115SBenjamin Tissoires 	TC_TEST(kfunc_call_test_ref_btf_id, 0),
7722ed8d5aSBenjamin Tissoires 	TC_TEST(kfunc_call_test_get_mem, 42),
78fb66223aSBenjamin Tissoires 	SYSCALL_TEST(kfunc_syscall_test, 0),
79fb66223aSBenjamin Tissoires 	SYSCALL_NULL_CTX_TEST(kfunc_syscall_test_null, 0),
806aed15e3SDavid Vernet 	TC_TEST(kfunc_call_test_static_unused_arg, 0),
81fb66223aSBenjamin Tissoires };
82fb66223aSBenjamin Tissoires 
83fb66223aSBenjamin Tissoires struct syscall_test_args {
84fb66223aSBenjamin Tissoires 	__u8 data[16];
85fb66223aSBenjamin Tissoires 	size_t size;
86012ba115SBenjamin Tissoires };
87012ba115SBenjamin Tissoires 
verify_success(struct kfunc_test_params * param)88012ba115SBenjamin Tissoires static void verify_success(struct kfunc_test_params *param)
897bd1590dSMartin KaFai Lau {
90012ba115SBenjamin Tissoires 	struct kfunc_call_test_lskel *lskel = NULL;
91fb66223aSBenjamin Tissoires 	LIBBPF_OPTS(bpf_test_run_opts, topts);
92012ba115SBenjamin Tissoires 	struct bpf_prog_desc *lskel_prog;
93012ba115SBenjamin Tissoires 	struct kfunc_call_test *skel;
94012ba115SBenjamin Tissoires 	struct bpf_program *prog;
9504fcb5f9SDelyan Kratunov 	int prog_fd, err;
96fb66223aSBenjamin Tissoires 	struct syscall_test_args args = {
97fb66223aSBenjamin Tissoires 		.size = 10,
98fb66223aSBenjamin Tissoires 	};
99fb66223aSBenjamin Tissoires 
100fb66223aSBenjamin Tissoires 	switch (param->test_type) {
101fb66223aSBenjamin Tissoires 	case syscall_test:
102fb66223aSBenjamin Tissoires 		topts.ctx_in = &args;
103fb66223aSBenjamin Tissoires 		topts.ctx_size_in = sizeof(args);
104fb66223aSBenjamin Tissoires 		/* fallthrough */
105fb66223aSBenjamin Tissoires 	case syscall_null_ctx_test:
106fb66223aSBenjamin Tissoires 		break;
107fb66223aSBenjamin Tissoires 	case tc_test:
108fb66223aSBenjamin Tissoires 		topts.data_in = &pkt_v4;
109fb66223aSBenjamin Tissoires 		topts.data_size_in = sizeof(pkt_v4);
110fb66223aSBenjamin Tissoires 		topts.repeat = 1;
111fb66223aSBenjamin Tissoires 		break;
112fb66223aSBenjamin Tissoires 	}
1137bd1590dSMartin KaFai Lau 
114012ba115SBenjamin Tissoires 	/* first test with normal libbpf */
115012ba115SBenjamin Tissoires 	skel = kfunc_call_test__open_and_load();
1167bd1590dSMartin KaFai Lau 	if (!ASSERT_OK_PTR(skel, "skel"))
1177bd1590dSMartin KaFai Lau 		return;
1187bd1590dSMartin KaFai Lau 
119012ba115SBenjamin Tissoires 	prog = bpf_object__find_program_by_name(skel->obj, param->prog_name);
120012ba115SBenjamin Tissoires 	if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
121012ba115SBenjamin Tissoires 		goto cleanup;
1227bd1590dSMartin KaFai Lau 
123012ba115SBenjamin Tissoires 	prog_fd = bpf_program__fd(prog);
12404fcb5f9SDelyan Kratunov 	err = bpf_prog_test_run_opts(prog_fd, &topts);
125012ba115SBenjamin Tissoires 	if (!ASSERT_OK(err, param->prog_name))
126012ba115SBenjamin Tissoires 		goto cleanup;
1277bd1590dSMartin KaFai Lau 
128012ba115SBenjamin Tissoires 	if (!ASSERT_EQ(topts.retval, param->retval, "retval"))
129012ba115SBenjamin Tissoires 		goto cleanup;
130012ba115SBenjamin Tissoires 
131012ba115SBenjamin Tissoires 	/* second test with light skeletons */
132012ba115SBenjamin Tissoires 	lskel = kfunc_call_test_lskel__open_and_load();
133012ba115SBenjamin Tissoires 	if (!ASSERT_OK_PTR(lskel, "lskel"))
134012ba115SBenjamin Tissoires 		goto cleanup;
135012ba115SBenjamin Tissoires 
136012ba115SBenjamin Tissoires 	lskel_prog = (struct bpf_prog_desc *)((char *)lskel + param->lskel_prog_desc_offset);
137012ba115SBenjamin Tissoires 
138012ba115SBenjamin Tissoires 	prog_fd = lskel_prog->prog_fd;
13904fcb5f9SDelyan Kratunov 	err = bpf_prog_test_run_opts(prog_fd, &topts);
140012ba115SBenjamin Tissoires 	if (!ASSERT_OK(err, param->prog_name))
141012ba115SBenjamin Tissoires 		goto cleanup;
142c1ff181fSKumar Kartikeya Dwivedi 
143012ba115SBenjamin Tissoires 	ASSERT_EQ(topts.retval, param->retval, "retval");
144012ba115SBenjamin Tissoires 
145012ba115SBenjamin Tissoires cleanup:
146012ba115SBenjamin Tissoires 	kfunc_call_test__destroy(skel);
147012ba115SBenjamin Tissoires 	if (lskel)
148012ba115SBenjamin Tissoires 		kfunc_call_test_lskel__destroy(lskel);
149012ba115SBenjamin Tissoires }
150012ba115SBenjamin Tissoires 
verify_fail(struct kfunc_test_params * param)151fb66223aSBenjamin Tissoires static void verify_fail(struct kfunc_test_params *param)
152fb66223aSBenjamin Tissoires {
153fb66223aSBenjamin Tissoires 	LIBBPF_OPTS(bpf_object_open_opts, opts);
154fb66223aSBenjamin Tissoires 	LIBBPF_OPTS(bpf_test_run_opts, topts);
155fb66223aSBenjamin Tissoires 	struct bpf_program *prog;
156fb66223aSBenjamin Tissoires 	struct kfunc_call_fail *skel;
157fb66223aSBenjamin Tissoires 	int prog_fd, err;
158fb66223aSBenjamin Tissoires 	struct syscall_test_args args = {
159fb66223aSBenjamin Tissoires 		.size = 10,
160fb66223aSBenjamin Tissoires 	};
161fb66223aSBenjamin Tissoires 
162fb66223aSBenjamin Tissoires 	opts.kernel_log_buf = obj_log_buf;
163fb66223aSBenjamin Tissoires 	opts.kernel_log_size = log_buf_sz;
164fb66223aSBenjamin Tissoires 	opts.kernel_log_level = 1;
165fb66223aSBenjamin Tissoires 
166fb66223aSBenjamin Tissoires 	switch (param->test_type) {
167fb66223aSBenjamin Tissoires 	case syscall_test:
168fb66223aSBenjamin Tissoires 		topts.ctx_in = &args;
169fb66223aSBenjamin Tissoires 		topts.ctx_size_in = sizeof(args);
170fb66223aSBenjamin Tissoires 		/* fallthrough */
171fb66223aSBenjamin Tissoires 	case syscall_null_ctx_test:
172fb66223aSBenjamin Tissoires 		break;
173fb66223aSBenjamin Tissoires 	case tc_test:
174fb66223aSBenjamin Tissoires 		topts.data_in = &pkt_v4;
175fb66223aSBenjamin Tissoires 		topts.data_size_in = sizeof(pkt_v4);
176fb66223aSBenjamin Tissoires 		topts.repeat = 1;
177*811915dbSYipeng Zou 		break;
178fb66223aSBenjamin Tissoires 	}
179fb66223aSBenjamin Tissoires 
180fb66223aSBenjamin Tissoires 	skel = kfunc_call_fail__open_opts(&opts);
181fb66223aSBenjamin Tissoires 	if (!ASSERT_OK_PTR(skel, "kfunc_call_fail__open_opts"))
182fb66223aSBenjamin Tissoires 		goto cleanup;
183fb66223aSBenjamin Tissoires 
184fb66223aSBenjamin Tissoires 	prog = bpf_object__find_program_by_name(skel->obj, param->prog_name);
185fb66223aSBenjamin Tissoires 	if (!ASSERT_OK_PTR(prog, "bpf_object__find_program_by_name"))
186fb66223aSBenjamin Tissoires 		goto cleanup;
187fb66223aSBenjamin Tissoires 
188fb66223aSBenjamin Tissoires 	bpf_program__set_autoload(prog, true);
189fb66223aSBenjamin Tissoires 
190fb66223aSBenjamin Tissoires 	err = kfunc_call_fail__load(skel);
191fb66223aSBenjamin Tissoires 	if (!param->retval) {
192fb66223aSBenjamin Tissoires 		/* the verifier is supposed to complain and refuses to load */
193fb66223aSBenjamin Tissoires 		if (!ASSERT_ERR(err, "unexpected load success"))
194fb66223aSBenjamin Tissoires 			goto out_err;
195fb66223aSBenjamin Tissoires 
196fb66223aSBenjamin Tissoires 	} else {
197fb66223aSBenjamin Tissoires 		/* the program is loaded but must dynamically fail */
198fb66223aSBenjamin Tissoires 		if (!ASSERT_OK(err, "unexpected load error"))
199fb66223aSBenjamin Tissoires 			goto out_err;
200fb66223aSBenjamin Tissoires 
201fb66223aSBenjamin Tissoires 		prog_fd = bpf_program__fd(prog);
202fb66223aSBenjamin Tissoires 		err = bpf_prog_test_run_opts(prog_fd, &topts);
203fb66223aSBenjamin Tissoires 		if (!ASSERT_EQ(err, param->retval, param->prog_name))
204fb66223aSBenjamin Tissoires 			goto out_err;
205fb66223aSBenjamin Tissoires 	}
206fb66223aSBenjamin Tissoires 
207fb66223aSBenjamin Tissoires out_err:
208fb66223aSBenjamin Tissoires 	if (!ASSERT_OK_PTR(strstr(obj_log_buf, param->expected_err_msg), "expected_err_msg")) {
209fb66223aSBenjamin Tissoires 		fprintf(stderr, "Expected err_msg: %s\n", param->expected_err_msg);
210fb66223aSBenjamin Tissoires 		fprintf(stderr, "Verifier output: %s\n", obj_log_buf);
211fb66223aSBenjamin Tissoires 	}
212fb66223aSBenjamin Tissoires 
213fb66223aSBenjamin Tissoires cleanup:
214fb66223aSBenjamin Tissoires 	kfunc_call_fail__destroy(skel);
215fb66223aSBenjamin Tissoires }
216fb66223aSBenjamin Tissoires 
test_main(void)217012ba115SBenjamin Tissoires static void test_main(void)
218012ba115SBenjamin Tissoires {
219012ba115SBenjamin Tissoires 	int i;
220012ba115SBenjamin Tissoires 
221012ba115SBenjamin Tissoires 	for (i = 0; i < ARRAY_SIZE(kfunc_tests); i++) {
222012ba115SBenjamin Tissoires 		if (!test__start_subtest(kfunc_tests[i].prog_name))
223012ba115SBenjamin Tissoires 			continue;
224012ba115SBenjamin Tissoires 
225fb66223aSBenjamin Tissoires 		if (!kfunc_tests[i].expected_err_msg)
226012ba115SBenjamin Tissoires 			verify_success(&kfunc_tests[i]);
227fb66223aSBenjamin Tissoires 		else
228fb66223aSBenjamin Tissoires 			verify_fail(&kfunc_tests[i]);
229012ba115SBenjamin Tissoires 	}
2307bd1590dSMartin KaFai Lau }
2317bd1590dSMartin KaFai Lau 
test_subprog(void)2327bd1590dSMartin KaFai Lau static void test_subprog(void)
2337bd1590dSMartin KaFai Lau {
2347bd1590dSMartin KaFai Lau 	struct kfunc_call_test_subprog *skel;
23504fcb5f9SDelyan Kratunov 	int prog_fd, err;
23604fcb5f9SDelyan Kratunov 	LIBBPF_OPTS(bpf_test_run_opts, topts,
23704fcb5f9SDelyan Kratunov 		.data_in = &pkt_v4,
23804fcb5f9SDelyan Kratunov 		.data_size_in = sizeof(pkt_v4),
23904fcb5f9SDelyan Kratunov 		.repeat = 1,
24004fcb5f9SDelyan Kratunov 	);
2417bd1590dSMartin KaFai Lau 
2427bd1590dSMartin KaFai Lau 	skel = kfunc_call_test_subprog__open_and_load();
2437bd1590dSMartin KaFai Lau 	if (!ASSERT_OK_PTR(skel, "skel"))
2447bd1590dSMartin KaFai Lau 		return;
2457bd1590dSMartin KaFai Lau 
2467bd1590dSMartin KaFai Lau 	prog_fd = bpf_program__fd(skel->progs.kfunc_call_test1);
24704fcb5f9SDelyan Kratunov 	err = bpf_prog_test_run_opts(prog_fd, &topts);
2487bd1590dSMartin KaFai Lau 	ASSERT_OK(err, "bpf_prog_test_run(test1)");
24904fcb5f9SDelyan Kratunov 	ASSERT_EQ(topts.retval, 10, "test1-retval");
2507bd1590dSMartin KaFai Lau 	ASSERT_NEQ(skel->data->active_res, -1, "active_res");
251700dcf0fSMartin KaFai Lau 	ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res");
2527bd1590dSMartin KaFai Lau 
2537bd1590dSMartin KaFai Lau 	kfunc_call_test_subprog__destroy(skel);
2547bd1590dSMartin KaFai Lau }
2557bd1590dSMartin KaFai Lau 
test_subprog_lskel(void)256bc5f75daSAlexei Starovoitov static void test_subprog_lskel(void)
257bc5f75daSAlexei Starovoitov {
258bc5f75daSAlexei Starovoitov 	struct kfunc_call_test_subprog_lskel *skel;
25904fcb5f9SDelyan Kratunov 	int prog_fd, err;
26004fcb5f9SDelyan Kratunov 	LIBBPF_OPTS(bpf_test_run_opts, topts,
26104fcb5f9SDelyan Kratunov 		.data_in = &pkt_v4,
26204fcb5f9SDelyan Kratunov 		.data_size_in = sizeof(pkt_v4),
26304fcb5f9SDelyan Kratunov 		.repeat = 1,
26404fcb5f9SDelyan Kratunov 	);
265bc5f75daSAlexei Starovoitov 
266bc5f75daSAlexei Starovoitov 	skel = kfunc_call_test_subprog_lskel__open_and_load();
267bc5f75daSAlexei Starovoitov 	if (!ASSERT_OK_PTR(skel, "skel"))
268bc5f75daSAlexei Starovoitov 		return;
269bc5f75daSAlexei Starovoitov 
270bc5f75daSAlexei Starovoitov 	prog_fd = skel->progs.kfunc_call_test1.prog_fd;
27104fcb5f9SDelyan Kratunov 	err = bpf_prog_test_run_opts(prog_fd, &topts);
272bc5f75daSAlexei Starovoitov 	ASSERT_OK(err, "bpf_prog_test_run(test1)");
27304fcb5f9SDelyan Kratunov 	ASSERT_EQ(topts.retval, 10, "test1-retval");
274bc5f75daSAlexei Starovoitov 	ASSERT_NEQ(skel->data->active_res, -1, "active_res");
275bc5f75daSAlexei Starovoitov 	ASSERT_EQ(skel->data->sk_state_res, BPF_TCP_CLOSE, "sk_state_res");
276bc5f75daSAlexei Starovoitov 
277bc5f75daSAlexei Starovoitov 	kfunc_call_test_subprog_lskel__destroy(skel);
278bc5f75daSAlexei Starovoitov }
279bc5f75daSAlexei Starovoitov 
test_destructive_open_and_load(void)280e3389458SArtem Savkov static int test_destructive_open_and_load(void)
281e3389458SArtem Savkov {
282e3389458SArtem Savkov 	struct kfunc_call_destructive *skel;
283e3389458SArtem Savkov 	int err;
284e3389458SArtem Savkov 
285e3389458SArtem Savkov 	skel = kfunc_call_destructive__open();
286e3389458SArtem Savkov 	if (!ASSERT_OK_PTR(skel, "prog_open"))
287e3389458SArtem Savkov 		return -1;
288e3389458SArtem Savkov 
289e3389458SArtem Savkov 	err = kfunc_call_destructive__load(skel);
290e3389458SArtem Savkov 
291e3389458SArtem Savkov 	kfunc_call_destructive__destroy(skel);
292e3389458SArtem Savkov 
293e3389458SArtem Savkov 	return err;
294e3389458SArtem Savkov }
295e3389458SArtem Savkov 
test_destructive(void)296e3389458SArtem Savkov static void test_destructive(void)
297e3389458SArtem Savkov {
298e3389458SArtem Savkov 	__u64 save_caps = 0;
299e3389458SArtem Savkov 
300e918cd23SColin Ian King 	ASSERT_OK(test_destructive_open_and_load(), "successful_load");
301e3389458SArtem Savkov 
302e3389458SArtem Savkov 	if (!ASSERT_OK(cap_disable_effective(1ULL << CAP_SYS_BOOT, &save_caps), "drop_caps"))
303e3389458SArtem Savkov 		return;
304e3389458SArtem Savkov 
305e3389458SArtem Savkov 	ASSERT_EQ(test_destructive_open_and_load(), -13, "no_caps_failure");
306e3389458SArtem Savkov 
307e3389458SArtem Savkov 	cap_enable_effective(save_caps, NULL);
308e3389458SArtem Savkov }
309e3389458SArtem Savkov 
test_kfunc_call(void)3107bd1590dSMartin KaFai Lau void test_kfunc_call(void)
3117bd1590dSMartin KaFai Lau {
3127bd1590dSMartin KaFai Lau 	test_main();
3137bd1590dSMartin KaFai Lau 
3147bd1590dSMartin KaFai Lau 	if (test__start_subtest("subprog"))
3157bd1590dSMartin KaFai Lau 		test_subprog();
316bc5f75daSAlexei Starovoitov 
317bc5f75daSAlexei Starovoitov 	if (test__start_subtest("subprog_lskel"))
318bc5f75daSAlexei Starovoitov 		test_subprog_lskel();
319e3389458SArtem Savkov 
320e3389458SArtem Savkov 	if (test__start_subtest("destructive"))
321e3389458SArtem Savkov 		test_destructive();
3227bd1590dSMartin KaFai Lau }
323