mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-21 04:53:46 -04:00
selftests/bpf: Add profiler test
The main purpose of the profiler test to check different llvm generation patterns to make sure the verifier can load these large programs. Note that profiler.inc.h test doesn't follow strict kernel coding style. The code was formatted in the kernel style, but variable declarations are kept as-is to preserve original llvm IR pattern. profiler1.c should pass with older and newer llvm profiler[23].c may fail on older llvm that don't have: https://reviews.llvm.org/D85570 because llvm may do speculative code motion optimization that will generate code like this: // r9 is a pointer to map_value // r7 is a scalar 17: bf 96 00 00 00 00 00 00 r6 = r9 18: 0f 76 00 00 00 00 00 00 r6 += r7 19: a5 07 01 00 01 01 00 00 if r7 < 257 goto +1 20: bf 96 00 00 00 00 00 00 r6 = r9 // r6 is used here The verifier will reject such code with the error: "math between map_value pointer and register with unbounded min value is not allowed" At insn 18 the r7 is indeed unbounded. The later insn 19 checks the bounds and the insn 20 undoes map_value addition. It is currently impossible for the verifier to understand such speculative pointer arithmetic. Hence llvm D85570 addresses it on the compiler side. Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/bpf/20201009011240.48506-4-alexei.starovoitov@gmail.com
This commit is contained in:
committed by
Daniel Borkmann
parent
5689d49b71
commit
03d4d13fab
@@ -7,6 +7,44 @@ General instructions on running selftests can be found in
|
||||
Additional information about selftest failures are
|
||||
documented here.
|
||||
|
||||
profiler[23] test failures with clang/llvm <12.0.0
|
||||
==================================================
|
||||
|
||||
With clang/llvm <12.0.0, the profiler[23] test may fail.
|
||||
The symptom looks like
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// r9 is a pointer to map_value
|
||||
// r7 is a scalar
|
||||
17: bf 96 00 00 00 00 00 00 r6 = r9
|
||||
18: 0f 76 00 00 00 00 00 00 r6 += r7
|
||||
math between map_value pointer and register with unbounded min value is not allowed
|
||||
|
||||
// the instructions below will not be seen in the verifier log
|
||||
19: a5 07 01 00 01 01 00 00 if r7 < 257 goto +1
|
||||
20: bf 96 00 00 00 00 00 00 r6 = r9
|
||||
// r6 is used here
|
||||
|
||||
The verifier will reject such code with above error.
|
||||
At insn 18 the r7 is indeed unbounded. The later insn 19 checks the bounds and
|
||||
the insn 20 undoes map_value addition. It is currently impossible for the
|
||||
verifier to understand such speculative pointer arithmetic.
|
||||
Hence
|
||||
https://reviews.llvm.org/D85570
|
||||
addresses it on the compiler side. It was committed on llvm 12.
|
||||
|
||||
The corresponding C code
|
||||
.. code-block:: c
|
||||
|
||||
for (int i = 0; i < MAX_CGROUPS_PATH_DEPTH; i++) {
|
||||
filepart_length = bpf_probe_read_str(payload, ...);
|
||||
if (filepart_length <= MAX_PATH) {
|
||||
barrier_var(filepart_length); // workaround
|
||||
payload += filepart_length;
|
||||
}
|
||||
}
|
||||
|
||||
bpf_iter test failures with clang/llvm 10.0.0
|
||||
=============================================
|
||||
|
||||
|
||||
Reference in New Issue
Block a user