diff options
author | Jakub Kicinski <kuba@kernel.org> | 2024-04-29 11:59:20 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2024-04-29 13:12:19 -0700 |
commit | 89de2db19317fb89a6e9163f33c3a7b23ee75a18 (patch) | |
tree | 6518d797d4c9a54979ace148307ba5c0c25335a5 /Documentation | |
parent | b3f1a08fcf0dd58d99b14b9f8fbd1929f188b746 (diff) | |
parent | 07801a24e2f18624cd2400ce15f14569eb416c9a (diff) |
Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says:
====================
pull-request: bpf-next 2024-04-29
We've added 147 non-merge commits during the last 32 day(s) which contain
a total of 158 files changed, 9400 insertions(+), 2213 deletions(-).
The main changes are:
1) Add an internal-only BPF per-CPU instruction for resolving per-CPU
memory addresses and implement support in x86 BPF JIT. This allows
inlining per-CPU array and hashmap lookups
and the bpf_get_smp_processor_id() helper, from Andrii Nakryiko.
2) Add BPF link support for sk_msg and sk_skb programs, from Yonghong Song.
3) Optimize x86 BPF JIT's emit_mov_imm64, and add support for various
atomics in bpf_arena which can be JITed as a single x86 instruction,
from Alexei Starovoitov.
4) Add support for passing mark with bpf_fib_lookup helper,
from Anton Protopopov.
5) Add a new bpf_wq API for deferring events and refactor sleepable
bpf_timer code to keep common code where possible,
from Benjamin Tissoires.
6) Fix BPF_PROG_TEST_RUN infra with regards to bpf_dummy_struct_ops programs
to check when NULL is passed for non-NULLable parameters,
from Eduard Zingerman.
7) Harden the BPF verifier's and/or/xor value tracking,
from Harishankar Vishwanathan.
8) Introduce crypto kfuncs to make BPF programs able to utilize the kernel
crypto subsystem, from Vadim Fedorenko.
9) Various improvements to the BPF instruction set standardization doc,
from Dave Thaler.
10) Extend libbpf APIs to partially consume items from the BPF ringbuffer,
from Andrea Righi.
11) Bigger batch of BPF selftests refactoring to use common network helpers
and to drop duplicate code, from Geliang Tang.
12) Support bpf_tail_call_static() helper for BPF programs with GCC 13,
from Jose E. Marchesi.
13) Add bpf_preempt_{disable,enable}() kfuncs in order to allow a BPF
program to have code sections where preemption is disabled,
from Kumar Kartikeya Dwivedi.
14) Allow invoking BPF kfuncs from BPF_PROG_TYPE_SYSCALL programs,
from David Vernet.
15) Extend the BPF verifier to allow different input maps for a given
bpf_for_each_map_elem() helper call in a BPF program, from Philo Lu.
16) Add support for PROBE_MEM32 and bpf_addr_space_cast instructions
for riscv64 and arm64 JITs to enable BPF Arena, from Puranjay Mohan.
17) Shut up a false-positive KMSAN splat in interpreter mode by unpoison
the stack memory, from Martin KaFai Lau.
18) Improve xsk selftest coverage with new tests on maximum and minimum
hardware ring size configurations, from Tushar Vyavahare.
19) Various ReST man pages fixes as well as documentation and bash completion
improvements for bpftool, from Rameez Rehman & Quentin Monnet.
20) Fix libbpf with regards to dumping subsequent char arrays,
from Quentin Deslandes.
* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (147 commits)
bpf, docs: Clarify PC use in instruction-set.rst
bpf_helpers.h: Define bpf_tail_call_static when building with GCC
bpf, docs: Add introduction for use in the ISA Internet Draft
selftests/bpf: extend BPF_SOCK_OPS_RTT_CB test for srtt and mrtt_us
bpf: add mrtt and srtt as BPF_SOCK_OPS_RTT_CB args
selftests/bpf: dummy_st_ops should reject 0 for non-nullable params
bpf: check bpf_dummy_struct_ops program params for test runs
selftests/bpf: do not pass NULL for non-nullable params in dummy_st_ops
selftests/bpf: adjust dummy_st_ops_success to detect additional error
bpf: mark bpf_dummy_struct_ops.test_1 parameter as nullable
selftests/bpf: Add ring_buffer__consume_n test.
bpf: Add bpf_guard_preempt() convenience macro
selftests: bpf: crypto: add benchmark for crypto functions
selftests: bpf: crypto skcipher algo selftests
bpf: crypto: add skcipher to bpf crypto
bpf: make common crypto API for TC/XDP programs
bpf: update the comment for BTF_FIELDS_MAX
selftests/bpf: Fix wq test.
selftests/bpf: Use make_sockaddr in test_sock_addr
selftests/bpf: Use connect_to_addr in test_sock_addr
...
====================
Link: https://lore.kernel.org/r/20240429131657.19423-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/bpf/standardization/instruction-set.rst | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/Documentation/bpf/standardization/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst index a5ab00ac0b14..997560abadab 100644 --- a/Documentation/bpf/standardization/instruction-set.rst +++ b/Documentation/bpf/standardization/instruction-set.rst @@ -5,7 +5,11 @@ BPF Instruction Set Architecture (ISA) ====================================== -This document specifies the BPF instruction set architecture (ISA). +eBPF (which is no longer an acronym for anything), also commonly +referred to as BPF, is a technology with origins in the Linux kernel +that can run untrusted programs in a privileged context such as an +operating system kernel. This document specifies the BPF instruction +set architecture (ISA). Documentation conventions ========================= @@ -43,7 +47,7 @@ a type's signedness (`S`) and bit width (`N`), respectively. ===== ========= For example, `u32` is a type whose valid values are all the 32-bit unsigned -numbers and `s16` is a types whose valid values are all the 16-bit signed +numbers and `s16` is a type whose valid values are all the 16-bit signed numbers. Functions @@ -108,7 +112,7 @@ conformance group means it must support all instructions in that conformance group. The use of named conformance groups enables interoperability between a runtime -that executes instructions, and tools as such compilers that generate +that executes instructions, and tools such as compilers that generate instructions for the runtime. Thus, capability discovery in terms of conformance groups might be done manually by users or automatically by tools. @@ -181,10 +185,13 @@ A basic instruction is encoded as follows:: (`64-bit immediate instructions`_ reuse this field for other purposes) **dst_reg** - destination register number (0-10) + destination register number (0-10), unless otherwise specified + (future instructions might reuse this field for other purposes) **offset** - signed integer offset used with pointer arithmetic + signed integer offset used with pointer arithmetic, except where + otherwise specified (some arithmetic instructions reuse this field + for other purposes) **imm** signed integer immediate value @@ -228,10 +235,12 @@ This is depicted in the following figure:: operation to perform, encoded as explained above **regs** - The source and destination register numbers, encoded as explained above + The source and destination register numbers (unless otherwise + specified), encoded as explained above **offset** - signed integer offset used with pointer arithmetic + signed integer offset used with pointer arithmetic, unless + otherwise specified **imm** signed integer immediate value @@ -342,8 +351,8 @@ where '(u32)' indicates that the upper 32 bits are zeroed. dst = dst ^ imm -Note that most instructions have instruction offset of 0. Only three instructions -(``SDIV``, ``SMOD``, ``MOVSX``) have a non-zero offset. +Note that most arithmetic instructions have 'offset' set to 0. Only three instructions +(``SDIV``, ``SMOD``, ``MOVSX``) have a non-zero 'offset'. Division, multiplication, and modulo operations for ``ALU`` are part of the "divmul32" conformance group, and division, multiplication, and @@ -365,15 +374,15 @@ Note that there are varying definitions of the signed modulo operation when the dividend or divisor are negative, where implementations often vary by language such that Python, Ruby, etc. differ from C, Go, Java, etc. This specification requires that signed modulo use truncated division -(where -13 % 3 == -1) as implemented in C, Go, etc.: +(where -13 % 3 == -1) as implemented in C, Go, etc.:: a % n = a - n * trunc(a / n) The ``MOVSX`` instruction does a move operation with sign extension. -``{MOVSX, X, ALU}`` :term:`sign extends<Sign Extend>` 8-bit and 16-bit operands into 32 -bit operands, and zeroes the remaining upper 32 bits. +``{MOVSX, X, ALU}`` :term:`sign extends<Sign Extend>` 8-bit and 16-bit operands into +32-bit operands, and zeroes the remaining upper 32 bits. ``{MOVSX, X, ALU64}`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit -operands into 64 bit operands. Unlike other arithmetic instructions, +operands into 64-bit operands. Unlike other arithmetic instructions, ``MOVSX`` is only defined for register source operands (``X``). The ``NEG`` instruction is only defined when the source bit is clear @@ -411,19 +420,19 @@ conformance group. Examples: -``{END, TO_LE, ALU}`` with imm = 16/32/64 means:: +``{END, TO_LE, ALU}`` with 'imm' = 16/32/64 means:: dst = htole16(dst) dst = htole32(dst) dst = htole64(dst) -``{END, TO_BE, ALU}`` with imm = 16/32/64 means:: +``{END, TO_BE, ALU}`` with 'imm' = 16/32/64 means:: dst = htobe16(dst) dst = htobe32(dst) dst = htobe64(dst) -``{END, TO_LE, ALU64}`` with imm = 16/32/64 means:: +``{END, TO_LE, ALU64}`` with 'imm' = 16/32/64 means:: dst = bswap16(dst) dst = bswap32(dst) @@ -438,27 +447,33 @@ otherwise identical operations, and indicates the base64 conformance group unless otherwise specified. The 'code' field encodes the operation as below: -======== ===== ======= =============================== =================================================== -code value src_reg description notes -======== ===== ======= =============================== =================================================== -JA 0x0 0x0 PC += offset {JA, K, JMP} only -JA 0x0 0x0 PC += imm {JA, K, JMP32} only +======== ===== ======= ================================= =================================================== +code value src_reg description notes +======== ===== ======= ================================= =================================================== +JA 0x0 0x0 PC += offset {JA, K, JMP} only +JA 0x0 0x0 PC += imm {JA, K, JMP32} only JEQ 0x1 any PC += offset if dst == src -JGT 0x2 any PC += offset if dst > src unsigned -JGE 0x3 any PC += offset if dst >= src unsigned +JGT 0x2 any PC += offset if dst > src unsigned +JGE 0x3 any PC += offset if dst >= src unsigned JSET 0x4 any PC += offset if dst & src JNE 0x5 any PC += offset if dst != src -JSGT 0x6 any PC += offset if dst > src signed -JSGE 0x7 any PC += offset if dst >= src signed -CALL 0x8 0x0 call helper function by address {CALL, K, JMP} only, see `Helper functions`_ -CALL 0x8 0x1 call PC += imm {CALL, K, JMP} only, see `Program-local functions`_ -CALL 0x8 0x2 call helper function by BTF ID {CALL, K, JMP} only, see `Helper functions`_ -EXIT 0x9 0x0 return {CALL, K, JMP} only -JLT 0xa any PC += offset if dst < src unsigned -JLE 0xb any PC += offset if dst <= src unsigned -JSLT 0xc any PC += offset if dst < src signed -JSLE 0xd any PC += offset if dst <= src signed -======== ===== ======= =============================== =================================================== +JSGT 0x6 any PC += offset if dst > src signed +JSGE 0x7 any PC += offset if dst >= src signed +CALL 0x8 0x0 call helper function by static ID {CALL, K, JMP} only, see `Helper functions`_ +CALL 0x8 0x1 call PC += imm {CALL, K, JMP} only, see `Program-local functions`_ +CALL 0x8 0x2 call helper function by BTF ID {CALL, K, JMP} only, see `Helper functions`_ +EXIT 0x9 0x0 return {CALL, K, JMP} only +JLT 0xa any PC += offset if dst < src unsigned +JLE 0xb any PC += offset if dst <= src unsigned +JSLT 0xc any PC += offset if dst < src signed +JSLE 0xd any PC += offset if dst <= src signed +======== ===== ======= ================================= =================================================== + +where 'PC' denotes the program counter, and the offset to increment by +is in units of 64-bit instructions relative to the instruction following +the jump instruction. Thus 'PC += 1' skips execution of the next +instruction if it's a basic instruction or results in undefined behavior +if the next instruction is a 128-bit wide instruction. The BPF program needs to store the return value into register R0 before doing an ``EXIT``. @@ -475,7 +490,7 @@ where 's>=' indicates a signed '>=' comparison. gotol +imm -where 'imm' means the branch offset comes from insn 'imm' field. +where 'imm' means the branch offset comes from the 'imm' field. Note that there are two flavors of ``JA`` instructions. The ``JMP`` class permits a 16-bit jump offset specified by the 'offset' @@ -493,26 +508,26 @@ Helper functions Helper functions are a concept whereby BPF programs can call into a set of function calls exposed by the underlying platform. -Historically, each helper function was identified by an address -encoded in the imm field. The available helper functions may differ -for each program type, but address values are unique across all program types. +Historically, each helper function was identified by a static ID +encoded in the 'imm' field. The available helper functions may differ +for each program type, but static IDs are unique across all program types. Platforms that support the BPF Type Format (BTF) support identifying -a helper function by a BTF ID encoded in the imm field, where the BTF ID +a helper function by a BTF ID encoded in the 'imm' field, where the BTF ID identifies the helper name and type. Program-local functions ~~~~~~~~~~~~~~~~~~~~~~~ Program-local functions are functions exposed by the same BPF program as the caller, and are referenced by offset from the call instruction, similar to -``JA``. The offset is encoded in the imm field of the call instruction. -A ``EXIT`` within the program-local function will return to the caller. +``JA``. The offset is encoded in the 'imm' field of the call instruction. +An ``EXIT`` within the program-local function will return to the caller. Load and store instructions =========================== For load and store instructions (``LD``, ``LDX``, ``ST``, and ``STX``), the -8-bit 'opcode' field is divided as:: +8-bit 'opcode' field is divided as follows:: +-+-+-+-+-+-+-+-+ |mode |sz |class| @@ -580,7 +595,7 @@ instructions that transfer data between a register and memory. dst = *(signed size *) (src + offset) -Where size is one of: ``B``, ``H``, or ``W``, and +Where '<size>' is one of: ``B``, ``H``, or ``W``, and 'signed size' is one of: s8, s16, or s32. Atomic operations @@ -662,11 +677,11 @@ src_reg pseudocode imm type dst type ======= ========================================= =========== ============== 0x0 dst = (next_imm << 32) | imm integer integer 0x1 dst = map_by_fd(imm) map fd map -0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer -0x3 dst = var_addr(imm) variable id data pointer -0x4 dst = code_addr(imm) integer code pointer +0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data address +0x3 dst = var_addr(imm) variable id data address +0x4 dst = code_addr(imm) integer code address 0x5 dst = map_by_idx(imm) map index map -0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer +0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data address ======= ========================================= =========== ============== where |