Merge tag 'efi-urgent-2020-08-23' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.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                         .bpf_syscall = false,
43                         .tristate_val = TRI_MODULE,
44                         .bool_val = true,
45                         .char_val = 100,
46                         .ushort_val = 30000,
47                         .int_val = 123456,
48                         .ulong_val = 0xDEADBEEFC0DE,
49                         .str_val = "abracad",
50                 },
51         },
52         /* TRISTATE */
53         { .name = "tristate (y)", .cfg = CFG"CONFIG_TRISTATE=y\n",
54           .data = { .tristate_val = TRI_YES } },
55         { .name = "tristate (n)", .cfg = CFG"CONFIG_TRISTATE=n\n",
56           .data = { .tristate_val = TRI_NO } },
57         { .name = "tristate (m)", .cfg = CFG"CONFIG_TRISTATE=m\n",
58           .data = { .tristate_val = TRI_MODULE } },
59         { .name = "tristate (int)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=1" },
60         { .name = "tristate (bad)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=M" },
61         /* BOOL */
62         { .name = "bool (y)", .cfg = CFG"CONFIG_BOOL=y\n",
63           .data = { .bool_val = true } },
64         { .name = "bool (n)", .cfg = CFG"CONFIG_BOOL=n\n",
65           .data = { .bool_val = false } },
66         { .name = "bool (tristate)", .fails = 1, .cfg = CFG"CONFIG_BOOL=m" },
67         { .name = "bool (int)", .fails = 1, .cfg = CFG"CONFIG_BOOL=1" },
68         /* CHAR */
69         { .name = "char (tristate)", .cfg = CFG"CONFIG_CHAR=m\n",
70           .data = { .char_val = 'm' } },
71         { .name = "char (bad)", .fails = 1, .cfg = CFG"CONFIG_CHAR=q\n" },
72         { .name = "char (empty)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\n" },
73         { .name = "char (str)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\"y\"\n" },
74         /* STRING */
75         { .name = "str (empty)", .cfg = CFG"CONFIG_STR=\"\"\n",
76           .data = { .str_val = "\0\0\0\0\0\0\0" } },
77         { .name = "str (padded)", .cfg = CFG"CONFIG_STR=\"abra\"\n",
78           .data = { .str_val = "abra\0\0\0" } },
79         { .name = "str (too long)", .cfg = CFG"CONFIG_STR=\"abracada\"\n",
80           .data = { .str_val = "abracad" } },
81         { .name = "str (no value)", .fails = 1, .cfg = CFG"CONFIG_STR=\n" },
82         { .name = "str (bad value)", .fails = 1, .cfg = CFG"CONFIG_STR=bla\n" },
83         /* INTEGERS */
84         {
85                 .name = "integer forms",
86                 .cfg = CFG
87                        "CONFIG_CHAR=0xA\n"
88                        "CONFIG_USHORT=0462\n"
89                        "CONFIG_INT=-100\n"
90                        "CONFIG_ULONG=+1000000000000",
91                 .data = {
92                         .char_val = 0xA,
93                         .ushort_val = 0462,
94                         .int_val = -100,
95                         .ulong_val = 1000000000000,
96                 },
97         },
98         { .name = "int (bad)", .fails = 1, .cfg = CFG"CONFIG_INT=abc" },
99         { .name = "int (str)", .fails = 1, .cfg = CFG"CONFIG_INT=\"abc\"" },
100         { .name = "int (empty)", .fails = 1, .cfg = CFG"CONFIG_INT=" },
101         { .name = "int (mixed)", .fails = 1, .cfg = CFG"CONFIG_INT=123abc" },
102         { .name = "int (max)", .cfg = CFG"CONFIG_INT=2147483647",
103           .data = { .int_val = 2147483647 } },
104         { .name = "int (min)", .cfg = CFG"CONFIG_INT=-2147483648",
105           .data = { .int_val = -2147483648 } },
106         { .name = "int (max+1)", .fails = 1, .cfg = CFG"CONFIG_INT=2147483648" },
107         { .name = "int (min-1)", .fails = 1, .cfg = CFG"CONFIG_INT=-2147483649" },
108         { .name = "ushort (max)", .cfg = CFG"CONFIG_USHORT=65535",
109           .data = { .ushort_val = 65535 } },
110         { .name = "ushort (min)", .cfg = CFG"CONFIG_USHORT=0",
111           .data = { .ushort_val = 0 } },
112         { .name = "ushort (max+1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=65536" },
113         { .name = "ushort (min-1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=-1" },
114         { .name = "u64 (max)", .cfg = CFG"CONFIG_ULONG=0xffffffffffffffff",
115           .data = { .ulong_val = 0xffffffffffffffff } },
116         { .name = "u64 (min)", .cfg = CFG"CONFIG_ULONG=0",
117           .data = { .ulong_val = 0 } },
118         { .name = "u64 (max+1)", .fails = 1, .cfg = CFG"CONFIG_ULONG=0x10000000000000000" },
119 };
120
121 void test_core_extern(void)
122 {
123         const uint32_t kern_ver = get_kernel_version();
124         int err, duration = 0, i, j;
125         struct test_core_extern *skel = NULL;
126         uint64_t *got, *exp;
127         int n = sizeof(*skel->data) / sizeof(uint64_t);
128
129         for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
130                 struct test_case *t = &test_cases[i];
131                 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
132                         .kconfig = t->cfg,
133                 );
134
135                 if (!test__start_subtest(t->name))
136                         continue;
137
138                 skel = test_core_extern__open_opts(&opts);
139                 if (CHECK(!skel, "skel_open", "skeleton open failed\n"))
140                         goto cleanup;
141                 err = test_core_extern__load(skel);
142                 if (t->fails) {
143                         CHECK(!err, "skel_load",
144                               "shouldn't succeed open/load of skeleton\n");
145                         goto cleanup;
146                 } else if (CHECK(err, "skel_load",
147                                  "failed to open/load skeleton\n")) {
148                         goto cleanup;
149                 }
150                 err = test_core_extern__attach(skel);
151                 if (CHECK(err, "attach_raw_tp", "failed attach: %d\n", err))
152                         goto cleanup;
153
154                 usleep(1);
155
156                 t->data.kern_ver = kern_ver;
157                 t->data.missing_val = 0xDEADC0DE;
158                 got = (uint64_t *)skel->data;
159                 exp = (uint64_t *)&t->data;
160                 for (j = 0; j < n; j++) {
161                         CHECK(got[j] != exp[j], "check_res",
162                               "result #%d: expected %llx, but got %llx\n",
163                                j, (__u64)exp[j], (__u64)got[j]);
164                 }
165 cleanup:
166                 test_core_extern__destroy(skel);
167                 skel = NULL;
168         }
169 }