Skip to content

Commit 31122b2

Browse files
Hou TaoAlexei Starovoitov
authored andcommitted
selftests/bpf: Add test cases for struct_ops prog
Running a BPF_PROG_TYPE_STRUCT_OPS prog for dummy_st_ops::test_N() through bpf_prog_test_run(). Four test cases are added: (1) attach dummy_st_ops should fail (2) function return value of bpf_dummy_ops::test_1() is expected (3) pointer argument of bpf_dummy_ops::test_1() works as expected (4) multiple arguments passed to bpf_dummy_ops::test_2() are correct Signed-off-by: Hou Tao <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent c196906 commit 31122b2

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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.skel.h"
5+
6+
/* Need to keep consistent with definition in include/linux/bpf.h */
7+
struct bpf_dummy_ops_state {
8+
int val;
9+
};
10+
11+
static void test_dummy_st_ops_attach(void)
12+
{
13+
struct dummy_st_ops *skel;
14+
struct bpf_link *link;
15+
16+
skel = dummy_st_ops__open_and_load();
17+
if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
18+
return;
19+
20+
link = bpf_map__attach_struct_ops(skel->maps.dummy_1);
21+
ASSERT_EQ(libbpf_get_error(link), -EOPNOTSUPP, "dummy_st_ops_attach");
22+
23+
dummy_st_ops__destroy(skel);
24+
}
25+
26+
static void test_dummy_init_ret_value(void)
27+
{
28+
__u64 args[1] = {0};
29+
struct bpf_prog_test_run_attr attr = {
30+
.ctx_size_in = sizeof(args),
31+
.ctx_in = args,
32+
};
33+
struct dummy_st_ops *skel;
34+
int fd, err;
35+
36+
skel = dummy_st_ops__open_and_load();
37+
if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
38+
return;
39+
40+
fd = bpf_program__fd(skel->progs.test_1);
41+
attr.prog_fd = fd;
42+
err = bpf_prog_test_run_xattr(&attr);
43+
ASSERT_OK(err, "test_run");
44+
ASSERT_EQ(attr.retval, 0xf2f3f4f5, "test_ret");
45+
46+
dummy_st_ops__destroy(skel);
47+
}
48+
49+
static void test_dummy_init_ptr_arg(void)
50+
{
51+
int exp_retval = 0xbeef;
52+
struct bpf_dummy_ops_state in_state = {
53+
.val = exp_retval,
54+
};
55+
__u64 args[1] = {(unsigned long)&in_state};
56+
struct bpf_prog_test_run_attr attr = {
57+
.ctx_size_in = sizeof(args),
58+
.ctx_in = args,
59+
};
60+
struct dummy_st_ops *skel;
61+
int fd, err;
62+
63+
skel = dummy_st_ops__open_and_load();
64+
if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
65+
return;
66+
67+
fd = bpf_program__fd(skel->progs.test_1);
68+
attr.prog_fd = fd;
69+
err = bpf_prog_test_run_xattr(&attr);
70+
ASSERT_OK(err, "test_run");
71+
ASSERT_EQ(in_state.val, 0x5a, "test_ptr_ret");
72+
ASSERT_EQ(attr.retval, exp_retval, "test_ret");
73+
74+
dummy_st_ops__destroy(skel);
75+
}
76+
77+
static void test_dummy_multiple_args(void)
78+
{
79+
__u64 args[5] = {0, -100, 0x8a5f, 'c', 0x1234567887654321ULL};
80+
struct bpf_prog_test_run_attr attr = {
81+
.ctx_size_in = sizeof(args),
82+
.ctx_in = args,
83+
};
84+
struct dummy_st_ops *skel;
85+
int fd, err;
86+
size_t i;
87+
char name[8];
88+
89+
skel = dummy_st_ops__open_and_load();
90+
if (!ASSERT_OK_PTR(skel, "dummy_st_ops_load"))
91+
return;
92+
93+
fd = bpf_program__fd(skel->progs.test_2);
94+
attr.prog_fd = fd;
95+
err = bpf_prog_test_run_xattr(&attr);
96+
ASSERT_OK(err, "test_run");
97+
for (i = 0; i < ARRAY_SIZE(args); i++) {
98+
snprintf(name, sizeof(name), "arg %zu", i);
99+
ASSERT_EQ(skel->bss->test_2_args[i], args[i], name);
100+
}
101+
102+
dummy_st_ops__destroy(skel);
103+
}
104+
105+
void test_dummy_st_ops(void)
106+
{
107+
if (test__start_subtest("dummy_st_ops_attach"))
108+
test_dummy_st_ops_attach();
109+
if (test__start_subtest("dummy_init_ret_value"))
110+
test_dummy_init_ret_value();
111+
if (test__start_subtest("dummy_init_ptr_arg"))
112+
test_dummy_init_ptr_arg();
113+
if (test__start_subtest("dummy_multiple_args"))
114+
test_dummy_multiple_args();
115+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright (C) 2021. Huawei Technologies Co., Ltd */
3+
#include <linux/bpf.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include <bpf/bpf_tracing.h>
6+
7+
struct bpf_dummy_ops_state {
8+
int val;
9+
} __attribute__((preserve_access_index));
10+
11+
struct bpf_dummy_ops {
12+
int (*test_1)(struct bpf_dummy_ops_state *state);
13+
int (*test_2)(struct bpf_dummy_ops_state *state, int a1, unsigned short a2,
14+
char a3, unsigned long a4);
15+
};
16+
17+
char _license[] SEC("license") = "GPL";
18+
19+
SEC("struct_ops/test_1")
20+
int BPF_PROG(test_1, struct bpf_dummy_ops_state *state)
21+
{
22+
int ret;
23+
24+
if (!state)
25+
return 0xf2f3f4f5;
26+
27+
ret = state->val;
28+
state->val = 0x5a;
29+
return ret;
30+
}
31+
32+
__u64 test_2_args[5];
33+
34+
SEC("struct_ops/test_2")
35+
int BPF_PROG(test_2, struct bpf_dummy_ops_state *state, int a1, unsigned short a2,
36+
char a3, unsigned long a4)
37+
{
38+
test_2_args[0] = (unsigned long)state;
39+
test_2_args[1] = a1;
40+
test_2_args[2] = a2;
41+
test_2_args[3] = a3;
42+
test_2_args[4] = a4;
43+
return 0;
44+
}
45+
46+
SEC(".struct_ops")
47+
struct bpf_dummy_ops dummy_1 = {
48+
.test_1 = (void *)test_1,
49+
.test_2 = (void *)test_2,
50+
};

0 commit comments

Comments
 (0)