From: David Vernet <void@manifault.com>
To: Dave Thaler <dthaler1968=40googlemail.com@dmarc.ietf.org>
Cc: bpf@vger.kernel.org, bpf@ietf.org, Dave Thaler <dthaler1968@gmail.com>
Subject: Re: [Bpf] [PATCH bpf-next] bpf, docs: Use IETF format for field definitions in instruction-set.rst
Date: Fri, 1 Mar 2024 15:49:29 -0600 [thread overview]
Message-ID: <20240301214929.GB192865@maniforge> (raw)
In-Reply-To: <20240301192020.15644-1-dthaler1968@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 43715 bytes --]
On Fri, Mar 01, 2024 at 11:20:20AM -0800, Dave Thaler wrote:
> In preparation for publication as an IETF RFC, the WG chairs asked me
> to convert the document to use IETF packet format for field layout, so
> this patch attempts to make it consistent with other IETF documents.
>
> Some fields that are not byte aligned were previously inconsistent
> in how values were defined. Some were defined as the value of the
> byte containing the field (like 0x20 for a field holding the high
> four bits of the byte), and others were defined as the value of the
> field itself (like 0x2). This PR makes them be consistent in using
> just the values of the field itself, which is IETF convention.
>
> As a result, some of the defines that used BPF_* would no longer
> match the value in the spec, and so this patch also drops the BPF_*
> prefix to avoid confusion with the defines that are the full-byte
> equivalent values. For consistency, BPF_* is then dropped from
> other fields too. BPF_<foo> is thus the Linux implementation-specific
> define for <foo> as it appears in the BPF ISA specification.
>
> The syntax BPF_ADD | BPF_X | BPF_ALU only worked for full-byte
> values so the convention {ADD, X, ALU} is proposed for referring
> to field values instead.
>
> Also replace the redundant "LSB bits" with "least significant bits".
>
> A preview of what the resulting Internet Draft would look like can
> be seen at:
> https://htmlpreview.github.io/?https://raw.githubusercontent.com/dthaler/ebp
> f-docs-1/format/draft-ietf-bpf-isa.html
>
> Signed-off-by: Dave Thaler <dthaler1968@gmail.com>
Very glad that we were able to do this before sending to WG last call. Thank
you, Dave. I left a couple of comments below but here's my AB:
Acked-by: David Vernet <void@manifault.com>
It's probably worth noting that this probably will make it a tiny bit more
difficult for vendors to implement directly from the standard, but I think
that's a small price to pay for having a doc that's properly formatted and
resembles typical IETF standards.
Thanks,
David
> ---
> .../bpf/standardization/instruction-set.rst | 531 ++++++++++--------
> 1 file changed, 290 insertions(+), 241 deletions(-)
>
> diff --git a/Documentation/bpf/standardization/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst
> index f3269d6dd..a0c8fe2f2 100644
> --- a/Documentation/bpf/standardization/instruction-set.rst
> +++ b/Documentation/bpf/standardization/instruction-set.rst
> @@ -24,22 +24,22 @@ a type's signedness (`S`) and bit width (`N`), respectively.
> .. table:: Meaning of signedness notation.
>
> ==== =========
> - `S` Meaning
> + S Meaning
> ==== =========
> - `u` unsigned
> - `s` signed
> + u unsigned
> + s signed
> ==== =========
>
> .. table:: Meaning of bit-width notation.
>
> ===== =========
> - `N` Bit width
> + N Bit width
> ===== =========
> - `8` 8 bits
> - `16` 16 bits
> - `32` 32 bits
> - `64` 64 bits
> - `128` 128 bits
> + 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
> @@ -48,31 +48,31 @@ numbers.
>
> Functions
> ---------
> -* `htobe16`: Takes an unsigned 16-bit number in host-endian format and
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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.
>
> @@ -135,34 +135,63 @@ Instruction encoding
> BPF has two instruction encodings:
>
> * the basic instruction encoding, which uses 64 bits to encode an instruction
> -* the wide instruction encoding, which appends a second 64-bit immediate (i.e.,
> - constant) value after the basic instruction for a total of 128 bits.
> +* the wide instruction encoding, which appends a second 64 bits
> + after the basic instruction for a total of 128 bits.
>
> -The fields conforming an encoded basic instruction are stored in the
> -following order::
> +Basic instruction encoding
> +--------------------------
>
> - opcode:8 src_reg:4 dst_reg:4 offset:16 imm:32 // In little-endian BPF.
> - opcode:8 dst_reg:4 src_reg:4 offset:16 imm:32 // In big-endian BPF.
> +A basic instruction is encoded as follows::
>
> -**imm**
> - signed integer immediate value
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | opcode | regs | offset |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | imm |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>
> -**offset**
> - signed integer offset used with pointer arithmetic
> +**opcode**
> + operation to perform, encoded as follows::
>
> -**src_reg**
> - the source register number (0-10), except where otherwise specified
> - (`64-bit immediate instructions`_ reuse this field for other purposes)
> + +-+-+-+-+-+-+-+-+
> + |specific |class|
> + +-+-+-+-+-+-+-+-+
>
> -**dst_reg**
> - destination register number (0-10)
> + **specific**
> + The format of these bits varies by instruction class
>
> -**opcode**
> - operation to perform
> + **class**
> + The instruction class (see `Instruction classes`_)
> +
> +**regs**
> + The source and destination register numbers, encoded as follows
> + on a little-endian host::
> +
> + +-+-+-+-+-+-+-+-+
> + |src_reg|dst_reg|
> + +-+-+-+-+-+-+-+-+
> +
> + and as follows on a big-endian host::
> +
> + +-+-+-+-+-+-+-+-+
> + |dst_reg|src_reg|
> + +-+-+-+-+-+-+-+-+
> +
> + **src_reg**
> + the source register number (0-10), except where otherwise specified
> + (`64-bit immediate instructions`_ reuse this field for other purposes)
> +
> + **dst_reg**
> + destination register number (0-10)
> +
> +**offset**
> + signed integer offset used with pointer arithmetic
> +
> +**imm**
> + signed integer immediate value
>
> -Note that the contents of multi-byte fields ('imm' and 'offset') are
> -stored using big-endian byte ordering in big-endian BPF and
> -little-endian byte ordering in little-endian BPF.
> +Note that the contents of multi-byte fields ('offset' and 'imm') are
> +stored using big-endian byte ordering on big-endian hosts and
> +little-endian byte ordering on little-endian hosts.
>
> For example::
>
> @@ -175,66 +204,83 @@ For example::
> Note that most instructions do not use all of the fields.
> Unused fields shall be cleared to zero.
>
> -As discussed below in `64-bit immediate instructions`_, a 64-bit immediate
> -instruction uses two 32-bit immediate values that are constructed as follows.
> -The 64 bits following the basic instruction contain a pseudo instruction
> -using the same format but with 'opcode', 'dst_reg', 'src_reg', and 'offset' all
> -set to zero, and imm containing the high 32 bits of the immediate value.
> +Wide instruction encoding
> +--------------------------
> +
> +Some instructions are defined to use the wide instruction encoding,
> +which uses two 32-bit immediate values. The 64 bits following
> +the basic instruction format contain a pseudo instruction
> +with 'opcode', 'dst_reg', 'src_reg', and 'offset' all set to zero.
>
> This is depicted in the following figure::
>
> - basic_instruction
> - .------------------------------.
> - | |
> - opcode:8 regs:8 offset:16 imm:32 unused:32 imm:32
> - | |
> - '--------------'
> - pseudo instruction
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | opcode | regs | offset |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | imm |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | reserved |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | next_imm |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> +
> +**opcode**
> + operation to perform, encoded as explained above
> +
> +**regs**
> + The source and destination register numbers, encoded as explained above
> +
> +**offset**
> + signed integer offset used with pointer arithmetic
> +
> +**imm**
> + signed integer immediate value
> +
> +**reserved**
> + unused, set to zero
>
> -Here, the imm value of the pseudo instruction is called 'next_imm'. The unused
> -bytes in the pseudo instruction are reserved and shall be cleared to zero.
> +**next_imm**
> + second signed integer immediate value
>
> Instruction classes
> -------------------
>
> -The three LSB bits of the 'opcode' field store the instruction class:
> -
> -========= ===== =============================== ===================================
> -class value description reference
> -========= ===== =============================== ===================================
> -BPF_LD 0x00 non-standard load operations `Load and store instructions`_
> -BPF_LDX 0x01 load into register operations `Load and store instructions`_
> -BPF_ST 0x02 store from immediate operations `Load and store instructions`_
> -BPF_STX 0x03 store from register operations `Load and store instructions`_
> -BPF_ALU 0x04 32-bit arithmetic operations `Arithmetic and jump instructions`_
> -BPF_JMP 0x05 64-bit jump operations `Arithmetic and jump instructions`_
> -BPF_JMP32 0x06 32-bit jump operations `Arithmetic and jump instructions`_
> -BPF_ALU64 0x07 64-bit arithmetic operations `Arithmetic and jump instructions`_
> -========= ===== =============================== ===================================
> +The three least significant bits of the 'opcode' field store the instruction class:
> +
> +===== ===== =============================== ===================================
> +class value description reference
> +===== ===== =============================== ===================================
> +LD 0x0 non-standard load operations `Load and store instructions`_
> +LDX 0x1 load into register operations `Load and store instructions`_
> +ST 0x2 store from immediate operations `Load and store instructions`_
> +STX 0x3 store from register operations `Load and store instructions`_
> +ALU 0x4 32-bit arithmetic operations `Arithmetic and jump instructions`_
> +JMP 0x5 64-bit jump operations `Arithmetic and jump instructions`_
> +JMP32 0x6 32-bit jump operations `Arithmetic and jump instructions`_
> +ALU64 0x7 64-bit arithmetic operations `Arithmetic and jump instructions`_
> +===== ===== =============================== ===================================
>
> Arithmetic and jump instructions
> ================================
>
> -For arithmetic and jump instructions (``BPF_ALU``, ``BPF_ALU64``, ``BPF_JMP`` and
> -``BPF_JMP32``), the 8-bit 'opcode' field is divided into three parts:
> +For arithmetic and jump instructions (``ALU``, ``ALU64``, ``JMP`` and
> +``JMP32``), the 8-bit 'opcode' field is divided into three parts::
>
> -============== ====== =================
> -4 bits (MSB) 1 bit 3 bits (LSB)
> -============== ====== =================
> -code source instruction class
> -============== ====== =================
> + +-+-+-+-+-+-+-+-+
> + | code |s|class|
> + +-+-+-+-+-+-+-+-+
>
> **code**
> the operation code, whose meaning varies by instruction class
>
> -**source**
> +**s (source)**
> the source operand location, which unless otherwise specified is one of:
>
> ====== ===== ==============================================
> source value description
> ====== ===== ==============================================
> - BPF_K 0x00 use 32-bit 'imm' value as source operand
> - BPF_X 0x08 use 'src_reg' register value as source operand
> + K 0 use 32-bit 'imm' value as source operand
> + X 1 use 'src_reg' register value as source operand
> ====== ===== ==============================================
>
> **instruction class**
> @@ -243,75 +289,75 @@ code source instruction class
> Arithmetic instructions
> -----------------------
>
> -``BPF_ALU`` uses 32-bit wide operands while ``BPF_ALU64`` uses 64-bit wide operands for
> -otherwise identical operations. ``BPF_ALU64`` instructions belong to the
> +``ALU`` uses 32-bit wide operands while ``ALU64`` uses 64-bit wide operands for
> +otherwise identical operations. ``ALU64`` instructions belong to the
> base64 conformance group unless noted otherwise.
> 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 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)
> -========= ===== ======= ==========================================================
> +===== ===== ======= ==========================================================
> +name code offset description
> +===== ===== ======= ==========================================================
> +ADD 0x0 0 dst += src
> +SUB 0x1 0 dst -= src
> +MUL 0x2 0 dst \*= src
> +DIV 0x3 0 dst = (src != 0) ? (dst / src) : 0
> +SDIV 0x3 1 dst = (src != 0) ? (dst s/ src) : 0
> +OR 0x4 0 dst \|= src
> +AND 0x5 0 dst &= src
> +LSH 0x6 0 dst <<= (src & mask)
> +RSH 0x7 0 dst >>= (src & mask)
> +NEG 0x8 0 dst = -dst
> +MOD 0x9 0 dst = (src != 0) ? (dst % src) : dst
> +SMOD 0x9 1 dst = (src != 0) ? (dst s% src) : dst
> +XOR 0xa 0 dst ^= src
> +MOV 0xb 0 dst = src
> +MOVSX 0xb 8/16/32 dst = (s8,s16,s32)src
> +ARSH 0xc 0 :term:`sign extending<Sign Extend>` dst >>= (src & mask)
> +END 0xd 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 BPF program execution would
> result in division by zero, the destination register is instead set to zero.
> -If execution would result in modulo by zero, for ``BPF_ALU64`` the value of
> -the destination register is unchanged whereas for ``BPF_ALU`` the upper
> +If execution would result in modulo by zero, for ``ALU64`` the value of
> +the destination register is unchanged whereas for ``ALU`` the upper
> 32 bits of the destination register are zeroed.
>
> -``BPF_ADD | BPF_X | BPF_ALU`` means::
> +``{ADD, X, ALU}``, where 'code'=``ADD``, 'source'=``X``, and 'class'=``ALU``, means::
For some reason ``ADD``, ``X`` and ``ALU`` aren't rendering correctly when
built with sphinx. It looks like we need to do this:
diff --git a/Documentation/bpf/standardization/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst
index a0c8fe2f230a..ffcba257e004 100644
--- a/Documentation/bpf/standardization/instruction-set.rst
+++ b/Documentation/bpf/standardization/instruction-set.rst
@@ -324,7 +324,7 @@ If execution would result in modulo by zero, for ``ALU64`` the value of
the destination register is unchanged whereas for ``ALU`` the upper
32 bits of the destination register are zeroed.
-``{ADD, X, ALU}``, where 'code'=``ADD``, 'source'=``X``, and 'class'=``ALU``, means::
+``{ADD, X, ALU}``, where 'code' = ``ADD``, 'source' = ``X``, and 'class' = ``ALU``, means::
dst = (u32) ((u32) dst + (u32) src)
>
> dst = (u32) ((u32) dst + (u32) src)
>
> where '(u32)' indicates that the upper 32 bits are zeroed.
>
> -``BPF_ADD | BPF_X | BPF_ALU64`` means::
> +``{ADD, X, ALU64}`` means::
>
> dst = dst + src
>
> -``BPF_XOR | BPF_K | BPF_ALU`` means::
> +``{XOR, K, ALU}`` means::
>
> dst = (u32) dst ^ (u32) imm
>
> -``BPF_XOR | BPF_K | BPF_ALU64`` means::
> +``{XOR, K, ALU64}`` means::
I do certainly personally prefer the notation that was there before, but if
this more closely matches IETF norms then LGTM.
> dst = dst ^ imm
>
> Note that most instructions have instruction offset of 0. Only three instructions
> -(``BPF_SDIV``, ``BPF_SMOD``, ``BPF_MOVSX``) have a non-zero offset.
> +(``SDIV``, ``SMOD``, ``MOVSX``) have a non-zero offset.
>
> -Division, multiplication, and modulo operations for ``BPF_ALU`` are part
> +Division, multiplication, and modulo operations for ``ALU`` are part
> of the "divmul32" conformance group, and division, multiplication, and
> -modulo operations for ``BPF_ALU64`` are part of the "divmul64" conformance
> +modulo operations for ``ALU64`` are part of the "divmul64" conformance
> group.
> 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``,
> +For unsigned operations (``DIV`` and ``MOD``), for ``ALU``,
> +'imm' is interpreted as a 32-bit unsigned value. For ``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'
> +For signed operations (``SDIV`` and ``SMOD``), for ``ALU``,
> +'imm' is interpreted as a 32-bit signed value. For ``ALU64``, 'imm'
> is first :term:`sign extended<Sign Extend>` from 32 to 64 bits, and then
> interpreted as a 64-bit signed value.
>
> @@ -323,15 +369,15 @@ etc. This specification requires that signed modulo use truncated division
>
> a % n = a - n * trunc(a / n)
>
> -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
> +The ``MOVSX`` instruction does a move operation with sign extension.
> +``{MOVSX, X, ALU}`` :term:`sign extends<Sign Extend>` 8-bit and 16-bit operands into 32
> bit operands, and zeroes the remaining upper 32 bits.
> -``BPF_ALU64 | BPF_MOVSX`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit
> +``{MOVSX, X, ALU64}`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit
> operands into 64 bit operands. Unlike other arithmetic instructions,
> -``BPF_MOVSX`` is only defined for register source operands (``BPF_X``).
> +``MOVSX`` is only defined for register source operands (``X``).
>
> -The ``BPF_NEG`` instruction is only defined when the source bit is clear
> -(``BPF_K``).
> +The ``NEG`` instruction is only defined when the source bit is clear
> +(``K``).
>
> Shift operations use a mask of 0x3F (63) for 64-bit operations and 0x1F (31)
> for 32-bit operations.
> @@ -339,24 +385,24 @@ for 32-bit operations.
> Byte swap instructions
> ----------------------
>
> -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 use instruction classes of ``ALU`` and ``ALU64``
> +and a 4-bit 'code' field of ``END``.
>
> The byte swap instructions operate on the destination register
> only and do not use a separate source register or immediate value.
>
> -For ``BPF_ALU``, the 1-bit source operand field in the opcode is used to
> +For ``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
> +``ALU64``, the 1-bit source operand field in the opcode is reserved
> and must be set to 0.
>
> -========= ========= ===== =================================================
> -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
> -========= ========= ===== =================================================
> +===== ======== ===== =================================================
> +class source value description
> +===== ======== ===== =================================================
> +ALU TO_LE 0 convert between host byte order and little endian
> +ALU TO_BE 1 convert between host byte order and big endian
> +ALU64 Reserved 0 do byte swap unconditionally
> +===== ======== ===== =================================================
>
> The 'imm' field encodes the width of the swap operations. The following widths
> are supported: 16, 32 and 64. Width 64 operations belong to the base64
> @@ -365,19 +411,19 @@ conformance group.
>
> Examples:
>
> -``BPF_ALU | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
> +``{END, TO_LE, ALU}`` with imm = 16/32/64 means::
>
> dst = htole16(dst)
> dst = htole32(dst)
> dst = htole64(dst)
>
> -``BPF_ALU | BPF_TO_BE | BPF_END`` with imm = 16/32/64 means::
> +``{END, TO_BE, ALU}`` with imm = 16/32/64 means::
>
> dst = htobe16(dst)
> dst = htobe32(dst)
> dst = htobe64(dst)
>
> -``BPF_ALU64 | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
> +``{END, TO_LE, ALU64}`` with imm = 16/32/64 means::
>
> dst = bswap16(dst)
> dst = bswap32(dst)
> @@ -386,59 +432,59 @@ Examples:
> Jump instructions
> -----------------
>
> -``BPF_JMP32`` uses 32-bit wide operands and indicates the base32
> -conformance group, while ``BPF_JMP`` uses 64-bit wide operands for
> +``JMP32`` uses 32-bit wide operands and indicates the base32
> +conformance group, while ``JMP`` uses 64-bit wide operands for
> otherwise identical operations, and indicates the base64 conformance
> group unless otherwise specified.
> The 'code' field encodes the operation as below:
>
> -======== ===== ======= =============================== =============================================
> +======== ===== ======= =============================== ===================================================
> code value src_reg description notes
> -======== ===== ======= =============================== =============================================
> -BPF_JA 0x0 0x0 PC += offset BPF_JMP | BPF_K only
> -BPF_JA 0x0 0x0 PC += imm BPF_JMP32 | BPF_K only
> -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
> -BPF_JSET 0x4 any PC += offset if dst & src
> -BPF_JNE 0x5 any PC += offset if dst != src
> -BPF_JSGT 0x6 any PC += offset if dst > src signed
> -BPF_JSGE 0x7 any PC += offset if dst >= src signed
> -BPF_CALL 0x8 0x0 call helper function by address BPF_JMP | BPF_K only, see `Helper functions`_
> -BPF_CALL 0x8 0x1 call PC += imm BPF_JMP | BPF_K only, see `Program-local functions`_
> -BPF_CALL 0x8 0x2 call helper function by BTF ID BPF_JMP | BPF_K only, see `Helper functions`_
> -BPF_EXIT 0x9 0x0 return BPF_JMP | BPF_K only
> -BPF_JLT 0xa any PC += offset if dst < src unsigned
> -BPF_JLE 0xb any PC += offset if dst <= src unsigned
> -BPF_JSLT 0xc any PC += offset if dst < src signed
> -BPF_JSLE 0xd any PC += offset if dst <= src signed
> -======== ===== ======= =============================== =============================================
> -
> -The BPF program needs to store the return value into register R0 before doing a
> -``BPF_EXIT``.
> +======== ===== ======= =============================== ===================================================
> +JA 0x0 0x0 PC += offset {JA, K, JMP} only
> +JA 0x0 0x0 PC += imm {JA, K, JMP32} only
> +JEQ 0x1 any PC += offset if dst == src
> +JGT 0x2 any PC += offset if dst > src unsigned
> +JGE 0x3 any PC += offset if dst >= src unsigned
> +JSET 0x4 any PC += offset if dst & src
> +JNE 0x5 any PC += offset if dst != src
> +JSGT 0x6 any PC += offset if dst > src signed
> +JSGE 0x7 any PC += offset if dst >= src signed
> +CALL 0x8 0x0 call helper function by address {CALL, K, JMP} only, see `Helper functions`_
> +CALL 0x8 0x1 call PC += imm {CALL, K, JMP} only, see `Program-local functions`_
> +CALL 0x8 0x2 call helper function by BTF ID {CALL, K, JMP} only, see `Helper functions`_
> +EXIT 0x9 0x0 return {CALL, K, JMP} only
> +JLT 0xa any PC += offset if dst < src unsigned
> +JLE 0xb any PC += offset if dst <= src unsigned
> +JSLT 0xc any PC += offset if dst < src signed
> +JSLE 0xd any PC += offset if dst <= src signed
> +======== ===== ======= =============================== ===================================================
> +
> +The BPF program needs to store the return value into register R0 before doing an
> +``EXIT``.
>
> Example:
>
> -``BPF_JSGE | BPF_X | BPF_JMP32`` (0x7e) means::
> +``{JSGE, X, JMP32}`` means::
>
> if (s32)dst s>= (s32)src goto +offset
>
> where 's>=' indicates a signed '>=' comparison.
>
> -``BPF_JA | BPF_K | BPF_JMP32`` (0x06) means::
> +``{JA, K, JMP32}`` 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
> +Note that there are two flavors of ``JA`` instructions. The
> +``JMP`` class permits a 16-bit jump offset specified by the 'offset'
> +field, whereas the ``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.
>
> -All ``BPF_CALL`` and ``BPF_JA`` instructions belong to the
> +All ``CALL`` and ``JA`` instructions belong to the
> base32 conformance group.
>
> Helper functions
> @@ -459,80 +505,83 @@ Program-local functions
> ~~~~~~~~~~~~~~~~~~~~~~~
> Program-local functions are functions exposed by the same BPF program as the
> caller, and are referenced by offset from the call instruction, similar to
> -``BPF_JA``. The offset is encoded in the imm field of the call instruction.
> -A ``BPF_EXIT`` within the program-local function will return to the caller.
> +``JA``. The offset is encoded in the imm field of the call instruction.
> +A ``EXIT`` within the program-local function will return to the caller.
>
> Load and store instructions
> ===========================
>
> -For load and store instructions (``BPF_LD``, ``BPF_LDX``, ``BPF_ST``, and ``BPF_STX``), the
> -8-bit 'opcode' field is divided as:
> -
> -============ ====== =================
> -3 bits (MSB) 2 bits 3 bits (LSB)
> -============ ====== =================
> -mode size instruction class
> -============ ====== =================
> -
> -The mode modifier is one of:
> -
> - ============= ===== ==================================== =============
> - mode modifier value description reference
> - ============= ===== ==================================== =============
> - BPF_IMM 0x00 64-bit immediate instructions `64-bit immediate instructions`_
> - 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`_
> - ============= ===== ==================================== =============
> -
> -The size modifier is one of:
> -
> - ============= ===== =====================
> - size modifier value description
> - ============= ===== =====================
> - BPF_W 0x00 word (4 bytes)
> - BPF_H 0x08 half word (2 bytes)
> - BPF_B 0x10 byte
> - BPF_DW 0x18 double word (8 bytes)
> - ============= ===== =====================
> -
> -Instructions using ``BPF_DW`` belong to the base64 conformance group.
> +For load and store instructions (``LD``, ``LDX``, ``ST``, and ``STX``), the
> +8-bit 'opcode' field is divided as::
> +
> + +-+-+-+-+-+-+-+-+
> + |mode |sz |class|
> + +-+-+-+-+-+-+-+-+
> +
> +**mode**
> + The mode modifier is one of:
> +
> + ============= ===== ==================================== =============
> + mode modifier value description reference
> + ============= ===== ==================================== =============
> + IMM 0 64-bit immediate instructions `64-bit immediate instructions`_
> + ABS 1 legacy BPF packet access (absolute) `Legacy BPF Packet access instructions`_
> + IND 2 legacy BPF packet access (indirect) `Legacy BPF Packet access instructions`_
> + MEM 3 regular load and store operations `Regular load and store operations`_
> + MEMSX 4 sign-extension load operations `Sign-extension load operations`_
> + ATOMIC 6 atomic operations `Atomic operations`_
> + ============= ===== ==================================== =============
> +
> +**sz (size)**
> + The size modifier is one of:
> +
> + ==== ===== =====================
> + size value description
> + ==== ===== =====================
> + W 0 word (4 bytes)
> + H 1 half word (2 bytes)
> + B 2 byte
> + DW 3 double word (8 bytes)
> + ==== ===== =====================
> +
> + Instructions using ``DW`` belong to the base64 conformance group.
> +
> +**class**
> + The instruction class (see `Instruction classes`_)
>
> Regular load and store operations
> ---------------------------------
>
> -The ``BPF_MEM`` mode modifier is used to encode regular load and store
> +The ``MEM`` mode modifier is used to encode regular load and store
> instructions that transfer data between a register and memory.
>
> -``BPF_MEM | <size> | BPF_STX`` means::
> +``{MEM, <size>, STX}`` means::
>
> *(size *) (dst + offset) = src
>
> -``BPF_MEM | <size> | BPF_ST`` means::
> +``{MEM, <size>, ST}`` means::
>
> *(size *) (dst + offset) = imm
>
> -``BPF_MEM | <size> | BPF_LDX`` means::
> +``{MEM, <size>, LDX}`` means::
>
> 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.
> +Where '<size>' is one of: ``B``, ``H``, ``W``, or ``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
> +The ``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::
> +``{MEMSX, <size>, LDX}`` means::
>
> dst = *(signed size *) (src + offset)
>
> -Where size is one of: ``BPF_B``, ``BPF_H`` or ``BPF_W``, and
> -'signed size' is one of s8, s16 or s32.
> +Where size is one of: ``B``, ``H``, or ``W``, and
> +'signed size' is one of: s8, s16, or s32.
>
> Atomic operations
> -----------------
> @@ -542,11 +591,11 @@ interrupted or corrupted by other access to the same memory region
> by other BPF programs or means outside of this specification.
>
> All atomic operations supported by BPF are encoded as store operations
> -that use the ``BPF_ATOMIC`` mode modifier as follows:
> +that use the ``ATOMIC`` mode modifier as follows:
>
> -* ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations, which are
> +* ``{ATOMIC, W, STX}`` for 32-bit operations, which are
> part of the "atomic32" conformance group.
> -* ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations, which are
> +* ``{ATOMIC, DW, STX}`` for 64-bit operations, which are
> part of the "atomic64" conformance group.
> * 8-bit and 16-bit wide atomic operations are not supported.
>
> @@ -557,18 +606,18 @@ arithmetic operations in the 'imm' field to encode the atomic operation:
> ======== ===== ===========
> imm value description
> ======== ===== ===========
> -BPF_ADD 0x00 atomic add
> -BPF_OR 0x40 atomic or
> -BPF_AND 0x50 atomic and
> -BPF_XOR 0xa0 atomic xor
> +ADD 0x00 atomic add
> +OR 0x40 atomic or
> +AND 0x50 atomic and
> +XOR 0xa0 atomic xor
> ======== ===== ===========
>
>
> -``BPF_ATOMIC | BPF_W | BPF_STX`` with 'imm' = BPF_ADD means::
> +``{ATOMIC, W, STX}`` with 'imm' = ADD means::
>
> *(u32 *)(dst + offset) += src
>
> -``BPF_ATOMIC | BPF_DW | BPF_STX`` with 'imm' = BPF_ADD means::
> +``{ATOMIC, DW, STX}`` with 'imm' = ADD means::
>
> *(u64 *)(dst + offset) += src
>
> @@ -578,20 +627,20 @@ two complex atomic operations:
> =========== ================ ===========================
> imm value description
> =========== ================ ===========================
> -BPF_FETCH 0x01 modifier: return old value
> -BPF_XCHG 0xe0 | BPF_FETCH atomic exchange
> -BPF_CMPXCHG 0xf0 | BPF_FETCH atomic compare and exchange
> +FETCH 0x01 modifier: return old value
> +XCHG 0xe0 | FETCH atomic exchange
> +CMPXCHG 0xf0 | FETCH atomic compare and exchange
> =========== ================ ===========================
>
> -The ``BPF_FETCH`` modifier is optional for simple atomic operations, and
> -always set for the complex atomic operations. If the ``BPF_FETCH`` flag
> +The ``FETCH`` modifier is optional for simple atomic operations, and
> +always set for the complex atomic operations. If the ``FETCH`` flag
> is set, then the operation also overwrites ``src`` with the value that
> was in memory before it was modified.
>
> -The ``BPF_XCHG`` operation atomically exchanges ``src`` with the value
> +The ``XCHG`` operation atomically exchanges ``src`` with the value
> addressed by ``dst + offset``.
>
> -The ``BPF_CMPXCHG`` operation atomically compares the value addressed by
> +The ``CMPXCHG`` operation atomically compares the value addressed by
> ``dst + offset`` with ``R0``. If they match, the value addressed by
> ``dst + offset`` is replaced with ``src``. In either case, the
> value that was at ``dst + offset`` before the operation is zero-extended
> @@ -600,25 +649,25 @@ and loaded back to ``R0``.
> 64-bit immediate instructions
> -----------------------------
>
> -Instructions with the ``BPF_IMM`` 'mode' modifier use the wide instruction
> +Instructions with the ``IMM`` 'mode' modifier use the wide instruction
> encoding defined in `Instruction encoding`_, and use the 'src_reg' field of the
> basic instruction to hold an opcode subtype.
>
> -The following table defines a set of ``BPF_IMM | BPF_DW | BPF_LD`` instructions
> +The following table defines a set of ``{IMM, DW, LD}`` instructions
> with opcode subtypes in the 'src_reg' field, using new terms such as "map"
> defined further below:
>
> -========================= ====== ======= ========================================= =========== ==============
> -opcode construction opcode src_reg pseudocode imm type dst type
> -========================= ====== ======= ========================================= =========== ==============
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x0 dst = (next_imm << 32) | imm integer integer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x1 dst = map_by_fd(imm) map fd map
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x3 dst = var_addr(imm) variable id data pointer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x4 dst = code_addr(imm) integer code pointer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x5 dst = map_by_idx(imm) map index map
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer
> -========================= ====== ======= ========================================= =========== ==============
> +======= ========================================= =========== ==============
> +src_reg pseudocode imm type dst type
> +======= ========================================= =========== ==============
> +0x0 dst = (next_imm << 32) | imm integer integer
> +0x1 dst = map_by_fd(imm) map fd map
> +0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer
> +0x3 dst = var_addr(imm) variable id data pointer
> +0x4 dst = code_addr(imm) integer code pointer
> +0x5 dst = map_by_idx(imm) map index map
> +0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer
> +======= ========================================= =========== ==============
>
> where
>
> @@ -657,8 +706,8 @@ Legacy BPF Packet access instructions
>
> BPF previously introduced special instructions for access to packet data that were
> carried over from classic BPF. These instructions used an instruction
> -class of BPF_LD, a size modifier of BPF_W, BPF_H, or BPF_B, and a
> -mode modifier of BPF_ABS or BPF_IND. The 'dst_reg' and 'offset' fields were
> -set to zero, and 'src_reg' was set to zero for BPF_ABS. However, these
> +class of ``LD``, a size modifier of ``W``, ``H``, or ``B``, and a
> +mode modifier of ``ABS`` or ``IND``. The 'dst_reg' and 'offset' fields were
> +set to zero, and 'src_reg' was set to zero for ``ABS``. However, these
> instructions are deprecated and should no longer be used. All legacy packet
> access instructions belong to the "legacy" conformance group.
> --
> 2.40.1
>
>
> --
> Bpf mailing list
> Bpf@ietf.org
> https://www.ietf.org/mailman/listinfo/bpf
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: David Vernet <void@manifault.com>
To: Dave Thaler <dthaler1968=40googlemail.com@dmarc.ietf.org>
Cc: bpf@vger.kernel.org, bpf@ietf.org, Dave Thaler <dthaler1968@gmail.com>
Subject: Re: [Bpf] [PATCH bpf-next] bpf, docs: Use IETF format for field definitions in instruction-set.rst
Date: Fri, 1 Mar 2024 15:49:29 -0600 [thread overview]
Message-ID: <20240301214929.GB192865@maniforge> (raw)
Message-ID: <20240301214929.NKpF5QFNzBZCAJ0hzOmYz51j8GG6O7K6ugc-Aa4_hEA@z> (raw)
In-Reply-To: <20240301192020.15644-1-dthaler1968@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 43715 bytes --]
On Fri, Mar 01, 2024 at 11:20:20AM -0800, Dave Thaler wrote:
> In preparation for publication as an IETF RFC, the WG chairs asked me
> to convert the document to use IETF packet format for field layout, so
> this patch attempts to make it consistent with other IETF documents.
>
> Some fields that are not byte aligned were previously inconsistent
> in how values were defined. Some were defined as the value of the
> byte containing the field (like 0x20 for a field holding the high
> four bits of the byte), and others were defined as the value of the
> field itself (like 0x2). This PR makes them be consistent in using
> just the values of the field itself, which is IETF convention.
>
> As a result, some of the defines that used BPF_* would no longer
> match the value in the spec, and so this patch also drops the BPF_*
> prefix to avoid confusion with the defines that are the full-byte
> equivalent values. For consistency, BPF_* is then dropped from
> other fields too. BPF_<foo> is thus the Linux implementation-specific
> define for <foo> as it appears in the BPF ISA specification.
>
> The syntax BPF_ADD | BPF_X | BPF_ALU only worked for full-byte
> values so the convention {ADD, X, ALU} is proposed for referring
> to field values instead.
>
> Also replace the redundant "LSB bits" with "least significant bits".
>
> A preview of what the resulting Internet Draft would look like can
> be seen at:
> https://htmlpreview.github.io/?https://raw.githubusercontent.com/dthaler/ebp
> f-docs-1/format/draft-ietf-bpf-isa.html
>
> Signed-off-by: Dave Thaler <dthaler1968@gmail.com>
Very glad that we were able to do this before sending to WG last call. Thank
you, Dave. I left a couple of comments below but here's my AB:
Acked-by: David Vernet <void@manifault.com>
It's probably worth noting that this probably will make it a tiny bit more
difficult for vendors to implement directly from the standard, but I think
that's a small price to pay for having a doc that's properly formatted and
resembles typical IETF standards.
Thanks,
David
> ---
> .../bpf/standardization/instruction-set.rst | 531 ++++++++++--------
> 1 file changed, 290 insertions(+), 241 deletions(-)
>
> diff --git a/Documentation/bpf/standardization/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst
> index f3269d6dd..a0c8fe2f2 100644
> --- a/Documentation/bpf/standardization/instruction-set.rst
> +++ b/Documentation/bpf/standardization/instruction-set.rst
> @@ -24,22 +24,22 @@ a type's signedness (`S`) and bit width (`N`), respectively.
> .. table:: Meaning of signedness notation.
>
> ==== =========
> - `S` Meaning
> + S Meaning
> ==== =========
> - `u` unsigned
> - `s` signed
> + u unsigned
> + s signed
> ==== =========
>
> .. table:: Meaning of bit-width notation.
>
> ===== =========
> - `N` Bit width
> + N Bit width
> ===== =========
> - `8` 8 bits
> - `16` 16 bits
> - `32` 32 bits
> - `64` 64 bits
> - `128` 128 bits
> + 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
> @@ -48,31 +48,31 @@ numbers.
>
> Functions
> ---------
> -* `htobe16`: Takes an unsigned 16-bit number in host-endian format and
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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
> +* 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.
>
> @@ -135,34 +135,63 @@ Instruction encoding
> BPF has two instruction encodings:
>
> * the basic instruction encoding, which uses 64 bits to encode an instruction
> -* the wide instruction encoding, which appends a second 64-bit immediate (i.e.,
> - constant) value after the basic instruction for a total of 128 bits.
> +* the wide instruction encoding, which appends a second 64 bits
> + after the basic instruction for a total of 128 bits.
>
> -The fields conforming an encoded basic instruction are stored in the
> -following order::
> +Basic instruction encoding
> +--------------------------
>
> - opcode:8 src_reg:4 dst_reg:4 offset:16 imm:32 // In little-endian BPF.
> - opcode:8 dst_reg:4 src_reg:4 offset:16 imm:32 // In big-endian BPF.
> +A basic instruction is encoded as follows::
>
> -**imm**
> - signed integer immediate value
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | opcode | regs | offset |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | imm |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>
> -**offset**
> - signed integer offset used with pointer arithmetic
> +**opcode**
> + operation to perform, encoded as follows::
>
> -**src_reg**
> - the source register number (0-10), except where otherwise specified
> - (`64-bit immediate instructions`_ reuse this field for other purposes)
> + +-+-+-+-+-+-+-+-+
> + |specific |class|
> + +-+-+-+-+-+-+-+-+
>
> -**dst_reg**
> - destination register number (0-10)
> + **specific**
> + The format of these bits varies by instruction class
>
> -**opcode**
> - operation to perform
> + **class**
> + The instruction class (see `Instruction classes`_)
> +
> +**regs**
> + The source and destination register numbers, encoded as follows
> + on a little-endian host::
> +
> + +-+-+-+-+-+-+-+-+
> + |src_reg|dst_reg|
> + +-+-+-+-+-+-+-+-+
> +
> + and as follows on a big-endian host::
> +
> + +-+-+-+-+-+-+-+-+
> + |dst_reg|src_reg|
> + +-+-+-+-+-+-+-+-+
> +
> + **src_reg**
> + the source register number (0-10), except where otherwise specified
> + (`64-bit immediate instructions`_ reuse this field for other purposes)
> +
> + **dst_reg**
> + destination register number (0-10)
> +
> +**offset**
> + signed integer offset used with pointer arithmetic
> +
> +**imm**
> + signed integer immediate value
>
> -Note that the contents of multi-byte fields ('imm' and 'offset') are
> -stored using big-endian byte ordering in big-endian BPF and
> -little-endian byte ordering in little-endian BPF.
> +Note that the contents of multi-byte fields ('offset' and 'imm') are
> +stored using big-endian byte ordering on big-endian hosts and
> +little-endian byte ordering on little-endian hosts.
>
> For example::
>
> @@ -175,66 +204,83 @@ For example::
> Note that most instructions do not use all of the fields.
> Unused fields shall be cleared to zero.
>
> -As discussed below in `64-bit immediate instructions`_, a 64-bit immediate
> -instruction uses two 32-bit immediate values that are constructed as follows.
> -The 64 bits following the basic instruction contain a pseudo instruction
> -using the same format but with 'opcode', 'dst_reg', 'src_reg', and 'offset' all
> -set to zero, and imm containing the high 32 bits of the immediate value.
> +Wide instruction encoding
> +--------------------------
> +
> +Some instructions are defined to use the wide instruction encoding,
> +which uses two 32-bit immediate values. The 64 bits following
> +the basic instruction format contain a pseudo instruction
> +with 'opcode', 'dst_reg', 'src_reg', and 'offset' all set to zero.
>
> This is depicted in the following figure::
>
> - basic_instruction
> - .------------------------------.
> - | |
> - opcode:8 regs:8 offset:16 imm:32 unused:32 imm:32
> - | |
> - '--------------'
> - pseudo instruction
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | opcode | regs | offset |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | imm |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | reserved |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> + | next_imm |
> + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> +
> +**opcode**
> + operation to perform, encoded as explained above
> +
> +**regs**
> + The source and destination register numbers, encoded as explained above
> +
> +**offset**
> + signed integer offset used with pointer arithmetic
> +
> +**imm**
> + signed integer immediate value
> +
> +**reserved**
> + unused, set to zero
>
> -Here, the imm value of the pseudo instruction is called 'next_imm'. The unused
> -bytes in the pseudo instruction are reserved and shall be cleared to zero.
> +**next_imm**
> + second signed integer immediate value
>
> Instruction classes
> -------------------
>
> -The three LSB bits of the 'opcode' field store the instruction class:
> -
> -========= ===== =============================== ===================================
> -class value description reference
> -========= ===== =============================== ===================================
> -BPF_LD 0x00 non-standard load operations `Load and store instructions`_
> -BPF_LDX 0x01 load into register operations `Load and store instructions`_
> -BPF_ST 0x02 store from immediate operations `Load and store instructions`_
> -BPF_STX 0x03 store from register operations `Load and store instructions`_
> -BPF_ALU 0x04 32-bit arithmetic operations `Arithmetic and jump instructions`_
> -BPF_JMP 0x05 64-bit jump operations `Arithmetic and jump instructions`_
> -BPF_JMP32 0x06 32-bit jump operations `Arithmetic and jump instructions`_
> -BPF_ALU64 0x07 64-bit arithmetic operations `Arithmetic and jump instructions`_
> -========= ===== =============================== ===================================
> +The three least significant bits of the 'opcode' field store the instruction class:
> +
> +===== ===== =============================== ===================================
> +class value description reference
> +===== ===== =============================== ===================================
> +LD 0x0 non-standard load operations `Load and store instructions`_
> +LDX 0x1 load into register operations `Load and store instructions`_
> +ST 0x2 store from immediate operations `Load and store instructions`_
> +STX 0x3 store from register operations `Load and store instructions`_
> +ALU 0x4 32-bit arithmetic operations `Arithmetic and jump instructions`_
> +JMP 0x5 64-bit jump operations `Arithmetic and jump instructions`_
> +JMP32 0x6 32-bit jump operations `Arithmetic and jump instructions`_
> +ALU64 0x7 64-bit arithmetic operations `Arithmetic and jump instructions`_
> +===== ===== =============================== ===================================
>
> Arithmetic and jump instructions
> ================================
>
> -For arithmetic and jump instructions (``BPF_ALU``, ``BPF_ALU64``, ``BPF_JMP`` and
> -``BPF_JMP32``), the 8-bit 'opcode' field is divided into three parts:
> +For arithmetic and jump instructions (``ALU``, ``ALU64``, ``JMP`` and
> +``JMP32``), the 8-bit 'opcode' field is divided into three parts::
>
> -============== ====== =================
> -4 bits (MSB) 1 bit 3 bits (LSB)
> -============== ====== =================
> -code source instruction class
> -============== ====== =================
> + +-+-+-+-+-+-+-+-+
> + | code |s|class|
> + +-+-+-+-+-+-+-+-+
>
> **code**
> the operation code, whose meaning varies by instruction class
>
> -**source**
> +**s (source)**
> the source operand location, which unless otherwise specified is one of:
>
> ====== ===== ==============================================
> source value description
> ====== ===== ==============================================
> - BPF_K 0x00 use 32-bit 'imm' value as source operand
> - BPF_X 0x08 use 'src_reg' register value as source operand
> + K 0 use 32-bit 'imm' value as source operand
> + X 1 use 'src_reg' register value as source operand
> ====== ===== ==============================================
>
> **instruction class**
> @@ -243,75 +289,75 @@ code source instruction class
> Arithmetic instructions
> -----------------------
>
> -``BPF_ALU`` uses 32-bit wide operands while ``BPF_ALU64`` uses 64-bit wide operands for
> -otherwise identical operations. ``BPF_ALU64`` instructions belong to the
> +``ALU`` uses 32-bit wide operands while ``ALU64`` uses 64-bit wide operands for
> +otherwise identical operations. ``ALU64`` instructions belong to the
> base64 conformance group unless noted otherwise.
> 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 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)
> -========= ===== ======= ==========================================================
> +===== ===== ======= ==========================================================
> +name code offset description
> +===== ===== ======= ==========================================================
> +ADD 0x0 0 dst += src
> +SUB 0x1 0 dst -= src
> +MUL 0x2 0 dst \*= src
> +DIV 0x3 0 dst = (src != 0) ? (dst / src) : 0
> +SDIV 0x3 1 dst = (src != 0) ? (dst s/ src) : 0
> +OR 0x4 0 dst \|= src
> +AND 0x5 0 dst &= src
> +LSH 0x6 0 dst <<= (src & mask)
> +RSH 0x7 0 dst >>= (src & mask)
> +NEG 0x8 0 dst = -dst
> +MOD 0x9 0 dst = (src != 0) ? (dst % src) : dst
> +SMOD 0x9 1 dst = (src != 0) ? (dst s% src) : dst
> +XOR 0xa 0 dst ^= src
> +MOV 0xb 0 dst = src
> +MOVSX 0xb 8/16/32 dst = (s8,s16,s32)src
> +ARSH 0xc 0 :term:`sign extending<Sign Extend>` dst >>= (src & mask)
> +END 0xd 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 BPF program execution would
> result in division by zero, the destination register is instead set to zero.
> -If execution would result in modulo by zero, for ``BPF_ALU64`` the value of
> -the destination register is unchanged whereas for ``BPF_ALU`` the upper
> +If execution would result in modulo by zero, for ``ALU64`` the value of
> +the destination register is unchanged whereas for ``ALU`` the upper
> 32 bits of the destination register are zeroed.
>
> -``BPF_ADD | BPF_X | BPF_ALU`` means::
> +``{ADD, X, ALU}``, where 'code'=``ADD``, 'source'=``X``, and 'class'=``ALU``, means::
For some reason ``ADD``, ``X`` and ``ALU`` aren't rendering correctly when
built with sphinx. It looks like we need to do this:
diff --git a/Documentation/bpf/standardization/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst
index a0c8fe2f230a..ffcba257e004 100644
--- a/Documentation/bpf/standardization/instruction-set.rst
+++ b/Documentation/bpf/standardization/instruction-set.rst
@@ -324,7 +324,7 @@ If execution would result in modulo by zero, for ``ALU64`` the value of
the destination register is unchanged whereas for ``ALU`` the upper
32 bits of the destination register are zeroed.
-``{ADD, X, ALU}``, where 'code'=``ADD``, 'source'=``X``, and 'class'=``ALU``, means::
+``{ADD, X, ALU}``, where 'code' = ``ADD``, 'source' = ``X``, and 'class' = ``ALU``, means::
dst = (u32) ((u32) dst + (u32) src)
>
> dst = (u32) ((u32) dst + (u32) src)
>
> where '(u32)' indicates that the upper 32 bits are zeroed.
>
> -``BPF_ADD | BPF_X | BPF_ALU64`` means::
> +``{ADD, X, ALU64}`` means::
>
> dst = dst + src
>
> -``BPF_XOR | BPF_K | BPF_ALU`` means::
> +``{XOR, K, ALU}`` means::
>
> dst = (u32) dst ^ (u32) imm
>
> -``BPF_XOR | BPF_K | BPF_ALU64`` means::
> +``{XOR, K, ALU64}`` means::
I do certainly personally prefer the notation that was there before, but if
this more closely matches IETF norms then LGTM.
> dst = dst ^ imm
>
> Note that most instructions have instruction offset of 0. Only three instructions
> -(``BPF_SDIV``, ``BPF_SMOD``, ``BPF_MOVSX``) have a non-zero offset.
> +(``SDIV``, ``SMOD``, ``MOVSX``) have a non-zero offset.
>
> -Division, multiplication, and modulo operations for ``BPF_ALU`` are part
> +Division, multiplication, and modulo operations for ``ALU`` are part
> of the "divmul32" conformance group, and division, multiplication, and
> -modulo operations for ``BPF_ALU64`` are part of the "divmul64" conformance
> +modulo operations for ``ALU64`` are part of the "divmul64" conformance
> group.
> 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``,
> +For unsigned operations (``DIV`` and ``MOD``), for ``ALU``,
> +'imm' is interpreted as a 32-bit unsigned value. For ``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'
> +For signed operations (``SDIV`` and ``SMOD``), for ``ALU``,
> +'imm' is interpreted as a 32-bit signed value. For ``ALU64``, 'imm'
> is first :term:`sign extended<Sign Extend>` from 32 to 64 bits, and then
> interpreted as a 64-bit signed value.
>
> @@ -323,15 +369,15 @@ etc. This specification requires that signed modulo use truncated division
>
> a % n = a - n * trunc(a / n)
>
> -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
> +The ``MOVSX`` instruction does a move operation with sign extension.
> +``{MOVSX, X, ALU}`` :term:`sign extends<Sign Extend>` 8-bit and 16-bit operands into 32
> bit operands, and zeroes the remaining upper 32 bits.
> -``BPF_ALU64 | BPF_MOVSX`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit
> +``{MOVSX, X, ALU64}`` :term:`sign extends<Sign Extend>` 8-bit, 16-bit, and 32-bit
> operands into 64 bit operands. Unlike other arithmetic instructions,
> -``BPF_MOVSX`` is only defined for register source operands (``BPF_X``).
> +``MOVSX`` is only defined for register source operands (``X``).
>
> -The ``BPF_NEG`` instruction is only defined when the source bit is clear
> -(``BPF_K``).
> +The ``NEG`` instruction is only defined when the source bit is clear
> +(``K``).
>
> Shift operations use a mask of 0x3F (63) for 64-bit operations and 0x1F (31)
> for 32-bit operations.
> @@ -339,24 +385,24 @@ for 32-bit operations.
> Byte swap instructions
> ----------------------
>
> -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 use instruction classes of ``ALU`` and ``ALU64``
> +and a 4-bit 'code' field of ``END``.
>
> The byte swap instructions operate on the destination register
> only and do not use a separate source register or immediate value.
>
> -For ``BPF_ALU``, the 1-bit source operand field in the opcode is used to
> +For ``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
> +``ALU64``, the 1-bit source operand field in the opcode is reserved
> and must be set to 0.
>
> -========= ========= ===== =================================================
> -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
> -========= ========= ===== =================================================
> +===== ======== ===== =================================================
> +class source value description
> +===== ======== ===== =================================================
> +ALU TO_LE 0 convert between host byte order and little endian
> +ALU TO_BE 1 convert between host byte order and big endian
> +ALU64 Reserved 0 do byte swap unconditionally
> +===== ======== ===== =================================================
>
> The 'imm' field encodes the width of the swap operations. The following widths
> are supported: 16, 32 and 64. Width 64 operations belong to the base64
> @@ -365,19 +411,19 @@ conformance group.
>
> Examples:
>
> -``BPF_ALU | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
> +``{END, TO_LE, ALU}`` with imm = 16/32/64 means::
>
> dst = htole16(dst)
> dst = htole32(dst)
> dst = htole64(dst)
>
> -``BPF_ALU | BPF_TO_BE | BPF_END`` with imm = 16/32/64 means::
> +``{END, TO_BE, ALU}`` with imm = 16/32/64 means::
>
> dst = htobe16(dst)
> dst = htobe32(dst)
> dst = htobe64(dst)
>
> -``BPF_ALU64 | BPF_TO_LE | BPF_END`` with imm = 16/32/64 means::
> +``{END, TO_LE, ALU64}`` with imm = 16/32/64 means::
>
> dst = bswap16(dst)
> dst = bswap32(dst)
> @@ -386,59 +432,59 @@ Examples:
> Jump instructions
> -----------------
>
> -``BPF_JMP32`` uses 32-bit wide operands and indicates the base32
> -conformance group, while ``BPF_JMP`` uses 64-bit wide operands for
> +``JMP32`` uses 32-bit wide operands and indicates the base32
> +conformance group, while ``JMP`` uses 64-bit wide operands for
> otherwise identical operations, and indicates the base64 conformance
> group unless otherwise specified.
> The 'code' field encodes the operation as below:
>
> -======== ===== ======= =============================== =============================================
> +======== ===== ======= =============================== ===================================================
> code value src_reg description notes
> -======== ===== ======= =============================== =============================================
> -BPF_JA 0x0 0x0 PC += offset BPF_JMP | BPF_K only
> -BPF_JA 0x0 0x0 PC += imm BPF_JMP32 | BPF_K only
> -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
> -BPF_JSET 0x4 any PC += offset if dst & src
> -BPF_JNE 0x5 any PC += offset if dst != src
> -BPF_JSGT 0x6 any PC += offset if dst > src signed
> -BPF_JSGE 0x7 any PC += offset if dst >= src signed
> -BPF_CALL 0x8 0x0 call helper function by address BPF_JMP | BPF_K only, see `Helper functions`_
> -BPF_CALL 0x8 0x1 call PC += imm BPF_JMP | BPF_K only, see `Program-local functions`_
> -BPF_CALL 0x8 0x2 call helper function by BTF ID BPF_JMP | BPF_K only, see `Helper functions`_
> -BPF_EXIT 0x9 0x0 return BPF_JMP | BPF_K only
> -BPF_JLT 0xa any PC += offset if dst < src unsigned
> -BPF_JLE 0xb any PC += offset if dst <= src unsigned
> -BPF_JSLT 0xc any PC += offset if dst < src signed
> -BPF_JSLE 0xd any PC += offset if dst <= src signed
> -======== ===== ======= =============================== =============================================
> -
> -The BPF program needs to store the return value into register R0 before doing a
> -``BPF_EXIT``.
> +======== ===== ======= =============================== ===================================================
> +JA 0x0 0x0 PC += offset {JA, K, JMP} only
> +JA 0x0 0x0 PC += imm {JA, K, JMP32} only
> +JEQ 0x1 any PC += offset if dst == src
> +JGT 0x2 any PC += offset if dst > src unsigned
> +JGE 0x3 any PC += offset if dst >= src unsigned
> +JSET 0x4 any PC += offset if dst & src
> +JNE 0x5 any PC += offset if dst != src
> +JSGT 0x6 any PC += offset if dst > src signed
> +JSGE 0x7 any PC += offset if dst >= src signed
> +CALL 0x8 0x0 call helper function by address {CALL, K, JMP} only, see `Helper functions`_
> +CALL 0x8 0x1 call PC += imm {CALL, K, JMP} only, see `Program-local functions`_
> +CALL 0x8 0x2 call helper function by BTF ID {CALL, K, JMP} only, see `Helper functions`_
> +EXIT 0x9 0x0 return {CALL, K, JMP} only
> +JLT 0xa any PC += offset if dst < src unsigned
> +JLE 0xb any PC += offset if dst <= src unsigned
> +JSLT 0xc any PC += offset if dst < src signed
> +JSLE 0xd any PC += offset if dst <= src signed
> +======== ===== ======= =============================== ===================================================
> +
> +The BPF program needs to store the return value into register R0 before doing an
> +``EXIT``.
>
> Example:
>
> -``BPF_JSGE | BPF_X | BPF_JMP32`` (0x7e) means::
> +``{JSGE, X, JMP32}`` means::
>
> if (s32)dst s>= (s32)src goto +offset
>
> where 's>=' indicates a signed '>=' comparison.
>
> -``BPF_JA | BPF_K | BPF_JMP32`` (0x06) means::
> +``{JA, K, JMP32}`` 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
> +Note that there are two flavors of ``JA`` instructions. The
> +``JMP`` class permits a 16-bit jump offset specified by the 'offset'
> +field, whereas the ``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.
>
> -All ``BPF_CALL`` and ``BPF_JA`` instructions belong to the
> +All ``CALL`` and ``JA`` instructions belong to the
> base32 conformance group.
>
> Helper functions
> @@ -459,80 +505,83 @@ Program-local functions
> ~~~~~~~~~~~~~~~~~~~~~~~
> Program-local functions are functions exposed by the same BPF program as the
> caller, and are referenced by offset from the call instruction, similar to
> -``BPF_JA``. The offset is encoded in the imm field of the call instruction.
> -A ``BPF_EXIT`` within the program-local function will return to the caller.
> +``JA``. The offset is encoded in the imm field of the call instruction.
> +A ``EXIT`` within the program-local function will return to the caller.
>
> Load and store instructions
> ===========================
>
> -For load and store instructions (``BPF_LD``, ``BPF_LDX``, ``BPF_ST``, and ``BPF_STX``), the
> -8-bit 'opcode' field is divided as:
> -
> -============ ====== =================
> -3 bits (MSB) 2 bits 3 bits (LSB)
> -============ ====== =================
> -mode size instruction class
> -============ ====== =================
> -
> -The mode modifier is one of:
> -
> - ============= ===== ==================================== =============
> - mode modifier value description reference
> - ============= ===== ==================================== =============
> - BPF_IMM 0x00 64-bit immediate instructions `64-bit immediate instructions`_
> - 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`_
> - ============= ===== ==================================== =============
> -
> -The size modifier is one of:
> -
> - ============= ===== =====================
> - size modifier value description
> - ============= ===== =====================
> - BPF_W 0x00 word (4 bytes)
> - BPF_H 0x08 half word (2 bytes)
> - BPF_B 0x10 byte
> - BPF_DW 0x18 double word (8 bytes)
> - ============= ===== =====================
> -
> -Instructions using ``BPF_DW`` belong to the base64 conformance group.
> +For load and store instructions (``LD``, ``LDX``, ``ST``, and ``STX``), the
> +8-bit 'opcode' field is divided as::
> +
> + +-+-+-+-+-+-+-+-+
> + |mode |sz |class|
> + +-+-+-+-+-+-+-+-+
> +
> +**mode**
> + The mode modifier is one of:
> +
> + ============= ===== ==================================== =============
> + mode modifier value description reference
> + ============= ===== ==================================== =============
> + IMM 0 64-bit immediate instructions `64-bit immediate instructions`_
> + ABS 1 legacy BPF packet access (absolute) `Legacy BPF Packet access instructions`_
> + IND 2 legacy BPF packet access (indirect) `Legacy BPF Packet access instructions`_
> + MEM 3 regular load and store operations `Regular load and store operations`_
> + MEMSX 4 sign-extension load operations `Sign-extension load operations`_
> + ATOMIC 6 atomic operations `Atomic operations`_
> + ============= ===== ==================================== =============
> +
> +**sz (size)**
> + The size modifier is one of:
> +
> + ==== ===== =====================
> + size value description
> + ==== ===== =====================
> + W 0 word (4 bytes)
> + H 1 half word (2 bytes)
> + B 2 byte
> + DW 3 double word (8 bytes)
> + ==== ===== =====================
> +
> + Instructions using ``DW`` belong to the base64 conformance group.
> +
> +**class**
> + The instruction class (see `Instruction classes`_)
>
> Regular load and store operations
> ---------------------------------
>
> -The ``BPF_MEM`` mode modifier is used to encode regular load and store
> +The ``MEM`` mode modifier is used to encode regular load and store
> instructions that transfer data between a register and memory.
>
> -``BPF_MEM | <size> | BPF_STX`` means::
> +``{MEM, <size>, STX}`` means::
>
> *(size *) (dst + offset) = src
>
> -``BPF_MEM | <size> | BPF_ST`` means::
> +``{MEM, <size>, ST}`` means::
>
> *(size *) (dst + offset) = imm
>
> -``BPF_MEM | <size> | BPF_LDX`` means::
> +``{MEM, <size>, LDX}`` means::
>
> 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.
> +Where '<size>' is one of: ``B``, ``H``, ``W``, or ``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
> +The ``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::
> +``{MEMSX, <size>, LDX}`` means::
>
> dst = *(signed size *) (src + offset)
>
> -Where size is one of: ``BPF_B``, ``BPF_H`` or ``BPF_W``, and
> -'signed size' is one of s8, s16 or s32.
> +Where size is one of: ``B``, ``H``, or ``W``, and
> +'signed size' is one of: s8, s16, or s32.
>
> Atomic operations
> -----------------
> @@ -542,11 +591,11 @@ interrupted or corrupted by other access to the same memory region
> by other BPF programs or means outside of this specification.
>
> All atomic operations supported by BPF are encoded as store operations
> -that use the ``BPF_ATOMIC`` mode modifier as follows:
> +that use the ``ATOMIC`` mode modifier as follows:
>
> -* ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations, which are
> +* ``{ATOMIC, W, STX}`` for 32-bit operations, which are
> part of the "atomic32" conformance group.
> -* ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations, which are
> +* ``{ATOMIC, DW, STX}`` for 64-bit operations, which are
> part of the "atomic64" conformance group.
> * 8-bit and 16-bit wide atomic operations are not supported.
>
> @@ -557,18 +606,18 @@ arithmetic operations in the 'imm' field to encode the atomic operation:
> ======== ===== ===========
> imm value description
> ======== ===== ===========
> -BPF_ADD 0x00 atomic add
> -BPF_OR 0x40 atomic or
> -BPF_AND 0x50 atomic and
> -BPF_XOR 0xa0 atomic xor
> +ADD 0x00 atomic add
> +OR 0x40 atomic or
> +AND 0x50 atomic and
> +XOR 0xa0 atomic xor
> ======== ===== ===========
>
>
> -``BPF_ATOMIC | BPF_W | BPF_STX`` with 'imm' = BPF_ADD means::
> +``{ATOMIC, W, STX}`` with 'imm' = ADD means::
>
> *(u32 *)(dst + offset) += src
>
> -``BPF_ATOMIC | BPF_DW | BPF_STX`` with 'imm' = BPF_ADD means::
> +``{ATOMIC, DW, STX}`` with 'imm' = ADD means::
>
> *(u64 *)(dst + offset) += src
>
> @@ -578,20 +627,20 @@ two complex atomic operations:
> =========== ================ ===========================
> imm value description
> =========== ================ ===========================
> -BPF_FETCH 0x01 modifier: return old value
> -BPF_XCHG 0xe0 | BPF_FETCH atomic exchange
> -BPF_CMPXCHG 0xf0 | BPF_FETCH atomic compare and exchange
> +FETCH 0x01 modifier: return old value
> +XCHG 0xe0 | FETCH atomic exchange
> +CMPXCHG 0xf0 | FETCH atomic compare and exchange
> =========== ================ ===========================
>
> -The ``BPF_FETCH`` modifier is optional for simple atomic operations, and
> -always set for the complex atomic operations. If the ``BPF_FETCH`` flag
> +The ``FETCH`` modifier is optional for simple atomic operations, and
> +always set for the complex atomic operations. If the ``FETCH`` flag
> is set, then the operation also overwrites ``src`` with the value that
> was in memory before it was modified.
>
> -The ``BPF_XCHG`` operation atomically exchanges ``src`` with the value
> +The ``XCHG`` operation atomically exchanges ``src`` with the value
> addressed by ``dst + offset``.
>
> -The ``BPF_CMPXCHG`` operation atomically compares the value addressed by
> +The ``CMPXCHG`` operation atomically compares the value addressed by
> ``dst + offset`` with ``R0``. If they match, the value addressed by
> ``dst + offset`` is replaced with ``src``. In either case, the
> value that was at ``dst + offset`` before the operation is zero-extended
> @@ -600,25 +649,25 @@ and loaded back to ``R0``.
> 64-bit immediate instructions
> -----------------------------
>
> -Instructions with the ``BPF_IMM`` 'mode' modifier use the wide instruction
> +Instructions with the ``IMM`` 'mode' modifier use the wide instruction
> encoding defined in `Instruction encoding`_, and use the 'src_reg' field of the
> basic instruction to hold an opcode subtype.
>
> -The following table defines a set of ``BPF_IMM | BPF_DW | BPF_LD`` instructions
> +The following table defines a set of ``{IMM, DW, LD}`` instructions
> with opcode subtypes in the 'src_reg' field, using new terms such as "map"
> defined further below:
>
> -========================= ====== ======= ========================================= =========== ==============
> -opcode construction opcode src_reg pseudocode imm type dst type
> -========================= ====== ======= ========================================= =========== ==============
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x0 dst = (next_imm << 32) | imm integer integer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x1 dst = map_by_fd(imm) map fd map
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x3 dst = var_addr(imm) variable id data pointer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x4 dst = code_addr(imm) integer code pointer
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x5 dst = map_by_idx(imm) map index map
> -BPF_IMM | BPF_DW | BPF_LD 0x18 0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer
> -========================= ====== ======= ========================================= =========== ==============
> +======= ========================================= =========== ==============
> +src_reg pseudocode imm type dst type
> +======= ========================================= =========== ==============
> +0x0 dst = (next_imm << 32) | imm integer integer
> +0x1 dst = map_by_fd(imm) map fd map
> +0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer
> +0x3 dst = var_addr(imm) variable id data pointer
> +0x4 dst = code_addr(imm) integer code pointer
> +0x5 dst = map_by_idx(imm) map index map
> +0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer
> +======= ========================================= =========== ==============
>
> where
>
> @@ -657,8 +706,8 @@ Legacy BPF Packet access instructions
>
> BPF previously introduced special instructions for access to packet data that were
> carried over from classic BPF. These instructions used an instruction
> -class of BPF_LD, a size modifier of BPF_W, BPF_H, or BPF_B, and a
> -mode modifier of BPF_ABS or BPF_IND. The 'dst_reg' and 'offset' fields were
> -set to zero, and 'src_reg' was set to zero for BPF_ABS. However, these
> +class of ``LD``, a size modifier of ``W``, ``H``, or ``B``, and a
> +mode modifier of ``ABS`` or ``IND``. The 'dst_reg' and 'offset' fields were
> +set to zero, and 'src_reg' was set to zero for ``ABS``. However, these
> instructions are deprecated and should no longer be used. All legacy packet
> access instructions belong to the "legacy" conformance group.
> --
> 2.40.1
>
>
> --
> Bpf mailing list
> Bpf@ietf.org
> https://www.ietf.org/mailman/listinfo/bpf
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 76 bytes --]
--
Bpf mailing list
Bpf@ietf.org
https://www.ietf.org/mailman/listinfo/bpf
next prev parent reply other threads:[~2024-03-01 21:49 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-01 19:20 [PATCH bpf-next] bpf, docs: Use IETF format for field definitions in instruction-set.rst Dave Thaler
2024-03-01 19:20 ` [Bpf] " Dave Thaler
2024-03-01 21:49 ` David Vernet [this message]
2024-03-01 21:49 ` David Vernet
2024-03-01 21:55 ` dthaler1968
2024-03-01 21:55 ` dthaler1968=40googlemail.com
2024-03-01 22:04 ` David Vernet
2024-03-01 22:04 ` David Vernet
2024-03-01 22:17 ` Alexei Starovoitov
2024-03-01 22:17 ` Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240301214929.GB192865@maniforge \
--to=void@manifault.com \
--cc=bpf@ietf.org \
--cc=bpf@vger.kernel.org \
--cc=dthaler1968=40googlemail.com@dmarc.ietf.org \
--cc=dthaler1968@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox