summaryrefslogtreecommitdiff
path: root/Documentation/bpf
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/bpf')
-rw-r--r--Documentation/bpf/bpf_design_QA.rst5
-rw-r--r--Documentation/bpf/bpf_devel_QA.rst10
-rw-r--r--Documentation/bpf/btf.rst4
-rw-r--r--Documentation/bpf/index.rst3
-rw-r--r--Documentation/bpf/llvm_reloc.rst6
-rw-r--r--Documentation/bpf/standardization/index.rst18
-rw-r--r--Documentation/bpf/standardization/instruction-set.rst (renamed from Documentation/bpf/instruction-set.rst)227
-rw-r--r--Documentation/bpf/standardization/linux-notes.rst (renamed from Documentation/bpf/linux-notes.rst)3
8 files changed, 216 insertions, 60 deletions
diff --git a/Documentation/bpf/bpf_design_QA.rst b/Documentation/bpf/bpf_design_QA.rst
index 38372a956d65..eb19c945f4d5 100644
--- a/Documentation/bpf/bpf_design_QA.rst
+++ b/Documentation/bpf/bpf_design_QA.rst
@@ -140,11 +140,6 @@ A: Because if we picked one-to-one relationship to x64 it would have made
it more complicated to support on arm64 and other archs. Also it
needs div-by-zero runtime check.
-Q: Why there is no BPF_SDIV for signed divide operation?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A: Because it would be rarely used. llvm errors in such case and
-prints a suggestion to use unsigned divide instead.
-
Q: Why BPF has implicit prologue and epilogue?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A: Because architectures like sparc have register windows and in general
diff --git a/Documentation/bpf/bpf_devel_QA.rst b/Documentation/bpf/bpf_devel_QA.rst
index 609b71f5747d..de27e1620821 100644
--- a/Documentation/bpf/bpf_devel_QA.rst
+++ b/Documentation/bpf/bpf_devel_QA.rst
@@ -635,12 +635,12 @@ test coverage.
Q: clang flag for target bpf?
-----------------------------
-Q: In some cases clang flag ``-target bpf`` is used but in other cases the
+Q: In some cases clang flag ``--target=bpf`` is used but in other cases the
default clang target, which matches the underlying architecture, is used.
What is the difference and when I should use which?
A: Although LLVM IR generation and optimization try to stay architecture
-independent, ``-target <arch>`` still has some impact on generated code:
+independent, ``--target=<arch>`` still has some impact on generated code:
- BPF program may recursively include header file(s) with file scope
inline assembly codes. The default target can handle this well,
@@ -658,7 +658,7 @@ independent, ``-target <arch>`` still has some impact on generated code:
The clang option ``-fno-jump-tables`` can be used to disable
switch table generation.
-- For clang ``-target bpf``, it is guaranteed that pointer or long /
+- For clang ``--target=bpf``, it is guaranteed that pointer or long /
unsigned long types will always have a width of 64 bit, no matter
whether underlying clang binary or default target (or kernel) is
32 bit. However, when native clang target is used, then it will
@@ -668,7 +668,7 @@ independent, ``-target <arch>`` still has some impact on generated code:
while the BPF LLVM back end still operates in 64 bit. The native
target is mostly needed in tracing for the case of walking ``pt_regs``
or other kernel structures where CPU's register width matters.
- Otherwise, ``clang -target bpf`` is generally recommended.
+ Otherwise, ``clang --target=bpf`` is generally recommended.
You should use default target when:
@@ -685,7 +685,7 @@ when:
into these structures is verified by the BPF verifier and may result
in verification failures if the native architecture is not aligned with
the BPF architecture, e.g. 64-bit. An example of this is
- BPF_PROG_TYPE_SK_MSG require ``-target bpf``
+ BPF_PROG_TYPE_SK_MSG require ``--target=bpf``
.. Links
diff --git a/Documentation/bpf/btf.rst b/Documentation/bpf/btf.rst
index 7cd7c5415a99..f32db1f44ae9 100644
--- a/Documentation/bpf/btf.rst
+++ b/Documentation/bpf/btf.rst
@@ -990,7 +990,7 @@ format.::
} g2;
int main() { return 0; }
int test() { return 0; }
- -bash-4.4$ clang -c -g -O2 -target bpf t2.c
+ -bash-4.4$ clang -c -g -O2 --target=bpf t2.c
-bash-4.4$ readelf -S t2.o
......
[ 8] .BTF PROGBITS 0000000000000000 00000247
@@ -1000,7 +1000,7 @@ format.::
[10] .rel.BTF.ext REL 0000000000000000 000007e0
0000000000000040 0000000000000010 16 9 8
......
- -bash-4.4$ clang -S -g -O2 -target bpf t2.c
+ -bash-4.4$ clang -S -g -O2 --target=bpf t2.c
-bash-4.4$ cat t2.s
......
.section .BTF,"",@progbits
diff --git a/Documentation/bpf/index.rst b/Documentation/bpf/index.rst
index dbb39e8f9889..1ff177b89d66 100644
--- a/Documentation/bpf/index.rst
+++ b/Documentation/bpf/index.rst
@@ -12,9 +12,9 @@ that goes into great technical depth about the BPF Architecture.
.. toctree::
:maxdepth: 1
- instruction-set
verifier
libbpf/index
+ standardization/index
btf
faq
syscall_api
@@ -29,7 +29,6 @@ that goes into great technical depth about the BPF Architecture.
bpf_licensing
test_debug
clang-notes
- linux-notes
other
redirect
diff --git a/Documentation/bpf/llvm_reloc.rst b/Documentation/bpf/llvm_reloc.rst
index e4a777a6a3a2..450e6403fe3d 100644
--- a/Documentation/bpf/llvm_reloc.rst
+++ b/Documentation/bpf/llvm_reloc.rst
@@ -28,7 +28,7 @@ For example, for the following code::
return g1 + g2 + l1 + l2;
}
-Compiled with ``clang -target bpf -O2 -c test.c``, the following is
+Compiled with ``clang --target=bpf -O2 -c test.c``, the following is
the code with ``llvm-objdump -dr test.o``::
0: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
@@ -157,7 +157,7 @@ and ``call`` instructions. For example::
return gfunc(a, b) + lfunc(a, b) + global;
}
-Compiled with ``clang -target bpf -O2 -c test.c``, we will have
+Compiled with ``clang --target=bpf -O2 -c test.c``, we will have
following code with `llvm-objdump -dr test.o``::
Disassembly of section .text:
@@ -203,7 +203,7 @@ The following is an example to show how R_BPF_64_ABS64 could be generated::
int global() { return 0; }
struct t { void *g; } gbl = { global };
-Compiled with ``clang -target bpf -O2 -g -c test.c``, we will see a
+Compiled with ``clang --target=bpf -O2 -g -c test.c``, we will see a
relocation below in ``.data`` section with command
``llvm-readelf -r test.o``::
diff --git a/Documentation/bpf/standardization/index.rst b/Documentation/bpf/standardization/index.rst
new file mode 100644
index 000000000000..09c6ba055fd7
--- /dev/null
+++ b/Documentation/bpf/standardization/index.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+
+===================
+BPF Standardization
+===================
+
+This directory contains documents that are being iterated on as part of the BPF
+standardization effort with the IETF. See the `IETF BPF Working Group`_ page
+for the working group charter, documents, and more.
+
+.. toctree::
+ :maxdepth: 1
+
+ instruction-set
+ linux-notes
+
+.. Links:
+.. _IETF BPF Working Group: https://datatracker.ietf.org/wg/bpf/about/
diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst
index 6644842cd3ea..4f73e9dc8d9e 100644
--- a/Documentation/bpf/instruction-set.rst
+++ b/Documentation/bpf/standardization/instruction-set.rst
@@ -10,9 +10,92 @@ This document specifies version 1.0 of the eBPF instruction set.
Documentation conventions
=========================
-For brevity, this document uses the type notion "u64", "u32", etc.
-to mean an unsigned integer whose width is the specified number of bits,
-and "s32", etc. to mean a signed integer of the specified number of bits.
+For brevity and consistency, this document refers to families
+of types using a shorthand syntax and refers to several expository,
+mnemonic functions when describing the semantics of instructions.
+The range of valid values for those types and the semantics of those
+functions are defined in the following subsections.
+
+Types
+-----
+This document refers to integer types with the notation `SN` to specify
+a type's signedness (`S`) and bit width (`N`), respectively.
+
+.. table:: Meaning of signedness notation.
+
+ ==== =========
+ `S` Meaning
+ ==== =========
+ `u` unsigned
+ `s` signed
+ ==== =========
+
+.. table:: Meaning of bit-width notation.
+
+ ===== =========
+ `N` Bit width
+ ===== =========
+ `8` 8 bits
+ `16` 16 bits
+ `32` 32 bits
+ `64` 64 bits
+ `128` 128 bits
+ ===== =========
+
+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.
+
+Functions
+---------
+* `htobe16`: Takes an unsigned 16-bit number in host-endian format and
+ returns the equivalent number as an unsigned 16-bit number in big-endian
+ format.
+* `htobe32`: Takes an unsigned 32-bit number in host-endian format and
+ returns the equivalent number as an unsigned 32-bit number in big-endian
+ format.
+* `htobe64`: Takes an unsigned 64-bit number in host-endian format and
+ returns the equivalent number as an unsigned 64-bit number in big-endian
+ format.
+* `htole16`: Takes an unsigned 16-bit number in host-endian format and
+ returns the equivalent number as an unsigned 16-bit number in little-endian
+ format.
+* `htole32`: Takes an unsigned 32-bit number in host-endian format and
+ returns the equivalent number as an unsigned 32-bit number in little-endian
+ format.
+* `htole64`: Takes an unsigned 64-bit number in host-endian format and
+ returns the equivalent number as an unsigned 64-bit number in little-endian
+ format.
+* `bswap16`: Takes an unsigned 16-bit number in either big- or little-endian
+ format and returns the equivalent number with the same bit width but
+ opposite endianness.
+* `bswap32`: Takes an unsigned 32-bit number in either big- or little-endian
+ format and returns the equivalent number with the same bit width but
+ opposite endianness.
+* `bswap64`: Takes an unsigned 64-bit number in either big- or little-endian
+ format and returns the equivalent number with the same bit width but
+ opposite endianness.
+
+
+Definitions
+-----------
+
+.. glossary::
+
+ Sign Extend
+ To `sign extend an` ``X`` `-bit number, A, to a` ``Y`` `-bit number, B ,` means to
+
+ #. Copy all ``X`` bits from `A` to the lower ``X`` bits of `B`.
+ #. Set the value of the remaining ``Y`` - ``X`` bits of `B` to the value of
+ the most-significant bit of `A`.
+
+.. admonition:: Example
+
+ Sign extend an 8-bit number ``A`` to a 16-bit number ``B`` on a big-endian platform:
+ ::
+
+ A: 10000110
+ B: 11111111 10000110
Registers and calling convention
================================
@@ -154,24 +237,27 @@ otherwise identical operations.
The 'code' field encodes the operation as below, where 'src' and 'dst' refer
to the values of the source and destination registers, respectively.
-======== ===== ==========================================================
-code value description
-======== ===== ==========================================================
-BPF_ADD 0x00 dst += src
-BPF_SUB 0x10 dst -= src
-BPF_MUL 0x20 dst \*= src
-BPF_DIV 0x30 dst = (src != 0) ? (dst / src) : 0
-BPF_OR 0x40 dst \|= src
-BPF_AND 0x50 dst &= src
-BPF_LSH 0x60 dst <<= (src & mask)
-BPF_RSH 0x70 dst >>= (src & mask)
-BPF_NEG 0x80 dst = ~src
-BPF_MOD 0x90 dst = (src != 0) ? (dst % src) : dst
-BPF_XOR 0xa0 dst ^= src
-BPF_MOV 0xb0 dst = src
-BPF_ARSH 0xc0 sign extending dst >>= (src & mask)
-BPF_END 0xd0 byte swap operations (see `Byte swap instructions`_ below)
-======== ===== ==========================================================
+========= ===== ======= ==========================================================
+code value offset description
+========= ===== ======= ==========================================================
+BPF_ADD 0x00 0 dst += src
+BPF_SUB 0x10 0 dst -= src
+BPF_MUL 0x20 0 dst \*= src
+BPF_DIV 0x30 0 dst = (src != 0) ? (dst / src) : 0
+BPF_SDIV 0x30 1 dst = (src != 0) ? (dst s/ src) : 0
+BPF_OR 0x40 0 dst \|= src
+BPF_AND 0x50 0 dst &= src
+BPF_LSH 0x60 0 dst <<= (src & mask)
+BPF_RSH 0x70 0 dst >>= (src & mask)
+BPF_NEG 0x80 0 dst = -dst
+BPF_MOD 0x90 0 dst = (src != 0) ? (dst % src) : dst
+BPF_SMOD 0x90 1 dst = (src != 0) ? (dst s% src) : dst
+BPF_XOR 0xa0 0 dst ^= src
+BPF_MOV 0xb0 0 dst = src
+BPF_MOVSX 0xb0 8/16/32 dst = (s8,s16,s32)src
+BPF_ARSH 0xc0 0 :term:`sign extending<Sign Extend>` dst >>= (src & mask)
+BPF_END 0xd0 0 byte swap operations (see `Byte swap instructions`_ below)
+========= ===== ======= ==========================================================
Underflow and overflow are allowed during arithmetic operations, meaning
the 64-bit or 32-bit value will wrap. If eBPF program execution would
@@ -198,47 +284,75 @@ where '(u32)' indicates that the upper 32 bits are zeroed.
dst = dst ^ imm32
-Also note that the division and modulo operations are unsigned. Thus, for
-``BPF_ALU``, 'imm' is first interpreted as an unsigned 32-bit value, whereas
-for ``BPF_ALU64``, 'imm' is first sign extended to 64 bits and the result
-interpreted as an unsigned 64-bit value. There are no instructions for
-signed division or modulo.
+Note that most instructions have instruction offset of 0. Only three instructions
+(``BPF_SDIV``, ``BPF_SMOD``, ``BPF_MOVSX``) have a non-zero offset.
+
+The division and modulo operations support both unsigned and signed flavors.
+
+For unsigned operations (``BPF_DIV`` and ``BPF_MOD``), for ``BPF_ALU``,
+'imm' is interpreted as a 32-bit unsigned value. For ``BPF_ALU64``,
+'imm' is first :term:`sign extended<Sign Extend>` from 32 to 64 bits, and then
+interpreted as a 64-bit unsigned value.
+
+For signed operations (``BPF_SDIV`` and ``BPF_SMOD``), for ``BPF_ALU``,
+'imm' is interpreted as a 32-bit signed value. For ``BPF_ALU64``, 'imm'
+is first :term:`sign extended<Sign Extend>` from 32 to 64 bits, and then
+interpreted as a 64-bit signed value.
+
+The ``BPF_MOVSX`` instruction does a move operation with sign extension.
+``BPF_ALU | BPF_MOVSX`` :term:`sign extends<Sign Extend>` 8-bit and 16-bit operands into 32
+bit operands, and zeroes the remaining upper 32 bits.
+``BPF_ALU64 | BPF_MOVSX`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit
+operands into 64 bit operands.
Shift operations use a mask of 0x3F (63) for 64-bit operations and 0x1F (31)
for 32-bit operations.
Byte swap instructions
-~~~~~~~~~~~~~~~~~~~~~~
+----------------------
-The byte swap instructions use an instruction class of ``BPF_ALU`` and a 4-bit
-'code' field of ``BPF_END``.
+The byte swap instructions use instruction classes of ``BPF_ALU`` and ``BPF_ALU64``
+and a 4-bit 'code' field of ``BPF_END``.
The byte swap instructions operate on the destination register
only and do not use a separate source register or immediate value.
-The 1-bit source operand field in the opcode is used to select what byte
-order the operation convert from or to:
+For ``BPF_ALU``, the 1-bit source operand field in the opcode is used to
+select what byte order the operation converts from or to. For
+``BPF_ALU64``, the 1-bit source operand field in the opcode is reserved
+and must be set to 0.
-========= ===== =================================================
-source value description
-========= ===== =================================================
-BPF_TO_LE 0x00 convert between host byte order and little endian
-BPF_TO_BE 0x08 convert between host byte order and big endian
-========= ===== =================================================
+========= ========= ===== =================================================
+class source value description
+========= ========= ===== =================================================
+BPF_ALU BPF_TO_LE 0x00 convert between host byte order and little endian
+BPF_ALU BPF_TO_BE 0x08 convert between host byte order and big endian
+BPF_ALU64 Reserved 0x00 do byte swap unconditionally
+========= ========= ===== =================================================
The 'imm' field encodes the width of the swap operations. The following widths
are supported: 16, 32 and 64.
Examples:
-``BPF_ALU | BPF_TO_LE | BPF_END`` with imm = 16 means::
+``BPF_ALU | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
dst = htole16(dst)
+ dst = htole32(dst)
+ dst = htole64(dst)
-``BPF_ALU | BPF_TO_BE | BPF_END`` with imm = 64 means::
+``BPF_ALU | BPF_TO_BE | BPF_END`` with imm = 16/32/64 means::
+ dst = htobe16(dst)
+ dst = htobe32(dst)
dst = htobe64(dst)
+``BPF_ALU64 | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
+
+ dst = bswap16(dst)
+ dst = bswap32(dst)
+ dst = bswap64(dst)
+
Jump instructions
-----------------
@@ -249,7 +363,8 @@ The 'code' field encodes the operation as below:
======== ===== === =========================================== =========================================
code value src description notes
======== ===== === =========================================== =========================================
-BPF_JA 0x0 0x0 PC += offset BPF_JMP only
+BPF_JA 0x0 0x0 PC += offset BPF_JMP class
+BPF_JA 0x0 0x0 PC += imm BPF_JMP32 class
BPF_JEQ 0x1 any PC += offset if dst == src
BPF_JGT 0x2 any PC += offset if dst > src unsigned
BPF_JGE 0x3 any PC += offset if dst >= src unsigned
@@ -278,6 +393,19 @@ Example:
where 's>=' indicates a signed '>=' comparison.
+``BPF_JA | BPF_K | BPF_JMP32`` (0x06) means::
+
+ gotol +imm
+
+where 'imm' means the branch offset comes from insn 'imm' field.
+
+Note that there are two flavors of ``BPF_JA`` instructions. The
+``BPF_JMP`` class permits a 16-bit jump offset specified by the 'offset'
+field, whereas the ``BPF_JMP32`` class permits a 32-bit jump offset
+specified by the 'imm' field. A > 16-bit conditional jump may be
+converted to a < 16-bit conditional jump plus a 32-bit unconditional
+jump.
+
Helper functions
~~~~~~~~~~~~~~~~
@@ -320,6 +448,7 @@ The mode modifier is one of:
BPF_ABS 0x20 legacy BPF packet access (absolute) `Legacy BPF Packet access instructions`_
BPF_IND 0x40 legacy BPF packet access (indirect) `Legacy BPF Packet access instructions`_
BPF_MEM 0x60 regular load and store operations `Regular load and store operations`_
+ BPF_MEMSX 0x80 sign-extension load operations `Sign-extension load operations`_
BPF_ATOMIC 0xc0 atomic operations `Atomic operations`_
============= ===== ==================================== =============
@@ -350,9 +479,23 @@ instructions that transfer data between a register and memory.
``BPF_MEM | <size> | BPF_LDX`` means::
- dst = *(size *) (src + offset)
+ dst = *(unsigned size *) (src + offset)
+
+Where size is one of: ``BPF_B``, ``BPF_H``, ``BPF_W``, or ``BPF_DW`` and
+'unsigned size' is one of u8, u16, u32 or u64.
+
+Sign-extension load operations
+------------------------------
+
+The ``BPF_MEMSX`` mode modifier is used to encode :term:`sign-extension<Sign Extend>` load
+instructions that transfer data between a register and memory.
+
+``BPF_MEMSX | <size> | BPF_LDX`` means::
+
+ dst = *(signed size *) (src + offset)
-Where size is one of: ``BPF_B``, ``BPF_H``, ``BPF_W``, or ``BPF_DW``.
+Where size is one of: ``BPF_B``, ``BPF_H`` or ``BPF_W``, and
+'signed size' is one of s8, s16 or s32.
Atomic operations
-----------------
diff --git a/Documentation/bpf/linux-notes.rst b/Documentation/bpf/standardization/linux-notes.rst
index 508d009d3bed..00d2693de025 100644
--- a/Documentation/bpf/linux-notes.rst
+++ b/Documentation/bpf/standardization/linux-notes.rst
@@ -45,7 +45,8 @@ On Linux, this integer is a BTF ID.
Legacy BPF Packet access instructions
=====================================
-As mentioned in the `ISA standard documentation <instruction-set.rst#legacy-bpf-packet-access-instructions>`_,
+As mentioned in the `ISA standard documentation
+<instruction-set.html#legacy-bpf-packet-access-instructions>`_,
Linux has special eBPF instructions for access to packet data that have been
carried over from classic BPF to retain the performance of legacy socket
filters running in the eBPF interpreter.