commit | 8328f373c0ef27fda14f12e67f1d6ed882dd2e81 | [log] [tgz] |
---|---|---|
author | Alexei Starovoitov <[email protected]> | Tue Mar 05 19:19:26 2024 -0800 |
committer | Quentin Monnet <[email protected]> | Thu Mar 07 10:12:34 2024 +0000 |
tree | 601cff7dad659a9df0ecda743e37fccece416cd8 | |
parent | 579d6b0e7e74109e8f24315f5f750ed098caecb3 [diff] |
bpf: Introduce may_goto instruction Introduce may_goto instruction that from the verifier pov is similar to open coded iterators bpf_for()/bpf_repeat() and bpf_loop() helper, but it doesn't iterate any objects. In assembly 'may_goto' is a nop most of the time until bpf runtime has to terminate the program for whatever reason. In the current implementation may_goto has a hidden counter, but other mechanisms can be used. For programs written in C the later patch introduces 'cond_break' macro that combines 'may_goto' with 'break' statement and has similar semantics: cond_break is a nop until bpf runtime has to break out of this loop. It can be used in any normal "for" or "while" loop, like for (i = zero; i < cnt; cond_break, i++) { The verifier recognizes that may_goto is used in the program, reserves additional 8 bytes of stack, initializes them in subprog prologue, and replaces may_goto instruction with: aux_reg = *(u64 *)(fp - 40) if aux_reg == 0 goto pc+off aux_reg -= 1 *(u64 *)(fp - 40) = aux_reg may_goto instruction can be used by LLVM to implement __builtin_memcpy, __builtin_strcmp. may_goto is not a full substitute for bpf_for() macro. bpf_for() doesn't have induction variable that verifiers sees, so 'i' in bpf_for(i, 0, 100) is seen as imprecise and bounded. But when the code is written as: for (i = 0; i < 100; cond_break, i++) the verifier see 'i' as precise constant zero, hence cond_break (aka may_goto) doesn't help to converge the loop. A static or global variable can be used as a workaround: static int zero = 0; for (i = zero; i < 100; cond_break, i++) // works! may_goto works well with arena pointers that don't need to be bounds checked on access. Load/store from arena returns imprecise unbounded scalar and loops with may_goto pass the verifier. Reserve new opcode BPF_JMP | BPF_JCOND for may_goto insn. JCOND stands for conditional pseudo jump. Since goto_or_nop insn was proposed, it may use the same opcode. may_goto vs goto_or_nop can be distinguished by src_reg: code = BPF_JMP | BPF_JCOND src_reg = 0 - may_goto src_reg = 1 - goto_or_nop Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Acked-by: Eduard Zingerman <[email protected]> Acked-by: John Fastabend <[email protected]> Tested-by: John Fastabend <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
This is the official home for bpftool. Please use this Github repository for building and packaging bpftool and when using it in your projects through Git submodule.
The authoritative source code of bpftool is developed as part of the bpf-next Linux source tree under the tools/bpf/bpftool
subdirectory and is periodically synced to https://github.com/libbpf/bpftool on Github. As such, all changes for bpftool should be sent to the BPF mailing list, please don't open PRs here unless you are changing some Github-specific components.
Check out the manual pages for documentation about bpftool. A number of example invocations are also displayed in this blog post.
All general BPF questions, including kernel functionality, bpftool features and usage, should be sent to [email protected] mailing list. You can subscribe to it here and search its archives here.
The mailing list is monitored by many more people than this repo and they will happily try to help you with whatever issue you encounter. This repository's PRs and issues should be opened only for dealing with issues related to components specific to the bpftool mirror repository (such as the synchronization script or the CI workflows). The project maintainers also use GitHub issues as a generic tracker for bpftool, but issues should first be reported on the mailing list nonetheless.
Required:
Optional:
This repository uses libbpf as a submodule. You can initialize it when cloning bpftool:
$ git clone --recurse-submodules https://github.com/libbpf/bpftool.git
Alternatively, if you have already cloned the repository, you can initialize the submodule by running the following command from within the repository:
$ git submodule update --init
To build bpftool:
$ cd src
$ make
To build and install bpftool on the system:
$ cd src # make install
Building bpftool in a separate directory is supported via the OUTPUT
variable:
$ mkdir /tmp/bpftool $ cd src $ OUTPUT=/tmp/bpftool make
Most of the output is suppressed by default, but detailed building logs can be displayed by passing V=1
:
$ cd src $ make V=1
Additional compilation flags can be passed to the command line if required. For example, we can create a static build with the following commands:
$ cd src $ EXTRA_CFLAGS=--static make
Note that to use the LLVM disassembler with static builds, we need a static version of the LLVM library installed on the system:
Download a precompiled LLVM release or build it locally.
Download the appropriate release of LLVM for your platform, for example on x86_64 with LLVM 15.0.0:
$ curl -LO https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.0/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4.tar.xz $ tar xvf clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4.tar.xz $ mv clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4 llvm_build
Alternatively, clone and build the LLVM libraries locally.
$ git clone https://github.com/llvm/llvm-project.git $ mkdir llvm_build $ cmake -S llvm-project/llvm -B llvm_build -DCMAKE_BUILD_TYPE=Release $ make -j -C llvm_build llvm-config llvm-libraries
Build bpftool with EXTRA_CFLAGS
set to --static
, and by passing the path to the relevant llvm-config
.
$ cd bpftool $ LLVM_CONFIG=../../llvm_build/bin/llvm-config EXTRA_CFLAGS=--static make -j -C src
The man pages for bpftool can be built with:
$ cd docs
$ make
They can be installed on the system with:
$ cd docs # make install
This repository mirrors bpf-next Linux source tree's tools/bpf/bpftool
directory, plus its few dependencies from under kernel/bpf/
, and its supporting header files. Some of these header files, include/linux/*.h
on the current repository, are reduced versions of their counterpart files at bpf-next's tools/include/linux/*.h
to make compilation successful.
Synchronization between the two repositories happens every few weeks or so. Given that bpftool remains aligned on libbpf‘s version, its repository tends to follow libbpf’s. When the libbpf repo syncs up with bpf-next, bpftool's repo usually follows within the next few days.
The synchronization process is semi-automated: the script in scripts/sync-kernel.sh
cherry-picks, adjusts and commits all changes from bpf-next
to a local version of the bpftool repository. However, maintainers run this script manually and then create a pull request to merge the resulting commits.
Take a look at the script for the technical details of the process. See also the documentation in the accompanying README.md
This work is dual-licensed under the GNU GPL v2.0 (only) license and the BSD 2-clause license. You can select either of them if you reuse this work.
SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)