File Index
Files and directories
Sign in
FILE

core_extern.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/core_extern.c 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
 10static 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
 23static 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
122void 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		}
162cleanup:
163		test_core_extern__destroy(skel);
164		skel = NULL;
165	}
166}
~/ Read-only file preview.