From: "Jose E. Marchesi" <jose.marchesi@oracle.com>
To: David Vernet <void@manifault.com>
Cc: bpf <bpf@vger.kernel.org>,
Alexei Starovoitov <alexei.starovoitov@gmail.com>,
bpf@ietf.org
Subject: Re: [Bpf] [PATCH V2] bpf, docs: Document BPF insn encoding in term of stored bytes
Date: Mon, 27 Feb 2023 20:31:33 +0100 [thread overview]
Message-ID: <87bkle9a7e.fsf@oracle.com> (raw)
In-Reply-To: <Y/z9vtWfevaiRqtP@maniforge> (David Vernet's message of "Mon, 27 Feb 2023 13:00:14 -0600")
> On Mon, Feb 27, 2023 at 07:21:25PM +0100, Jose E. Marchesi wrote:
>>
>> [Differences from V1:
>> - Use rst literal blocks for figures.
>> - Avoid using | in the basic instruction/pseudo instruction figure.
>> - Rebased to today's bpf-next master branch.]
>>
>> This patch modifies instruction-set.rst so it documents the encoding
>> of BPF instructions in terms of how the bytes are stored (be it in an
>> ELF file or as bytes in a memory buffer to be loaded into the kernel
>> or some other BPF consumer) as opposed to how the instruction looks
>> like once loaded.
>>
>> This is hopefully easier to understand by implementors looking to
>> generate and/or consume bytes conforming BPF instructions.
>>
>> The patch also clarifies that the unused bytes in a pseudo-instruction
>> shall be cleared with zeros.
>>
>> Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
>
> Thanks Jose, this looks a lot better. Just left a couple more small
> suggestions + questions below before stamping.
>
>>
>> ---
>> Documentation/bpf/instruction-set.rst | 44 +++++++++++++--------------
>> 1 file changed, 22 insertions(+), 22 deletions(-)
>>
>> diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst
>> index 01802ed9b29b..3341bfe20e4d 100644
>> --- a/Documentation/bpf/instruction-set.rst
>> +++ b/Documentation/bpf/instruction-set.rst
>> @@ -38,15 +38,13 @@ eBPF has two instruction encodings:
>> * 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 basic instruction encoding looks as follows for a little-endian processor,
>> -where MSB and LSB mean the most significant bits and least significant bits,
>> -respectively:
>> +The fields conforming an encoded basic instruction are stored in the
>> +following order::
>>
>> -============= ======= ======= ======= ============
>> -32 bits (MSB) 16 bits 4 bits 4 bits 8 bits (LSB)
>> -============= ======= ======= ======= ============
>> -imm offset src_reg dst_reg opcode
>> -============= ======= ======= ======= ============
>> + opcode:8 src:4 dst:4 offset:16 imm:32 // In little-endian BPF.
>> + opcode:8 dst:4 src:4 offset:16 imm:32 // In big-endian BPF.
>
> The terms below use src_reg and dst_reg. Can we either update these code
> blocks to match, or change the term definitions to "src" and "dst"? I'd
> vote for the latter, given that we explain that it's the source /
> destination register number where they're defined.
Will change.
>> +
>> +Where,
>
> IMO, we can probably remove this "Where,". I think it's pretty clear
> that the following terms are referring to the code block above. Wdyt?
I added the "Where," to make the reading a little bit more fluid, but I
don't have a strong opinion on that.
>
>>
>> **imm**
>> signed integer immediate value
>> @@ -64,16 +62,17 @@ imm offset src_reg dst_reg opcode
>> **opcode**
>> operation to perform
>>
>> -and as follows for a big-endian processor:
>> +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.
>>
>> -============= ======= ======= ======= ============
>> -32 bits (MSB) 16 bits 4 bits 4 bits 8 bits (LSB)
>> -============= ======= ======= ======= ============
>> -imm offset dst_reg src_reg opcode
>> -============= ======= ======= ======= ============
>> +For example::
>>
>> -Multi-byte fields ('imm' and 'offset') are similarly stored in
>> -the byte order of the processor.
>> + opcode offset imm assembly
>> + src dst
>> + 07 0 1 00 00 44 33 22 11 r1 += 0x11223344 // little
>> + dst src
>> + 07 1 0 00 00 11 22 33 44 r1 += 0x11223344 // big
>>
>> Note that most instructions do not use all of the fields.
>> Unused fields shall be cleared to zero.
>> @@ -84,18 +83,19 @@ 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.
>>
>> -================= ==================
>> -64 bits (MSB) 64 bits (LSB)
>> -================= ==================
>> -basic instruction pseudo instruction
>> -================= ==================
>> +This is depicted in the following figure::
>> +
>> + basic_instruction pseudo instruction
>> + ------------------------------- ------------------
>> + code:8 regs:16 offset:16 imm:32 unused:32 imm:32
>
> Don't want to bikeshed too much, but this seems a bit hard to read. It
> kind of all looks like one line, though perhaps that was the intention.
> Wdyt about this?
>
> This is depicted in the following figure::
>
> code:8 regs:16 offset:16 imm:32 // MSB: basic instruction
> reserved:32 imm:32 // LSB: pseudo instruction
Hmm, yes, that was the intention, to depict the fact that a 128-bit
instruction is composed by the sequence of a basic instruction followed
by a pseudo instruction...
This would be the bombastic ASCII-art version of what I had in mind :)
basic_instruction
.-----------------------------.
| |
code:8 regs:16 offset:16 imm:32 unused:32 imm:32
| |
'--------------'
pseudo instruction
I don't think MSB and LSB marks are meaningful in this context. Bytes
in a file or in memory are no more or less significative: they just have
addresses (or file offsets) which can be lower or higher than the
addresses (or file offsets) of other bytes.
>>
>> Thus the 64-bit immediate value is constructed as follows:
>>
>> imm64 = (next_imm << 32) | imm
>>
>> where 'next_imm' refers to the imm value of the pseudo instruction
>> -following the basic instruction.
>> +following the basic instruction. The unused bytes in the pseudo
>> +instruction shall be cleared to zero.
>
> Also apologies if this is also a bikeshed and has already been
> discussed, but should we say, "The unused bits in the pseudo instruction
> are reserved" rather than saying they should be cleared to zero?
> Implemenations should interpret "reserved" to mean that the bits should
> be zeroed, no? Or at least that seems like the norm in technical
> manuals. For example, reserved bits in control registers on x86 should
> be cleared to avoid unexpected side effects if and when those bits are
> eventually actually used for something in future releases.
That is a good point.
I agree that "reserved" almost always means zero, but I think it is very
common to say so explicitly. A couple of examples:
Example 1, from the x86 MBR spec:
* Offset Size (bytes) Description
*
* 0x000 440 MBR Bootstrap (flat binary executable code)
* 0x1B8 4 Optional "Unique Disk ID / Signature"
* 0x1BC 2 Optional, reserved 0x0000
* 0x1BE 16 First partition table entry
* 0x1CE 16 Second partition table entry
* 0x1DE 16 Third partition table entry
* 0x1EE 16 Fourth partition table entry
* 0x1FE 2 (0x55, 0xAA) "Valid bootsector" signature bytes
Example 2, this is how the PE Object File specification defines a
reserved field:
reserved, A description of a field that indicates that the value
must be 0 of the field must be zero for generators and consumers
must ignore the field.
What about this: "The unused bits in the pseudo instruction are reserved
and shall be cleared to zero."
next prev parent reply other threads:[~2023-02-27 19:31 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-27 18:21 [PATCH V2] bpf, docs: Document BPF insn encoding in term of stored bytes Jose E. Marchesi
2023-02-27 19:00 ` David Vernet
2023-02-27 19:31 ` Jose E. Marchesi [this message]
2023-02-27 20:01 ` [Bpf] " David Vernet
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=87bkle9a7e.fsf@oracle.com \
--to=jose.marchesi@oracle.com \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@ietf.org \
--cc=bpf@vger.kernel.org \
--cc=void@manifault.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