162306a36Sopenharmony_ci.. contents::
262306a36Sopenharmony_ci.. sectnum::
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci=======================================
562306a36Sopenharmony_ciBPF Instruction Set Specification, v1.0
662306a36Sopenharmony_ci=======================================
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciThis document specifies version 1.0 of the BPF instruction set.
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciDocumentation conventions
1162306a36Sopenharmony_ci=========================
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciFor brevity and consistency, this document refers to families
1462306a36Sopenharmony_ciof types using a shorthand syntax and refers to several expository,
1562306a36Sopenharmony_cimnemonic functions when describing the semantics of instructions.
1662306a36Sopenharmony_ciThe range of valid values for those types and the semantics of those
1762306a36Sopenharmony_cifunctions are defined in the following subsections.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciTypes
2062306a36Sopenharmony_ci-----
2162306a36Sopenharmony_ciThis document refers to integer types with the notation `SN` to specify
2262306a36Sopenharmony_cia type's signedness (`S`) and bit width (`N`), respectively.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci.. table:: Meaning of signedness notation.
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci  ==== =========
2762306a36Sopenharmony_ci  `S`  Meaning
2862306a36Sopenharmony_ci  ==== =========
2962306a36Sopenharmony_ci  `u`  unsigned
3062306a36Sopenharmony_ci  `s`  signed
3162306a36Sopenharmony_ci  ==== =========
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci.. table:: Meaning of bit-width notation.
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci  ===== =========
3662306a36Sopenharmony_ci  `N`   Bit width
3762306a36Sopenharmony_ci  ===== =========
3862306a36Sopenharmony_ci  `8`   8 bits
3962306a36Sopenharmony_ci  `16`  16 bits
4062306a36Sopenharmony_ci  `32`  32 bits
4162306a36Sopenharmony_ci  `64`  64 bits
4262306a36Sopenharmony_ci  `128` 128 bits
4362306a36Sopenharmony_ci  ===== =========
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ciFor example, `u32` is a type whose valid values are all the 32-bit unsigned
4662306a36Sopenharmony_cinumbers and `s16` is a types whose valid values are all the 16-bit signed
4762306a36Sopenharmony_cinumbers.
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciFunctions
5062306a36Sopenharmony_ci---------
5162306a36Sopenharmony_ci* `htobe16`: Takes an unsigned 16-bit number in host-endian format and
5262306a36Sopenharmony_ci  returns the equivalent number as an unsigned 16-bit number in big-endian
5362306a36Sopenharmony_ci  format.
5462306a36Sopenharmony_ci* `htobe32`: Takes an unsigned 32-bit number in host-endian format and
5562306a36Sopenharmony_ci  returns the equivalent number as an unsigned 32-bit number in big-endian
5662306a36Sopenharmony_ci  format.
5762306a36Sopenharmony_ci* `htobe64`: Takes an unsigned 64-bit number in host-endian format and
5862306a36Sopenharmony_ci  returns the equivalent number as an unsigned 64-bit number in big-endian
5962306a36Sopenharmony_ci  format.
6062306a36Sopenharmony_ci* `htole16`: Takes an unsigned 16-bit number in host-endian format and
6162306a36Sopenharmony_ci  returns the equivalent number as an unsigned 16-bit number in little-endian
6262306a36Sopenharmony_ci  format.
6362306a36Sopenharmony_ci* `htole32`: Takes an unsigned 32-bit number in host-endian format and
6462306a36Sopenharmony_ci  returns the equivalent number as an unsigned 32-bit number in little-endian
6562306a36Sopenharmony_ci  format.
6662306a36Sopenharmony_ci* `htole64`: Takes an unsigned 64-bit number in host-endian format and
6762306a36Sopenharmony_ci  returns the equivalent number as an unsigned 64-bit number in little-endian
6862306a36Sopenharmony_ci  format.
6962306a36Sopenharmony_ci* `bswap16`: Takes an unsigned 16-bit number in either big- or little-endian
7062306a36Sopenharmony_ci  format and returns the equivalent number with the same bit width but
7162306a36Sopenharmony_ci  opposite endianness.
7262306a36Sopenharmony_ci* `bswap32`: Takes an unsigned 32-bit number in either big- or little-endian
7362306a36Sopenharmony_ci  format and returns the equivalent number with the same bit width but
7462306a36Sopenharmony_ci  opposite endianness.
7562306a36Sopenharmony_ci* `bswap64`: Takes an unsigned 64-bit number in either big- or little-endian
7662306a36Sopenharmony_ci  format and returns the equivalent number with the same bit width but
7762306a36Sopenharmony_ci  opposite endianness.
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciDefinitions
8162306a36Sopenharmony_ci-----------
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci.. glossary::
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci  Sign Extend
8662306a36Sopenharmony_ci    To `sign extend an` ``X`` `-bit number, A, to a` ``Y`` `-bit number, B  ,` means to
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci    #. Copy all ``X`` bits from `A` to the lower ``X`` bits of `B`.
8962306a36Sopenharmony_ci    #. Set the value of the remaining ``Y`` - ``X`` bits of `B` to the value of
9062306a36Sopenharmony_ci       the  most-significant bit of `A`.
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci.. admonition:: Example
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci  Sign extend an 8-bit number ``A`` to a 16-bit number ``B`` on a big-endian platform:
9562306a36Sopenharmony_ci  ::
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci    A:          10000110
9862306a36Sopenharmony_ci    B: 11111111 10000110
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ciInstruction encoding
10162306a36Sopenharmony_ci====================
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciBPF has two instruction encodings:
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci* the basic instruction encoding, which uses 64 bits to encode an instruction
10662306a36Sopenharmony_ci* the wide instruction encoding, which appends a second 64-bit immediate (i.e.,
10762306a36Sopenharmony_ci  constant) value after the basic instruction for a total of 128 bits.
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciThe fields conforming an encoded basic instruction are stored in the
11062306a36Sopenharmony_cifollowing order::
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci  opcode:8 src_reg:4 dst_reg:4 offset:16 imm:32 // In little-endian BPF.
11362306a36Sopenharmony_ci  opcode:8 dst_reg:4 src_reg:4 offset:16 imm:32 // In big-endian BPF.
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci**imm**
11662306a36Sopenharmony_ci  signed integer immediate value
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci**offset**
11962306a36Sopenharmony_ci  signed integer offset used with pointer arithmetic
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci**src_reg**
12262306a36Sopenharmony_ci  the source register number (0-10), except where otherwise specified
12362306a36Sopenharmony_ci  (`64-bit immediate instructions`_ reuse this field for other purposes)
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci**dst_reg**
12662306a36Sopenharmony_ci  destination register number (0-10)
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci**opcode**
12962306a36Sopenharmony_ci  operation to perform
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ciNote that the contents of multi-byte fields ('imm' and 'offset') are
13262306a36Sopenharmony_cistored using big-endian byte ordering in big-endian BPF and
13362306a36Sopenharmony_cilittle-endian byte ordering in little-endian BPF.
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ciFor example::
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci  opcode                  offset imm          assembly
13862306a36Sopenharmony_ci         src_reg dst_reg
13962306a36Sopenharmony_ci  07     0       1        00 00  44 33 22 11  r1 += 0x11223344 // little
14062306a36Sopenharmony_ci         dst_reg src_reg
14162306a36Sopenharmony_ci  07     1       0        00 00  11 22 33 44  r1 += 0x11223344 // big
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ciNote that most instructions do not use all of the fields.
14462306a36Sopenharmony_ciUnused fields shall be cleared to zero.
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ciAs discussed below in `64-bit immediate instructions`_, a 64-bit immediate
14762306a36Sopenharmony_ciinstruction uses a 64-bit immediate value that is constructed as follows.
14862306a36Sopenharmony_ciThe 64 bits following the basic instruction contain a pseudo instruction
14962306a36Sopenharmony_ciusing the same format but with opcode, dst_reg, src_reg, and offset all set to zero,
15062306a36Sopenharmony_ciand imm containing the high 32 bits of the immediate value.
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciThis is depicted in the following figure::
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci        basic_instruction
15562306a36Sopenharmony_ci  .-----------------------------.
15662306a36Sopenharmony_ci  |                             |
15762306a36Sopenharmony_ci  code:8 regs:8 offset:16 imm:32 unused:32 imm:32
15862306a36Sopenharmony_ci                                 |              |
15962306a36Sopenharmony_ci                                 '--------------'
16062306a36Sopenharmony_ci                                pseudo instruction
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ciThus the 64-bit immediate value is constructed as follows:
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci  imm64 = (next_imm << 32) | imm
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ciwhere 'next_imm' refers to the imm value of the pseudo instruction
16762306a36Sopenharmony_cifollowing the basic instruction.  The unused bytes in the pseudo
16862306a36Sopenharmony_ciinstruction are reserved and shall be cleared to zero.
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ciInstruction classes
17162306a36Sopenharmony_ci-------------------
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ciThe three LSB bits of the 'opcode' field store the instruction class:
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci=========  =====  ===============================  ===================================
17662306a36Sopenharmony_ciclass      value  description                      reference
17762306a36Sopenharmony_ci=========  =====  ===============================  ===================================
17862306a36Sopenharmony_ciBPF_LD     0x00   non-standard load operations     `Load and store instructions`_
17962306a36Sopenharmony_ciBPF_LDX    0x01   load into register operations    `Load and store instructions`_
18062306a36Sopenharmony_ciBPF_ST     0x02   store from immediate operations  `Load and store instructions`_
18162306a36Sopenharmony_ciBPF_STX    0x03   store from register operations   `Load and store instructions`_
18262306a36Sopenharmony_ciBPF_ALU    0x04   32-bit arithmetic operations     `Arithmetic and jump instructions`_
18362306a36Sopenharmony_ciBPF_JMP    0x05   64-bit jump operations           `Arithmetic and jump instructions`_
18462306a36Sopenharmony_ciBPF_JMP32  0x06   32-bit jump operations           `Arithmetic and jump instructions`_
18562306a36Sopenharmony_ciBPF_ALU64  0x07   64-bit arithmetic operations     `Arithmetic and jump instructions`_
18662306a36Sopenharmony_ci=========  =====  ===============================  ===================================
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ciArithmetic and jump instructions
18962306a36Sopenharmony_ci================================
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ciFor arithmetic and jump instructions (``BPF_ALU``, ``BPF_ALU64``, ``BPF_JMP`` and
19262306a36Sopenharmony_ci``BPF_JMP32``), the 8-bit 'opcode' field is divided into three parts:
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci==============  ======  =================
19562306a36Sopenharmony_ci4 bits (MSB)    1 bit   3 bits (LSB)
19662306a36Sopenharmony_ci==============  ======  =================
19762306a36Sopenharmony_cicode            source  instruction class
19862306a36Sopenharmony_ci==============  ======  =================
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci**code**
20162306a36Sopenharmony_ci  the operation code, whose meaning varies by instruction class
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci**source**
20462306a36Sopenharmony_ci  the source operand location, which unless otherwise specified is one of:
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci  ======  =====  ==============================================
20762306a36Sopenharmony_ci  source  value  description
20862306a36Sopenharmony_ci  ======  =====  ==============================================
20962306a36Sopenharmony_ci  BPF_K   0x00   use 32-bit 'imm' value as source operand
21062306a36Sopenharmony_ci  BPF_X   0x08   use 'src_reg' register value as source operand
21162306a36Sopenharmony_ci  ======  =====  ==============================================
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci**instruction class**
21462306a36Sopenharmony_ci  the instruction class (see `Instruction classes`_)
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciArithmetic instructions
21762306a36Sopenharmony_ci-----------------------
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci``BPF_ALU`` uses 32-bit wide operands while ``BPF_ALU64`` uses 64-bit wide operands for
22062306a36Sopenharmony_ciotherwise identical operations.
22162306a36Sopenharmony_ciThe 'code' field encodes the operation as below, where 'src' and 'dst' refer
22262306a36Sopenharmony_cito the values of the source and destination registers, respectively.
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci=========  =====  =======  ==========================================================
22562306a36Sopenharmony_cicode       value  offset   description
22662306a36Sopenharmony_ci=========  =====  =======  ==========================================================
22762306a36Sopenharmony_ciBPF_ADD    0x00   0        dst += src
22862306a36Sopenharmony_ciBPF_SUB    0x10   0        dst -= src
22962306a36Sopenharmony_ciBPF_MUL    0x20   0        dst \*= src
23062306a36Sopenharmony_ciBPF_DIV    0x30   0        dst = (src != 0) ? (dst / src) : 0
23162306a36Sopenharmony_ciBPF_SDIV   0x30   1        dst = (src != 0) ? (dst s/ src) : 0
23262306a36Sopenharmony_ciBPF_OR     0x40   0        dst \|= src
23362306a36Sopenharmony_ciBPF_AND    0x50   0        dst &= src
23462306a36Sopenharmony_ciBPF_LSH    0x60   0        dst <<= (src & mask)
23562306a36Sopenharmony_ciBPF_RSH    0x70   0        dst >>= (src & mask)
23662306a36Sopenharmony_ciBPF_NEG    0x80   0        dst = -dst
23762306a36Sopenharmony_ciBPF_MOD    0x90   0        dst = (src != 0) ? (dst % src) : dst
23862306a36Sopenharmony_ciBPF_SMOD   0x90   1        dst = (src != 0) ? (dst s% src) : dst
23962306a36Sopenharmony_ciBPF_XOR    0xa0   0        dst ^= src
24062306a36Sopenharmony_ciBPF_MOV    0xb0   0        dst = src
24162306a36Sopenharmony_ciBPF_MOVSX  0xb0   8/16/32  dst = (s8,s16,s32)src
24262306a36Sopenharmony_ciBPF_ARSH   0xc0   0        :term:`sign extending<Sign Extend>` dst >>= (src & mask)
24362306a36Sopenharmony_ciBPF_END    0xd0   0        byte swap operations (see `Byte swap instructions`_ below)
24462306a36Sopenharmony_ci=========  =====  =======  ==========================================================
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ciUnderflow and overflow are allowed during arithmetic operations, meaning
24762306a36Sopenharmony_cithe 64-bit or 32-bit value will wrap. If BPF program execution would
24862306a36Sopenharmony_ciresult in division by zero, the destination register is instead set to zero.
24962306a36Sopenharmony_ciIf execution would result in modulo by zero, for ``BPF_ALU64`` the value of
25062306a36Sopenharmony_cithe destination register is unchanged whereas for ``BPF_ALU`` the upper
25162306a36Sopenharmony_ci32 bits of the destination register are zeroed.
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci``BPF_ADD | BPF_X | BPF_ALU`` means::
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci  dst = (u32) ((u32) dst + (u32) src)
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ciwhere '(u32)' indicates that the upper 32 bits are zeroed.
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci``BPF_ADD | BPF_X | BPF_ALU64`` means::
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci  dst = dst + src
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci``BPF_XOR | BPF_K | BPF_ALU`` means::
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci  dst = (u32) dst ^ (u32) imm32
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci``BPF_XOR | BPF_K | BPF_ALU64`` means::
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci  dst = dst ^ imm32
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ciNote that most instructions have instruction offset of 0. Only three instructions
27262306a36Sopenharmony_ci(``BPF_SDIV``, ``BPF_SMOD``, ``BPF_MOVSX``) have a non-zero offset.
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ciThe division and modulo operations support both unsigned and signed flavors.
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ciFor unsigned operations (``BPF_DIV`` and ``BPF_MOD``), for ``BPF_ALU``,
27762306a36Sopenharmony_ci'imm' is interpreted as a 32-bit unsigned value. For ``BPF_ALU64``,
27862306a36Sopenharmony_ci'imm' is first :term:`sign extended<Sign Extend>` from 32 to 64 bits, and then
27962306a36Sopenharmony_ciinterpreted as a 64-bit unsigned value.
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ciFor signed operations (``BPF_SDIV`` and ``BPF_SMOD``), for ``BPF_ALU``,
28262306a36Sopenharmony_ci'imm' is interpreted as a 32-bit signed value. For ``BPF_ALU64``, 'imm'
28362306a36Sopenharmony_ciis first :term:`sign extended<Sign Extend>` from 32 to 64 bits, and then
28462306a36Sopenharmony_ciinterpreted as a 64-bit signed value.
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ciThe ``BPF_MOVSX`` instruction does a move operation with sign extension.
28762306a36Sopenharmony_ci``BPF_ALU | BPF_MOVSX`` :term:`sign extends<Sign Extend>` 8-bit and 16-bit operands into 32
28862306a36Sopenharmony_cibit operands, and zeroes the remaining upper 32 bits.
28962306a36Sopenharmony_ci``BPF_ALU64 | BPF_MOVSX`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit
29062306a36Sopenharmony_cioperands into 64 bit operands.
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ciShift operations use a mask of 0x3F (63) for 64-bit operations and 0x1F (31)
29362306a36Sopenharmony_cifor 32-bit operations.
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ciByte swap instructions
29662306a36Sopenharmony_ci----------------------
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ciThe byte swap instructions use instruction classes of ``BPF_ALU`` and ``BPF_ALU64``
29962306a36Sopenharmony_ciand a 4-bit 'code' field of ``BPF_END``.
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ciThe byte swap instructions operate on the destination register
30262306a36Sopenharmony_cionly and do not use a separate source register or immediate value.
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ciFor ``BPF_ALU``, the 1-bit source operand field in the opcode is used to
30562306a36Sopenharmony_ciselect what byte order the operation converts from or to. For
30662306a36Sopenharmony_ci``BPF_ALU64``, the 1-bit source operand field in the opcode is reserved
30762306a36Sopenharmony_ciand must be set to 0.
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci=========  =========  =====  =================================================
31062306a36Sopenharmony_ciclass      source     value  description
31162306a36Sopenharmony_ci=========  =========  =====  =================================================
31262306a36Sopenharmony_ciBPF_ALU    BPF_TO_LE  0x00   convert between host byte order and little endian
31362306a36Sopenharmony_ciBPF_ALU    BPF_TO_BE  0x08   convert between host byte order and big endian
31462306a36Sopenharmony_ciBPF_ALU64  Reserved   0x00   do byte swap unconditionally
31562306a36Sopenharmony_ci=========  =========  =====  =================================================
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ciThe 'imm' field encodes the width of the swap operations.  The following widths
31862306a36Sopenharmony_ciare supported: 16, 32 and 64.
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ciExamples:
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci``BPF_ALU | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci  dst = htole16(dst)
32562306a36Sopenharmony_ci  dst = htole32(dst)
32662306a36Sopenharmony_ci  dst = htole64(dst)
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci``BPF_ALU | BPF_TO_BE | BPF_END`` with imm = 16/32/64 means::
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci  dst = htobe16(dst)
33162306a36Sopenharmony_ci  dst = htobe32(dst)
33262306a36Sopenharmony_ci  dst = htobe64(dst)
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci``BPF_ALU64 | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci  dst = bswap16(dst)
33762306a36Sopenharmony_ci  dst = bswap32(dst)
33862306a36Sopenharmony_ci  dst = bswap64(dst)
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ciJump instructions
34162306a36Sopenharmony_ci-----------------
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci``BPF_JMP32`` uses 32-bit wide operands while ``BPF_JMP`` uses 64-bit wide operands for
34462306a36Sopenharmony_ciotherwise identical operations.
34562306a36Sopenharmony_ciThe 'code' field encodes the operation as below:
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci========  =====  ===  ===========================================  =========================================
34862306a36Sopenharmony_cicode      value  src  description                                  notes
34962306a36Sopenharmony_ci========  =====  ===  ===========================================  =========================================
35062306a36Sopenharmony_ciBPF_JA    0x0    0x0  PC += offset                                 BPF_JMP class
35162306a36Sopenharmony_ciBPF_JA    0x0    0x0  PC += imm                                    BPF_JMP32 class
35262306a36Sopenharmony_ciBPF_JEQ   0x1    any  PC += offset if dst == src
35362306a36Sopenharmony_ciBPF_JGT   0x2    any  PC += offset if dst > src                    unsigned
35462306a36Sopenharmony_ciBPF_JGE   0x3    any  PC += offset if dst >= src                   unsigned
35562306a36Sopenharmony_ciBPF_JSET  0x4    any  PC += offset if dst & src
35662306a36Sopenharmony_ciBPF_JNE   0x5    any  PC += offset if dst != src
35762306a36Sopenharmony_ciBPF_JSGT  0x6    any  PC += offset if dst > src                    signed
35862306a36Sopenharmony_ciBPF_JSGE  0x7    any  PC += offset if dst >= src                   signed
35962306a36Sopenharmony_ciBPF_CALL  0x8    0x0  call helper function by address              see `Helper functions`_
36062306a36Sopenharmony_ciBPF_CALL  0x8    0x1  call PC += imm                               see `Program-local functions`_
36162306a36Sopenharmony_ciBPF_CALL  0x8    0x2  call helper function by BTF ID               see `Helper functions`_
36262306a36Sopenharmony_ciBPF_EXIT  0x9    0x0  return                                       BPF_JMP only
36362306a36Sopenharmony_ciBPF_JLT   0xa    any  PC += offset if dst < src                    unsigned
36462306a36Sopenharmony_ciBPF_JLE   0xb    any  PC += offset if dst <= src                   unsigned
36562306a36Sopenharmony_ciBPF_JSLT  0xc    any  PC += offset if dst < src                    signed
36662306a36Sopenharmony_ciBPF_JSLE  0xd    any  PC += offset if dst <= src                   signed
36762306a36Sopenharmony_ci========  =====  ===  ===========================================  =========================================
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ciThe BPF program needs to store the return value into register R0 before doing a
37062306a36Sopenharmony_ci``BPF_EXIT``.
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ciExample:
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci``BPF_JSGE | BPF_X | BPF_JMP32`` (0x7e) means::
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci  if (s32)dst s>= (s32)src goto +offset
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ciwhere 's>=' indicates a signed '>=' comparison.
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci``BPF_JA | BPF_K | BPF_JMP32`` (0x06) means::
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci  gotol +imm
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ciwhere 'imm' means the branch offset comes from insn 'imm' field.
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ciNote that there are two flavors of ``BPF_JA`` instructions. The
38762306a36Sopenharmony_ci``BPF_JMP`` class permits a 16-bit jump offset specified by the 'offset'
38862306a36Sopenharmony_cifield, whereas the ``BPF_JMP32`` class permits a 32-bit jump offset
38962306a36Sopenharmony_cispecified by the 'imm' field. A > 16-bit conditional jump may be
39062306a36Sopenharmony_ciconverted to a < 16-bit conditional jump plus a 32-bit unconditional
39162306a36Sopenharmony_cijump.
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ciHelper functions
39462306a36Sopenharmony_ci~~~~~~~~~~~~~~~~
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ciHelper functions are a concept whereby BPF programs can call into a
39762306a36Sopenharmony_ciset of function calls exposed by the underlying platform.
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ciHistorically, each helper function was identified by an address
40062306a36Sopenharmony_ciencoded in the imm field.  The available helper functions may differ
40162306a36Sopenharmony_cifor each program type, but address values are unique across all program types.
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ciPlatforms that support the BPF Type Format (BTF) support identifying
40462306a36Sopenharmony_cia helper function by a BTF ID encoded in the imm field, where the BTF ID
40562306a36Sopenharmony_ciidentifies the helper name and type.
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ciProgram-local functions
40862306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~
40962306a36Sopenharmony_ciProgram-local functions are functions exposed by the same BPF program as the
41062306a36Sopenharmony_cicaller, and are referenced by offset from the call instruction, similar to
41162306a36Sopenharmony_ci``BPF_JA``.  The offset is encoded in the imm field of the call instruction.
41262306a36Sopenharmony_ciA ``BPF_EXIT`` within the program-local function will return to the caller.
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ciLoad and store instructions
41562306a36Sopenharmony_ci===========================
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ciFor load and store instructions (``BPF_LD``, ``BPF_LDX``, ``BPF_ST``, and ``BPF_STX``), the
41862306a36Sopenharmony_ci8-bit 'opcode' field is divided as:
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci============  ======  =================
42162306a36Sopenharmony_ci3 bits (MSB)  2 bits  3 bits (LSB)
42262306a36Sopenharmony_ci============  ======  =================
42362306a36Sopenharmony_cimode          size    instruction class
42462306a36Sopenharmony_ci============  ======  =================
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ciThe mode modifier is one of:
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci  =============  =====  ====================================  =============
42962306a36Sopenharmony_ci  mode modifier  value  description                           reference
43062306a36Sopenharmony_ci  =============  =====  ====================================  =============
43162306a36Sopenharmony_ci  BPF_IMM        0x00   64-bit immediate instructions         `64-bit immediate instructions`_
43262306a36Sopenharmony_ci  BPF_ABS        0x20   legacy BPF packet access (absolute)   `Legacy BPF Packet access instructions`_
43362306a36Sopenharmony_ci  BPF_IND        0x40   legacy BPF packet access (indirect)   `Legacy BPF Packet access instructions`_
43462306a36Sopenharmony_ci  BPF_MEM        0x60   regular load and store operations     `Regular load and store operations`_
43562306a36Sopenharmony_ci  BPF_MEMSX      0x80   sign-extension load operations        `Sign-extension load operations`_
43662306a36Sopenharmony_ci  BPF_ATOMIC     0xc0   atomic operations                     `Atomic operations`_
43762306a36Sopenharmony_ci  =============  =====  ====================================  =============
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ciThe size modifier is one of:
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci  =============  =====  =====================
44262306a36Sopenharmony_ci  size modifier  value  description
44362306a36Sopenharmony_ci  =============  =====  =====================
44462306a36Sopenharmony_ci  BPF_W          0x00   word        (4 bytes)
44562306a36Sopenharmony_ci  BPF_H          0x08   half word   (2 bytes)
44662306a36Sopenharmony_ci  BPF_B          0x10   byte
44762306a36Sopenharmony_ci  BPF_DW         0x18   double word (8 bytes)
44862306a36Sopenharmony_ci  =============  =====  =====================
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ciRegular load and store operations
45162306a36Sopenharmony_ci---------------------------------
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ciThe ``BPF_MEM`` mode modifier is used to encode regular load and store
45462306a36Sopenharmony_ciinstructions that transfer data between a register and memory.
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci``BPF_MEM | <size> | BPF_STX`` means::
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci  *(size *) (dst + offset) = src
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_ci``BPF_MEM | <size> | BPF_ST`` means::
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci  *(size *) (dst + offset) = imm32
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci``BPF_MEM | <size> | BPF_LDX`` means::
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci  dst = *(unsigned size *) (src + offset)
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ciWhere size is one of: ``BPF_B``, ``BPF_H``, ``BPF_W``, or ``BPF_DW`` and
46962306a36Sopenharmony_ci'unsigned size' is one of u8, u16, u32 or u64.
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ciSign-extension load operations
47262306a36Sopenharmony_ci------------------------------
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ciThe ``BPF_MEMSX`` mode modifier is used to encode :term:`sign-extension<Sign Extend>` load
47562306a36Sopenharmony_ciinstructions that transfer data between a register and memory.
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci``BPF_MEMSX | <size> | BPF_LDX`` means::
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci  dst = *(signed size *) (src + offset)
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ciWhere size is one of: ``BPF_B``, ``BPF_H`` or ``BPF_W``, and
48262306a36Sopenharmony_ci'signed size' is one of s8, s16 or s32.
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ciAtomic operations
48562306a36Sopenharmony_ci-----------------
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ciAtomic operations are operations that operate on memory and can not be
48862306a36Sopenharmony_ciinterrupted or corrupted by other access to the same memory region
48962306a36Sopenharmony_ciby other BPF programs or means outside of this specification.
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ciAll atomic operations supported by BPF are encoded as store operations
49262306a36Sopenharmony_cithat use the ``BPF_ATOMIC`` mode modifier as follows:
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci* ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations
49562306a36Sopenharmony_ci* ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations
49662306a36Sopenharmony_ci* 8-bit and 16-bit wide atomic operations are not supported.
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ciThe 'imm' field is used to encode the actual atomic operation.
49962306a36Sopenharmony_ciSimple atomic operation use a subset of the values defined to encode
50062306a36Sopenharmony_ciarithmetic operations in the 'imm' field to encode the atomic operation:
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci========  =====  ===========
50362306a36Sopenharmony_ciimm       value  description
50462306a36Sopenharmony_ci========  =====  ===========
50562306a36Sopenharmony_ciBPF_ADD   0x00   atomic add
50662306a36Sopenharmony_ciBPF_OR    0x40   atomic or
50762306a36Sopenharmony_ciBPF_AND   0x50   atomic and
50862306a36Sopenharmony_ciBPF_XOR   0xa0   atomic xor
50962306a36Sopenharmony_ci========  =====  ===========
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci``BPF_ATOMIC | BPF_W  | BPF_STX`` with 'imm' = BPF_ADD means::
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci  *(u32 *)(dst + offset) += src
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci``BPF_ATOMIC | BPF_DW | BPF_STX`` with 'imm' = BPF ADD means::
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci  *(u64 *)(dst + offset) += src
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ciIn addition to the simple atomic operations, there also is a modifier and
52162306a36Sopenharmony_citwo complex atomic operations:
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci===========  ================  ===========================
52462306a36Sopenharmony_ciimm          value             description
52562306a36Sopenharmony_ci===========  ================  ===========================
52662306a36Sopenharmony_ciBPF_FETCH    0x01              modifier: return old value
52762306a36Sopenharmony_ciBPF_XCHG     0xe0 | BPF_FETCH  atomic exchange
52862306a36Sopenharmony_ciBPF_CMPXCHG  0xf0 | BPF_FETCH  atomic compare and exchange
52962306a36Sopenharmony_ci===========  ================  ===========================
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ciThe ``BPF_FETCH`` modifier is optional for simple atomic operations, and
53262306a36Sopenharmony_cialways set for the complex atomic operations.  If the ``BPF_FETCH`` flag
53362306a36Sopenharmony_ciis set, then the operation also overwrites ``src`` with the value that
53462306a36Sopenharmony_ciwas in memory before it was modified.
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ciThe ``BPF_XCHG`` operation atomically exchanges ``src`` with the value
53762306a36Sopenharmony_ciaddressed by ``dst + offset``.
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ciThe ``BPF_CMPXCHG`` operation atomically compares the value addressed by
54062306a36Sopenharmony_ci``dst + offset`` with ``R0``. If they match, the value addressed by
54162306a36Sopenharmony_ci``dst + offset`` is replaced with ``src``. In either case, the
54262306a36Sopenharmony_civalue that was at ``dst + offset`` before the operation is zero-extended
54362306a36Sopenharmony_ciand loaded back to ``R0``.
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci64-bit immediate instructions
54662306a36Sopenharmony_ci-----------------------------
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ciInstructions with the ``BPF_IMM`` 'mode' modifier use the wide instruction
54962306a36Sopenharmony_ciencoding defined in `Instruction encoding`_, and use the 'src' field of the
55062306a36Sopenharmony_cibasic instruction to hold an opcode subtype.
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ciThe following table defines a set of ``BPF_IMM | BPF_DW | BPF_LD`` instructions
55362306a36Sopenharmony_ciwith opcode subtypes in the 'src' field, using new terms such as "map"
55462306a36Sopenharmony_cidefined further below:
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci=========================  ======  ===  =========================================  ===========  ==============
55762306a36Sopenharmony_ciopcode construction        opcode  src  pseudocode                                 imm type     dst type
55862306a36Sopenharmony_ci=========================  ======  ===  =========================================  ===========  ==============
55962306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x0  dst = imm64                                integer      integer
56062306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x1  dst = map_by_fd(imm)                       map fd       map
56162306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x2  dst = map_val(map_by_fd(imm)) + next_imm   map fd       data pointer
56262306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x3  dst = var_addr(imm)                        variable id  data pointer
56362306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x4  dst = code_addr(imm)                       integer      code pointer
56462306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x5  dst = map_by_idx(imm)                      map index    map
56562306a36Sopenharmony_ciBPF_IMM | BPF_DW | BPF_LD  0x18    0x6  dst = map_val(map_by_idx(imm)) + next_imm  map index    data pointer
56662306a36Sopenharmony_ci=========================  ======  ===  =========================================  ===========  ==============
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ciwhere
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci* map_by_fd(imm) means to convert a 32-bit file descriptor into an address of a map (see `Maps`_)
57162306a36Sopenharmony_ci* map_by_idx(imm) means to convert a 32-bit index into an address of a map
57262306a36Sopenharmony_ci* map_val(map) gets the address of the first value in a given map
57362306a36Sopenharmony_ci* var_addr(imm) gets the address of a platform variable (see `Platform Variables`_) with a given id
57462306a36Sopenharmony_ci* code_addr(imm) gets the address of the instruction at a specified relative offset in number of (64-bit) instructions
57562306a36Sopenharmony_ci* the 'imm type' can be used by disassemblers for display
57662306a36Sopenharmony_ci* the 'dst type' can be used for verification and JIT compilation purposes
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ciMaps
57962306a36Sopenharmony_ci~~~~
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ciMaps are shared memory regions accessible by BPF programs on some platforms.
58262306a36Sopenharmony_ciA map can have various semantics as defined in a separate document, and may or
58362306a36Sopenharmony_cimay not have a single contiguous memory region, but the 'map_val(map)' is
58462306a36Sopenharmony_cicurrently only defined for maps that do have a single contiguous memory region.
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ciEach map can have a file descriptor (fd) if supported by the platform, where
58762306a36Sopenharmony_ci'map_by_fd(imm)' means to get the map with the specified file descriptor. Each
58862306a36Sopenharmony_ciBPF program can also be defined to use a set of maps associated with the
58962306a36Sopenharmony_ciprogram at load time, and 'map_by_idx(imm)' means to get the map with the given
59062306a36Sopenharmony_ciindex in the set associated with the BPF program containing the instruction.
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ciPlatform Variables
59362306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ciPlatform variables are memory regions, identified by integer ids, exposed by
59662306a36Sopenharmony_cithe runtime and accessible by BPF programs on some platforms.  The
59762306a36Sopenharmony_ci'var_addr(imm)' operation means to get the address of the memory region
59862306a36Sopenharmony_ciidentified by the given id.
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_ciLegacy BPF Packet access instructions
60162306a36Sopenharmony_ci-------------------------------------
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ciBPF previously introduced special instructions for access to packet data that were
60462306a36Sopenharmony_cicarried over from classic BPF. However, these instructions are
60562306a36Sopenharmony_cideprecated and should no longer be used.
606