Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2019 Facebook */
0003 
0004 #include <test_progs.h>
0005 #include <sys/mman.h>
0006 #include <sys/utsname.h>
0007 #include <linux/version.h>
0008 #include "test_core_extern.skel.h"
0009 
0010 static uint32_t get_kernel_version(void)
0011 {
0012     uint32_t major, minor, patch;
0013     struct utsname info;
0014 
0015     uname(&info);
0016     if (sscanf(info.release, "%u.%u.%u", &major, &minor, &patch) != 3)
0017         return 0;
0018     return KERNEL_VERSION(major, minor, patch);
0019 }
0020 
0021 #define CFG "CONFIG_BPF_SYSCALL=n\n"
0022 
0023 static struct test_case {
0024     const char *name;
0025     const char *cfg;
0026     bool fails;
0027     struct test_core_extern__data data;
0028 } test_cases[] = {
0029     { .name = "default search path", .data = { .bpf_syscall = true } },
0030     {
0031         .name = "custom values",
0032         .cfg = "CONFIG_BPF_SYSCALL=n\n"
0033                "CONFIG_TRISTATE=m\n"
0034                "CONFIG_BOOL=y\n"
0035                "CONFIG_CHAR=100\n"
0036                "CONFIG_USHORT=30000\n"
0037                "CONFIG_INT=123456\n"
0038                "CONFIG_ULONG=0xDEADBEEFC0DE\n"
0039                "CONFIG_STR=\"abracad\"\n"
0040                "CONFIG_MISSING=0",
0041         .data = {
0042             .unkn_virt_val = 0,
0043             .bpf_syscall = false,
0044             .tristate_val = TRI_MODULE,
0045             .bool_val = true,
0046             .char_val = 100,
0047             .ushort_val = 30000,
0048             .int_val = 123456,
0049             .ulong_val = 0xDEADBEEFC0DE,
0050             .str_val = "abracad",
0051         },
0052     },
0053     /* TRISTATE */
0054     { .name = "tristate (y)", .cfg = CFG"CONFIG_TRISTATE=y\n",
0055       .data = { .tristate_val = TRI_YES } },
0056     { .name = "tristate (n)", .cfg = CFG"CONFIG_TRISTATE=n\n",
0057       .data = { .tristate_val = TRI_NO } },
0058     { .name = "tristate (m)", .cfg = CFG"CONFIG_TRISTATE=m\n",
0059       .data = { .tristate_val = TRI_MODULE } },
0060     { .name = "tristate (int)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=1" },
0061     { .name = "tristate (bad)", .fails = 1, .cfg = CFG"CONFIG_TRISTATE=M" },
0062     /* BOOL */
0063     { .name = "bool (y)", .cfg = CFG"CONFIG_BOOL=y\n",
0064       .data = { .bool_val = true } },
0065     { .name = "bool (n)", .cfg = CFG"CONFIG_BOOL=n\n",
0066       .data = { .bool_val = false } },
0067     { .name = "bool (tristate)", .fails = 1, .cfg = CFG"CONFIG_BOOL=m" },
0068     { .name = "bool (int)", .fails = 1, .cfg = CFG"CONFIG_BOOL=1" },
0069     /* CHAR */
0070     { .name = "char (tristate)", .cfg = CFG"CONFIG_CHAR=m\n",
0071       .data = { .char_val = 'm' } },
0072     { .name = "char (bad)", .fails = 1, .cfg = CFG"CONFIG_CHAR=q\n" },
0073     { .name = "char (empty)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\n" },
0074     { .name = "char (str)", .fails = 1, .cfg = CFG"CONFIG_CHAR=\"y\"\n" },
0075     /* STRING */
0076     { .name = "str (empty)", .cfg = CFG"CONFIG_STR=\"\"\n",
0077       .data = { .str_val = "\0\0\0\0\0\0\0" } },
0078     { .name = "str (padded)", .cfg = CFG"CONFIG_STR=\"abra\"\n",
0079       .data = { .str_val = "abra\0\0\0" } },
0080     { .name = "str (too long)", .cfg = CFG"CONFIG_STR=\"abracada\"\n",
0081       .data = { .str_val = "abracad" } },
0082     { .name = "str (no value)", .fails = 1, .cfg = CFG"CONFIG_STR=\n" },
0083     { .name = "str (bad value)", .fails = 1, .cfg = CFG"CONFIG_STR=bla\n" },
0084     /* INTEGERS */
0085     {
0086         .name = "integer forms",
0087         .cfg = CFG
0088                "CONFIG_CHAR=0xA\n"
0089                "CONFIG_USHORT=0462\n"
0090                "CONFIG_INT=-100\n"
0091                "CONFIG_ULONG=+1000000000000",
0092         .data = {
0093             .char_val = 0xA,
0094             .ushort_val = 0462,
0095             .int_val = -100,
0096             .ulong_val = 1000000000000,
0097         },
0098     },
0099     { .name = "int (bad)", .fails = 1, .cfg = CFG"CONFIG_INT=abc" },
0100     { .name = "int (str)", .fails = 1, .cfg = CFG"CONFIG_INT=\"abc\"" },
0101     { .name = "int (empty)", .fails = 1, .cfg = CFG"CONFIG_INT=" },
0102     { .name = "int (mixed)", .fails = 1, .cfg = CFG"CONFIG_INT=123abc" },
0103     { .name = "int (max)", .cfg = CFG"CONFIG_INT=2147483647",
0104       .data = { .int_val = 2147483647 } },
0105     { .name = "int (min)", .cfg = CFG"CONFIG_INT=-2147483648",
0106       .data = { .int_val = -2147483648 } },
0107     { .name = "int (max+1)", .fails = 1, .cfg = CFG"CONFIG_INT=2147483648" },
0108     { .name = "int (min-1)", .fails = 1, .cfg = CFG"CONFIG_INT=-2147483649" },
0109     { .name = "ushort (max)", .cfg = CFG"CONFIG_USHORT=65535",
0110       .data = { .ushort_val = 65535 } },
0111     { .name = "ushort (min)", .cfg = CFG"CONFIG_USHORT=0",
0112       .data = { .ushort_val = 0 } },
0113     { .name = "ushort (max+1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=65536" },
0114     { .name = "ushort (min-1)", .fails = 1, .cfg = CFG"CONFIG_USHORT=-1" },
0115     { .name = "u64 (max)", .cfg = CFG"CONFIG_ULONG=0xffffffffffffffff",
0116       .data = { .ulong_val = 0xffffffffffffffff } },
0117     { .name = "u64 (min)", .cfg = CFG"CONFIG_ULONG=0",
0118       .data = { .ulong_val = 0 } },
0119     { .name = "u64 (max+1)", .fails = 1, .cfg = CFG"CONFIG_ULONG=0x10000000000000000" },
0120 };
0121 
0122 void test_core_extern(void)
0123 {
0124     const uint32_t kern_ver = get_kernel_version();
0125     int err, i, j;
0126     struct test_core_extern *skel = NULL;
0127     uint64_t *got, *exp;
0128     int n = sizeof(*skel->data) / sizeof(uint64_t);
0129 
0130     for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
0131         struct test_case *t = &test_cases[i];
0132         DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
0133             .kconfig = t->cfg,
0134         );
0135 
0136         if (!test__start_subtest(t->name))
0137             continue;
0138 
0139         skel = test_core_extern__open_opts(&opts);
0140         if (!ASSERT_OK_PTR(skel, "skel_open"))
0141             goto cleanup;
0142         err = test_core_extern__load(skel);
0143         if (t->fails) {
0144             ASSERT_ERR(err, "skel_load_should_fail");
0145             goto cleanup;
0146         } else if (!ASSERT_OK(err, "skel_load")) {
0147             goto cleanup;
0148         }
0149         err = test_core_extern__attach(skel);
0150         if (!ASSERT_OK(err, "attach_raw_tp"))
0151             goto cleanup;
0152 
0153         usleep(1);
0154 
0155         t->data.kern_ver = kern_ver;
0156         t->data.missing_val = 0xDEADC0DE;
0157         got = (uint64_t *)skel->data;
0158         exp = (uint64_t *)&t->data;
0159         for (j = 0; j < n; j++) {
0160             ASSERT_EQ(got[j], exp[j], "result");
0161         }
0162 cleanup:
0163         test_core_extern__destroy(skel);
0164         skel = NULL;
0165     }
0166 }