xref: /openbmc/linux/tools/testing/selftests/bpf/prog_tests/dummy_st_ops.c (revision ee1cd5048959de496cd005c50b137212a5b62062)
1  // SPDX-License-Identifier: GPL-2.0
2  /* Copyright (C) 2021. Huawei Technologies Co., Ltd */
3  #include <test_progs.h>
4  #include "dummy_st_ops_success.skel.h"
5  #include "dummy_st_ops_fail.skel.h"
6  #include "trace_dummy_st_ops.skel.h"
7  
8  /* Need to keep consistent with definition in include/linux/bpf.h */
9  struct bpf_dummy_ops_state {
10  	int val;
11  };
12  
test_dummy_st_ops_attach(void)13  static void test_dummy_st_ops_attach(void)
14  {
15  	struct dummy_st_ops_success *skel;
16  	struct bpf_link *link;
17  
18  	skel = dummy_st_ops_success__open_and_load();
19  	if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
20  		return;
21  
22  	link = bpf_map__attach_struct_ops(skel->maps.dummy_1);
23  	ASSERT_EQ(libbpf_get_error(link), -EOPNOTSUPP, "dummy_st_ops_attach");
24  
25  	dummy_st_ops_success__destroy(skel);
26  }
27  
test_dummy_init_ret_value(void)28  static void test_dummy_init_ret_value(void)
29  {
30  	__u64 args[1] = {0};
31  	LIBBPF_OPTS(bpf_test_run_opts, attr,
32  		.ctx_in = args,
33  		.ctx_size_in = sizeof(args),
34  	);
35  	struct dummy_st_ops_success *skel;
36  	int fd, err;
37  
38  	skel = dummy_st_ops_success__open_and_load();
39  	if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
40  		return;
41  
42  	fd = bpf_program__fd(skel->progs.test_1);
43  	err = bpf_prog_test_run_opts(fd, &attr);
44  	ASSERT_OK(err, "test_run");
45  	ASSERT_EQ(attr.retval, 0xf2f3f4f5, "test_ret");
46  
47  	dummy_st_ops_success__destroy(skel);
48  }
49  
test_dummy_init_ptr_arg(void)50  static void test_dummy_init_ptr_arg(void)
51  {
52  	int exp_retval = 0xbeef;
53  	struct bpf_dummy_ops_state in_state = {
54  		.val = exp_retval,
55  	};
56  	__u64 args[1] = {(unsigned long)&in_state};
57  	LIBBPF_OPTS(bpf_test_run_opts, attr,
58  		.ctx_in = args,
59  		.ctx_size_in = sizeof(args),
60  	);
61  	struct trace_dummy_st_ops *trace_skel;
62  	struct dummy_st_ops_success *skel;
63  	int fd, err;
64  
65  	skel = dummy_st_ops_success__open_and_load();
66  	if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
67  		return;
68  
69  	fd = bpf_program__fd(skel->progs.test_1);
70  
71  	trace_skel = trace_dummy_st_ops__open();
72  	if (!ASSERT_OK_PTR(trace_skel, "trace_dummy_st_ops__open"))
73  		goto done;
74  
75  	err = bpf_program__set_attach_target(trace_skel->progs.fentry_test_1,
76  					     fd, "test_1");
77  	if (!ASSERT_OK(err, "set_attach_target(fentry_test_1)"))
78  		goto done;
79  
80  	err = trace_dummy_st_ops__load(trace_skel);
81  	if (!ASSERT_OK(err, "load(trace_skel)"))
82  		goto done;
83  
84  	err = trace_dummy_st_ops__attach(trace_skel);
85  	if (!ASSERT_OK(err, "attach(trace_skel)"))
86  		goto done;
87  
88  	err = bpf_prog_test_run_opts(fd, &attr);
89  	ASSERT_OK(err, "test_run");
90  	ASSERT_EQ(in_state.val, 0x5a, "test_ptr_ret");
91  	ASSERT_EQ(attr.retval, exp_retval, "test_ret");
92  	ASSERT_EQ(trace_skel->bss->val, exp_retval, "fentry_val");
93  
94  done:
95  	dummy_st_ops_success__destroy(skel);
96  	trace_dummy_st_ops__destroy(trace_skel);
97  }
98  
test_dummy_multiple_args(void)99  static void test_dummy_multiple_args(void)
100  {
101  	struct bpf_dummy_ops_state st = { 7 };
102  	__u64 args[5] = {(__u64)&st, -100, 0x8a5f, 'c', 0x1234567887654321ULL};
103  	LIBBPF_OPTS(bpf_test_run_opts, attr,
104  		.ctx_in = args,
105  		.ctx_size_in = sizeof(args),
106  	);
107  	struct dummy_st_ops_success *skel;
108  	int fd, err;
109  	size_t i;
110  	char name[8];
111  
112  	skel = dummy_st_ops_success__open_and_load();
113  	if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
114  		return;
115  
116  	fd = bpf_program__fd(skel->progs.test_2);
117  	err = bpf_prog_test_run_opts(fd, &attr);
118  	ASSERT_OK(err, "test_run");
119  	args[0] = 7;
120  	for (i = 0; i < ARRAY_SIZE(args); i++) {
121  		snprintf(name, sizeof(name), "arg %zu", i);
122  		ASSERT_EQ(skel->bss->test_2_args[i], args[i], name);
123  	}
124  
125  	dummy_st_ops_success__destroy(skel);
126  }
127  
test_dummy_sleepable(void)128  static void test_dummy_sleepable(void)
129  {
130  	struct bpf_dummy_ops_state st;
131  	__u64 args[1] = {(__u64)&st};
132  	LIBBPF_OPTS(bpf_test_run_opts, attr,
133  		.ctx_in = args,
134  		.ctx_size_in = sizeof(args),
135  	);
136  	struct dummy_st_ops_success *skel;
137  	int fd, err;
138  
139  	skel = dummy_st_ops_success__open_and_load();
140  	if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
141  		return;
142  
143  	fd = bpf_program__fd(skel->progs.test_sleepable);
144  	err = bpf_prog_test_run_opts(fd, &attr);
145  	ASSERT_OK(err, "test_run");
146  
147  	dummy_st_ops_success__destroy(skel);
148  }
149  
150  /* dummy_st_ops.test_sleepable() parameter is not marked as nullable,
151   * thus bpf_prog_test_run_opts() below should be rejected as it tries
152   * to pass NULL for this parameter.
153   */
test_dummy_sleepable_reject_null(void)154  static void test_dummy_sleepable_reject_null(void)
155  {
156  	__u64 args[1] = {0};
157  	LIBBPF_OPTS(bpf_test_run_opts, attr,
158  		.ctx_in = args,
159  		.ctx_size_in = sizeof(args),
160  	);
161  	struct dummy_st_ops_success *skel;
162  	int fd, err;
163  
164  	skel = dummy_st_ops_success__open_and_load();
165  	if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
166  		return;
167  
168  	fd = bpf_program__fd(skel->progs.test_sleepable);
169  	err = bpf_prog_test_run_opts(fd, &attr);
170  	ASSERT_EQ(err, -EINVAL, "test_run");
171  
172  	dummy_st_ops_success__destroy(skel);
173  }
174  
test_dummy_st_ops(void)175  void test_dummy_st_ops(void)
176  {
177  	if (test__start_subtest("dummy_st_ops_attach"))
178  		test_dummy_st_ops_attach();
179  	if (test__start_subtest("dummy_init_ret_value"))
180  		test_dummy_init_ret_value();
181  	if (test__start_subtest("dummy_init_ptr_arg"))
182  		test_dummy_init_ptr_arg();
183  	if (test__start_subtest("dummy_multiple_args"))
184  		test_dummy_multiple_args();
185  	if (test__start_subtest("dummy_sleepable"))
186  		test_dummy_sleepable();
187  	if (test__start_subtest("dummy_sleepable_reject_null"))
188  		test_dummy_sleepable_reject_null();
189  
190  	RUN_TESTS(dummy_st_ops_fail);
191  }
192