2022-01-24 23:16:20 +09:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef __BPF_MISC_H__
|
|
|
|
#define __BPF_MISC_H__
|
|
|
|
|
2023-03-01 19:54:17 +02:00
|
|
|
/* This set of attributes controls behavior of the
|
|
|
|
* test_loader.c:test_loader__run_subtests().
|
|
|
|
*
|
2023-03-25 04:54:44 +02:00
|
|
|
* The test_loader sequentially loads each program in a skeleton.
|
|
|
|
* Programs could be loaded in privileged and unprivileged modes.
|
|
|
|
* - __success, __failure, __msg imply privileged mode;
|
|
|
|
* - __success_unpriv, __failure_unpriv, __msg_unpriv imply
|
|
|
|
* unprivileged mode.
|
|
|
|
* If combination of privileged and unprivileged attributes is present
|
|
|
|
* both modes are used. If none are present privileged mode is implied.
|
|
|
|
*
|
|
|
|
* See test_loader.c:drop_capabilities() for exact set of capabilities
|
|
|
|
* that differ between privileged and unprivileged modes.
|
|
|
|
*
|
|
|
|
* For test filtering purposes the name of the program loaded in
|
|
|
|
* unprivileged mode is derived from the usual program name by adding
|
|
|
|
* `@unpriv' suffix.
|
|
|
|
*
|
2023-03-01 19:54:17 +02:00
|
|
|
* __msg Message expected to be found in the verifier log.
|
|
|
|
* Multiple __msg attributes could be specified.
|
2023-03-25 04:54:44 +02:00
|
|
|
* __msg_unpriv Same as __msg but for unprivileged mode.
|
2023-03-01 19:54:17 +02:00
|
|
|
*
|
|
|
|
* __success Expect program load success in privileged mode.
|
2023-03-25 04:54:44 +02:00
|
|
|
* __success_unpriv Expect program load success in unprivileged mode.
|
2023-03-01 19:54:17 +02:00
|
|
|
*
|
|
|
|
* __failure Expect program load failure in privileged mode.
|
2023-03-25 04:54:44 +02:00
|
|
|
* __failure_unpriv Expect program load failure in unprivileged mode.
|
|
|
|
*
|
2023-03-25 04:54:45 +02:00
|
|
|
* __retval Execute the program using BPF_PROG_TEST_RUN command,
|
|
|
|
* expect return value to match passed parameter:
|
|
|
|
* - a decimal number
|
|
|
|
* - a hexadecimal number, when starts from 0x
|
|
|
|
* - literal INT_MIN
|
|
|
|
* - literal POINTER_VALUE (see definition below)
|
|
|
|
* - literal TEST_DATA_LEN (see definition below)
|
|
|
|
* __retval_unpriv Same, but load program in unprivileged mode.
|
|
|
|
*
|
2023-03-25 04:54:44 +02:00
|
|
|
* __description Text to be used instead of a program name for display
|
|
|
|
* and filtering purposes.
|
2023-03-01 19:54:17 +02:00
|
|
|
*
|
|
|
|
* __log_level Log level to use for the program, numeric value expected.
|
|
|
|
*
|
|
|
|
* __flag Adds one flag use for the program, the following values are valid:
|
|
|
|
* - BPF_F_STRICT_ALIGNMENT;
|
|
|
|
* - BPF_F_TEST_RND_HI32;
|
|
|
|
* - BPF_F_TEST_STATE_FREQ;
|
|
|
|
* - BPF_F_SLEEPABLE;
|
|
|
|
* - BPF_F_XDP_HAS_FRAGS;
|
|
|
|
* - A numeric value.
|
|
|
|
* Multiple __flag attributes could be specified, the final flags
|
|
|
|
* value is derived by applying binary "or" to all specified values.
|
2023-04-21 20:42:11 +03:00
|
|
|
*
|
|
|
|
* __auxiliary Annotated program is not a separate test, but used as auxiliary
|
|
|
|
* for some other test cases and should always be loaded.
|
|
|
|
* __auxiliary_unpriv Same, but load program in unprivileged mode.
|
2023-03-01 19:54:17 +02:00
|
|
|
*/
|
selftests/bpf: add generic BPF program tester-loader
It's become a common pattern to have a collection of small BPF programs
in one BPF object file, each representing one test case. On user-space
side of such tests we maintain a table of program names and expected
failure or success, along with optional expected verifier log message.
This works, but each set of tests reimplement this mundane code over and
over again, which is a waste of time for anyone trying to add a new set
of tests. Furthermore, it's quite error prone as it's way too easy to miss
some entries in these manually maintained test tables (as evidences by
dynptr_fail tests, in which ringbuf_release_uninit_dynptr subtest was
accidentally missed; this is fixed in next patch).
So this patch implements generic test_loader, which accepts skeleton
name and handles the rest of details: opens and loads BPF object file,
making sure each program is tested in isolation. Optionally each test
case can specify expected BPF verifier log message. In case of failure,
tester makes sure to report verifier log, but it also reports verifier
log in verbose mode unconditionally.
Now, the interesting deviation from existing custom implementations is
the use of btf_decl_tag attribute to specify expected-to-fail vs
expected-to-succeed markers and, optionally, expected log message
directly next to BPF program source code, eliminating the need to
manually create and update table of tests.
We define few macros wrapping btf_decl_tag with a convention that all
values of btf_decl_tag start with "comment:" prefix, and then utilizing
a very simple "just_some_text_tag" or "some_key_name=<value>" pattern to
define things like expected success/failure, expected verifier message,
extra verifier log level (if necessary). This approach is demonstrated
by next patch in which two existing sets of failure tests are converted.
Tester supports both expected-to-fail and expected-to-succeed programs,
though this patch set didn't convert any existing expected-to-succeed
programs yet, as existing tests couple BPF program loading with their
further execution through attach or test_prog_run. One way to allow
testing scenarios like this would be ability to specify custom callback,
executed for each successfully loaded BPF program. This is left for
follow up patches, after some more analysis of existing test cases.
This test_loader is, hopefully, a start of a test_verifier-like runner,
but integrated into test_progs infrastructure. It will allow much better
"user experience" of defining low-level verification tests that can take
advantage of all the libbpf-provided nicety features on BPF side: global
variables, declarative maps, etc. All while having a choice of defining
it in C or as BPF assembly (through __attribute__((naked)) functions and
using embedded asm), depending on what makes most sense in each
particular case. This will be explored in follow up patches as well.
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20221207201648.2990661-1-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2022-12-07 12:16:47 -08:00
|
|
|
#define __msg(msg) __attribute__((btf_decl_tag("comment:test_expect_msg=" msg)))
|
|
|
|
#define __failure __attribute__((btf_decl_tag("comment:test_expect_failure")))
|
|
|
|
#define __success __attribute__((btf_decl_tag("comment:test_expect_success")))
|
2023-03-25 04:54:44 +02:00
|
|
|
#define __description(desc) __attribute__((btf_decl_tag("comment:test_description=" desc)))
|
|
|
|
#define __msg_unpriv(msg) __attribute__((btf_decl_tag("comment:test_expect_msg_unpriv=" msg)))
|
|
|
|
#define __failure_unpriv __attribute__((btf_decl_tag("comment:test_expect_failure_unpriv")))
|
|
|
|
#define __success_unpriv __attribute__((btf_decl_tag("comment:test_expect_success_unpriv")))
|
selftests/bpf: add generic BPF program tester-loader
It's become a common pattern to have a collection of small BPF programs
in one BPF object file, each representing one test case. On user-space
side of such tests we maintain a table of program names and expected
failure or success, along with optional expected verifier log message.
This works, but each set of tests reimplement this mundane code over and
over again, which is a waste of time for anyone trying to add a new set
of tests. Furthermore, it's quite error prone as it's way too easy to miss
some entries in these manually maintained test tables (as evidences by
dynptr_fail tests, in which ringbuf_release_uninit_dynptr subtest was
accidentally missed; this is fixed in next patch).
So this patch implements generic test_loader, which accepts skeleton
name and handles the rest of details: opens and loads BPF object file,
making sure each program is tested in isolation. Optionally each test
case can specify expected BPF verifier log message. In case of failure,
tester makes sure to report verifier log, but it also reports verifier
log in verbose mode unconditionally.
Now, the interesting deviation from existing custom implementations is
the use of btf_decl_tag attribute to specify expected-to-fail vs
expected-to-succeed markers and, optionally, expected log message
directly next to BPF program source code, eliminating the need to
manually create and update table of tests.
We define few macros wrapping btf_decl_tag with a convention that all
values of btf_decl_tag start with "comment:" prefix, and then utilizing
a very simple "just_some_text_tag" or "some_key_name=<value>" pattern to
define things like expected success/failure, expected verifier message,
extra verifier log level (if necessary). This approach is demonstrated
by next patch in which two existing sets of failure tests are converted.
Tester supports both expected-to-fail and expected-to-succeed programs,
though this patch set didn't convert any existing expected-to-succeed
programs yet, as existing tests couple BPF program loading with their
further execution through attach or test_prog_run. One way to allow
testing scenarios like this would be ability to specify custom callback,
executed for each successfully loaded BPF program. This is left for
follow up patches, after some more analysis of existing test cases.
This test_loader is, hopefully, a start of a test_verifier-like runner,
but integrated into test_progs infrastructure. It will allow much better
"user experience" of defining low-level verification tests that can take
advantage of all the libbpf-provided nicety features on BPF side: global
variables, declarative maps, etc. All while having a choice of defining
it in C or as BPF assembly (through __attribute__((naked)) functions and
using embedded asm), depending on what makes most sense in each
particular case. This will be explored in follow up patches as well.
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20221207201648.2990661-1-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2022-12-07 12:16:47 -08:00
|
|
|
#define __log_level(lvl) __attribute__((btf_decl_tag("comment:test_log_level="#lvl)))
|
2023-03-01 19:54:17 +02:00
|
|
|
#define __flag(flag) __attribute__((btf_decl_tag("comment:test_prog_flags="#flag)))
|
2023-03-25 04:54:45 +02:00
|
|
|
#define __retval(val) __attribute__((btf_decl_tag("comment:test_retval="#val)))
|
|
|
|
#define __retval_unpriv(val) __attribute__((btf_decl_tag("comment:test_retval_unpriv="#val)))
|
2023-04-21 20:42:11 +03:00
|
|
|
#define __auxiliary __attribute__((btf_decl_tag("comment:test_auxiliary")))
|
|
|
|
#define __auxiliary_unpriv __attribute__((btf_decl_tag("comment:test_auxiliary_unpriv")))
|
2023-12-11 13:20:08 -07:00
|
|
|
#define __btf_path(path) __attribute__((btf_decl_tag("comment:test_btf_path=" path)))
|
selftests/bpf: add generic BPF program tester-loader
It's become a common pattern to have a collection of small BPF programs
in one BPF object file, each representing one test case. On user-space
side of such tests we maintain a table of program names and expected
failure or success, along with optional expected verifier log message.
This works, but each set of tests reimplement this mundane code over and
over again, which is a waste of time for anyone trying to add a new set
of tests. Furthermore, it's quite error prone as it's way too easy to miss
some entries in these manually maintained test tables (as evidences by
dynptr_fail tests, in which ringbuf_release_uninit_dynptr subtest was
accidentally missed; this is fixed in next patch).
So this patch implements generic test_loader, which accepts skeleton
name and handles the rest of details: opens and loads BPF object file,
making sure each program is tested in isolation. Optionally each test
case can specify expected BPF verifier log message. In case of failure,
tester makes sure to report verifier log, but it also reports verifier
log in verbose mode unconditionally.
Now, the interesting deviation from existing custom implementations is
the use of btf_decl_tag attribute to specify expected-to-fail vs
expected-to-succeed markers and, optionally, expected log message
directly next to BPF program source code, eliminating the need to
manually create and update table of tests.
We define few macros wrapping btf_decl_tag with a convention that all
values of btf_decl_tag start with "comment:" prefix, and then utilizing
a very simple "just_some_text_tag" or "some_key_name=<value>" pattern to
define things like expected success/failure, expected verifier message,
extra verifier log level (if necessary). This approach is demonstrated
by next patch in which two existing sets of failure tests are converted.
Tester supports both expected-to-fail and expected-to-succeed programs,
though this patch set didn't convert any existing expected-to-succeed
programs yet, as existing tests couple BPF program loading with their
further execution through attach or test_prog_run. One way to allow
testing scenarios like this would be ability to specify custom callback,
executed for each successfully loaded BPF program. This is left for
follow up patches, after some more analysis of existing test cases.
This test_loader is, hopefully, a start of a test_verifier-like runner,
but integrated into test_progs infrastructure. It will allow much better
"user experience" of defining low-level verification tests that can take
advantage of all the libbpf-provided nicety features on BPF side: global
variables, declarative maps, etc. All while having a choice of defining
it in C or as BPF assembly (through __attribute__((naked)) functions and
using embedded asm), depending on what makes most sense in each
particular case. This will be explored in follow up patches as well.
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20221207201648.2990661-1-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2022-12-07 12:16:47 -08:00
|
|
|
|
2023-01-21 05:52:37 +05:30
|
|
|
/* Convenience macro for use with 'asm volatile' blocks */
|
|
|
|
#define __naked __attribute__((naked))
|
|
|
|
#define __clobber_all "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "memory"
|
|
|
|
#define __clobber_common "r0", "r1", "r2", "r3", "r4", "r5", "memory"
|
|
|
|
#define __imm(name) [name]"i"(name)
|
2023-03-25 04:54:43 +02:00
|
|
|
#define __imm_const(name, expr) [name]"i"(expr)
|
2023-01-21 05:52:37 +05:30
|
|
|
#define __imm_addr(name) [name]"i"(&name)
|
bpf: Use r constraint instead of p constraint in selftests
Some of the BPF selftests use the "p" constraint in inline assembly
snippets, for input operands for MOV (rN = rM) instructions.
This is mainly done via the __imm_ptr macro defined in
tools/testing/selftests/bpf/progs/bpf_misc.h:
#define __imm_ptr(name) [name]"p"(&name)
Example:
int consume_first_item_only(void *ctx)
{
struct bpf_iter_num iter;
asm volatile (
/* create iterator */
"r1 = %[iter];"
[...]
:
: __imm_ptr(iter)
: CLOBBERS);
[...]
}
The "p" constraint is a tricky one. It is documented in the GCC manual
section "Simple Constraints":
An operand that is a valid memory address is allowed. This is for
``load address'' and ``push address'' instructions.
p in the constraint must be accompanied by address_operand as the
predicate in the match_operand. This predicate interprets the mode
specified in the match_operand as the mode of the memory reference for
which the address would be valid.
There are two problems:
1. It is questionable whether that constraint was ever intended to be
used in inline assembly templates, because its behavior really
depends on compiler internals. A "memory address" is not the same
than a "memory operand" or a "memory reference" (constraint "m"), and
in fact its usage in the template above results in an error in both
x86_64-linux-gnu and bpf-unkonwn-none:
foo.c: In function ‘bar’:
foo.c:6:3: error: invalid 'asm': invalid expression as operand
6 | asm volatile ("r1 = %[jorl]" : : [jorl]"p"(&jorl));
| ^~~
I would assume the same happens with aarch64, riscv, and most/all
other targets in GCC, that do not accept operands of the form A + B
that are not wrapped either in a const or in a memory reference.
To avoid that error, the usage of the "p" constraint in internal GCC
instruction templates is supposed to be complemented by the 'a'
modifier, like in:
asm volatile ("r1 = %a[jorl]" : : [jorl]"p"(&jorl));
Internally documented (in GCC's final.cc) as:
%aN means expect operand N to be a memory address
(not a memory reference!) and print a reference
to that address.
That works because when the modifier 'a' is found, GCC prints an
"operand address", which is not the same than an "operand".
But...
2. Even if we used the internal 'a' modifier (we shouldn't) the 'rN =
rM' instruction really requires a register argument. In cases
involving automatics, like in the examples above, we easily end with:
bar:
#APP
r1 = r10-4
#NO_APP
In other cases we could conceibly also end with a 64-bit label that
may overflow the 32-bit immediate operand of `rN = imm32'
instructions:
r1 = foo
All of which is clearly wrong.
clang happens to do "the right thing" in the current usage of __imm_ptr
in the BPF tests, because even with -O2 it seems to "reload" the
fp-relative address of the automatic to a register like in:
bar:
r1 = r10
r1 += -4
#APP
r1 = r1
#NO_APP
Which is what GCC would generate with -O0. Whether this is by chance
or by design, the compiler shouln't be expected to do that reload
driven by the "p" constraint.
This patch changes the usage of the "p" constraint in the BPF
selftests macros to use the "r" constraint instead. If a register is
what is required, we should let the compiler know.
Previous discussion in bpf@vger:
https://lore.kernel.org/bpf/87h6p5ebpb.fsf@oracle.com/T/#ef0df83d6975c34dff20bf0dd52e078f5b8ca2767
Tested in bpf-next master.
No regressions.
Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
Cc: Yonghong Song <yonghong.song@linux.dev>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/r/20240123181309.19853-1-jose.marchesi@oracle.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2024-01-23 19:13:09 +01:00
|
|
|
#define __imm_ptr(name) [name]"r"(&name)
|
2023-03-25 04:54:43 +02:00
|
|
|
#define __imm_insn(name, expr) [name]"i"(*(long *)&(expr))
|
2023-01-21 05:52:37 +05:30
|
|
|
|
2023-03-25 04:54:45 +02:00
|
|
|
/* Magic constants used with __retval() */
|
|
|
|
#define POINTER_VALUE 0xcafe4all
|
|
|
|
#define TEST_DATA_LEN 64
|
|
|
|
|
2023-05-04 21:33:16 -07:00
|
|
|
#ifndef __used
|
|
|
|
#define __used __attribute__((used))
|
|
|
|
#endif
|
|
|
|
|
2022-01-24 23:16:20 +09:00
|
|
|
#if defined(__TARGET_ARCH_x86)
|
|
|
|
#define SYSCALL_WRAPPER 1
|
|
|
|
#define SYS_PREFIX "__x64_"
|
|
|
|
#elif defined(__TARGET_ARCH_s390)
|
|
|
|
#define SYSCALL_WRAPPER 1
|
|
|
|
#define SYS_PREFIX "__s390x_"
|
|
|
|
#elif defined(__TARGET_ARCH_arm64)
|
|
|
|
#define SYSCALL_WRAPPER 1
|
|
|
|
#define SYS_PREFIX "__arm64_"
|
2023-10-04 13:09:04 +02:00
|
|
|
#elif defined(__TARGET_ARCH_riscv)
|
|
|
|
#define SYSCALL_WRAPPER 1
|
|
|
|
#define SYS_PREFIX "__riscv_"
|
2022-01-24 23:16:20 +09:00
|
|
|
#else
|
|
|
|
#define SYSCALL_WRAPPER 0
|
2022-02-04 17:05:19 +05:30
|
|
|
#define SYS_PREFIX "__se_"
|
2022-01-24 23:16:20 +09:00
|
|
|
#endif
|
|
|
|
|
2023-01-20 12:09:00 -08:00
|
|
|
/* How many arguments are passed to function in register */
|
|
|
|
#if defined(__TARGET_ARCH_x86) || defined(__x86_64__)
|
|
|
|
#define FUNC_REG_ARG_CNT 6
|
|
|
|
#elif defined(__i386__)
|
|
|
|
#define FUNC_REG_ARG_CNT 3
|
|
|
|
#elif defined(__TARGET_ARCH_s390) || defined(__s390x__)
|
|
|
|
#define FUNC_REG_ARG_CNT 5
|
|
|
|
#elif defined(__TARGET_ARCH_arm) || defined(__arm__)
|
|
|
|
#define FUNC_REG_ARG_CNT 4
|
|
|
|
#elif defined(__TARGET_ARCH_arm64) || defined(__aarch64__)
|
|
|
|
#define FUNC_REG_ARG_CNT 8
|
|
|
|
#elif defined(__TARGET_ARCH_mips) || defined(__mips__)
|
|
|
|
#define FUNC_REG_ARG_CNT 8
|
|
|
|
#elif defined(__TARGET_ARCH_powerpc) || defined(__powerpc__) || defined(__powerpc64__)
|
|
|
|
#define FUNC_REG_ARG_CNT 8
|
|
|
|
#elif defined(__TARGET_ARCH_sparc) || defined(__sparc__)
|
|
|
|
#define FUNC_REG_ARG_CNT 6
|
|
|
|
#elif defined(__TARGET_ARCH_riscv) || defined(__riscv__)
|
|
|
|
#define FUNC_REG_ARG_CNT 8
|
|
|
|
#else
|
|
|
|
/* default to 5 for others */
|
|
|
|
#define FUNC_REG_ARG_CNT 5
|
|
|
|
#endif
|
|
|
|
|
2023-03-08 21:40:13 -08:00
|
|
|
/* make it look to compiler like value is read and written */
|
|
|
|
#define __sink(expr) asm volatile("" : "+g"(expr))
|
|
|
|
|
2022-01-24 23:16:20 +09:00
|
|
|
#endif
|