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