]> Git Repo - linux.git/blob - tools/testing/selftests/bpf/prog_tests/core_extern.c
Linux 6.14-rc3
[linux.git] / tools / testing / selftests / bpf / prog_tests / core_extern.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019 Facebook */
3
4 #include <test_progs.h>
5 #include <sys/mman.h>
6 #include <sys/utsname.h>
7 #include <linux/version.h>
8 #include "test_core_extern.skel.h"
9
10 static uint32_t get_kernel_version(void)
11 {
12         uint32_t major, minor, patch;
13         struct utsname info;
14
15         uname(&info);
16         if (sscanf(info.release, "%u.%u.%u", &major, &minor, &patch) != 3)
17                 return 0;
18         return KERNEL_VERSION(major, minor, patch);
19 }
20
21 #define CFG "CONFIG_BPF_SYSCALL=n\n"
22
23 static struct test_case {
24         const char *name;
25         const char *cfg;
26         bool fails;
27         struct test_core_extern__data data;
28 } test_cases[] = {
29         { .name = "default search path", .data = { .bpf_syscall = true } },
30         {
31                 .name = "custom values",
32                 .cfg = "CONFIG_BPF_SYSCALL=n\n"
33                        "CONFIG_TRISTATE=m\n"
34                        "CONFIG_BOOL=y\n"
35                        "CONFIG_CHAR=100\n"
36                        "CONFIG_USHORT=30000\n"
37                        "CONFIG_INT=123456\n"
38                        "CONFIG_ULONG=0xDEADBEEFC0DE\n"
39                        "CONFIG_STR=\"abracad\"\n"
40                        "CONFIG_MISSING=0",
41                 .data = {
42                         .unkn_virt_val = 0,
43                         .bpf_syscall = false,
44                         .tristate_val = TRI_MODULE,
45                         .bool_val = true,
46                         .char_val = 100,
47                         .ushort_val = 30000,
48                         .int_val = 123456,
49                         .ulong_val = 0xDEADBEEFC0DE,
50                         .str_val = "abracad",
51                 },
52         },
53         /* TRISTATE */
54         { .name = "tristate (y)", .cfg = CFG"CONFIG_TRISTATE=y\n",
55           .data = { .tristate_val = TRI_YES } },
56         { .name = "tristate (n)", .cfg = CFG"CONFIG_TRISTATE=n\n",
57           .data = { .tristate_val = TRI_NO } },
58         { .name = "tristate (m)", .cfg = CFG"CONFIG_TRISTATE=m\n",
59           .data = { .tristate_val = TRI_MODULE } },
60         { .name = "tristate (int)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=1" },
61         { .name = "tristate (bad)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=M" },
62         /* BOOL */
63         { .name = "bool (y)", .cfg = CFG"CONFIG_BOOL=y\n",
64           .data = { .bool_val = true } },
65         { .name = "bool (n)", .cfg = CFG"CONFIG_BOOL=n\n",
66           .data = { .bool_val = false } },
67         { .name = "bool (tristate)", .fails = 1, .cfg = CFG"CONFIG_BOOL=m" },
68         { .name = "bool (int)", .fails = 1, .cfg = CFG"CONFIG_BOOL=1" },
69         /* CHAR */
70         { .name = "char (tristate)", .cfg = CFG"CONFIG_CHAR=m\n",
71           .data = { .char_val = 'm' } },
72         { .name = "char (bad)", .fails = 1, .cfg = CFG"CONFIG_CHAR=q\n" },
73         { .name = "char (empty)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\n" },
74         { .name = "char (str)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\"y\"\n" },
75         /* STRING */
76         { .name = "str (empty)", .cfg = CFG"CONFIG_STR=\"\"\n",
77           .data = { .str_val = "\0\0\0\0\0\0\0" } },
78         { .name = "str (padded)", .cfg = CFG"CONFIG_STR=\"abra\"\n",
79           .data = { .str_val = "abra\0\0\0" } },
80         { .name = "str (too long)", .cfg = CFG"CONFIG_STR=\"abracada\"\n",
81           .data = { .str_val = "abracad" } },
82         { .name = "str (no value)", .fails = 1, .cfg = CFG"CONFIG_STR=\n" },
83         { .name = "str (bad value)", .fails = 1, .cfg = CFG"CONFIG_STR=bla\n" },
84         /* INTEGERS */
85         {
86                 .name = "integer forms",
87                 .cfg = CFG
88                        "CONFIG_CHAR=0xA\n"
89                        "CONFIG_USHORT=0462\n"
90                        "CONFIG_INT=-100\n"
91                        "CONFIG_ULONG=+1000000000000",
92                 .data = {
93                         .char_val = 0xA,
94                         .ushort_val = 0462,
95                         .int_val = -100,
96                         .ulong_val = 1000000000000,
97                 },
98         },
99         { .name = "int (bad)", .fails = 1, .cfg = CFG"CONFIG_INT=abc" },
100         { .name = "int (str)", .fails = 1, .cfg = CFG"CONFIG_INT=\"abc\"" },
101         { .name = "int (empty)", .fails = 1, .cfg = CFG"CONFIG_INT=" },
102         { .name = "int (mixed)", .fails = 1, .cfg = CFG"CONFIG_INT=123abc" },
103         { .name = "int (max)", .cfg = CFG"CONFIG_INT=2147483647",
104           .data = { .int_val = 2147483647 } },
105         { .name = "int (min)", .cfg = CFG"CONFIG_INT=-2147483648",
106           .data = { .int_val = -2147483648 } },
107         { .name = "int (max+1)", .fails = 1, .cfg = CFG"CONFIG_INT=2147483648" },
108         { .name = "int (min-1)", .fails = 1, .cfg = CFG"CONFIG_INT=-2147483649" },
109         { .name = "ushort (max)", .cfg = CFG"CONFIG_USHORT=65535",
110           .data = { .ushort_val = 65535 } },
111         { .name = "ushort (min)", .cfg = CFG"CONFIG_USHORT=0",
112           .data = { .ushort_val = 0 } },
113         { .name = "ushort (max+1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=65536" },
114         { .name = "ushort (min-1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=-1" },
115         { .name = "u64 (max)", .cfg = CFG"CONFIG_ULONG=0xffffffffffffffff",
116           .data = { .ulong_val = 0xffffffffffffffff } },
117         { .name = "u64 (min)", .cfg = CFG"CONFIG_ULONG=0",
118           .data = { .ulong_val = 0 } },
119         { .name = "u64 (max+1)", .fails = 1, .cfg = CFG"CONFIG_ULONG=0x10000000000000000" },
120 };
121
122 void test_core_extern(void)
123 {
124         const uint32_t kern_ver = get_kernel_version();
125         int err, i, j;
126         struct test_core_extern *skel = NULL;
127         uint64_t *got, *exp;
128         int n = sizeof(*skel->data) / sizeof(uint64_t);
129
130         for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
131                 struct test_case *t = &test_cases[i];
132                 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
133                         .kconfig = t->cfg,
134                 );
135
136                 if (!test__start_subtest(t->name))
137                         continue;
138
139                 skel = test_core_extern__open_opts(&opts);
140                 if (!ASSERT_OK_PTR(skel, "skel_open"))
141                         goto cleanup;
142                 err = test_core_extern__load(skel);
143                 if (t->fails) {
144                         ASSERT_ERR(err, "skel_load_should_fail");
145                         goto cleanup;
146                 } else if (!ASSERT_OK(err, "skel_load")) {
147                         goto cleanup;
148                 }
149                 err = test_core_extern__attach(skel);
150                 if (!ASSERT_OK(err, "attach_raw_tp"))
151                         goto cleanup;
152
153                 usleep(1);
154
155                 t->data.kern_ver = kern_ver;
156                 t->data.missing_val = 0xDEADC0DE;
157                 got = (uint64_t *)skel->data;
158                 exp = (uint64_t *)&t->data;
159                 for (j = 0; j < n; j++) {
160                         ASSERT_EQ(got[j], exp[j], "result");
161                 }
162 cleanup:
163                 test_core_extern__destroy(skel);
164                 skel = NULL;
165         }
166 }
This page took 0.051886 seconds and 4 git commands to generate.