From: David Vernet <void@manifault.com>
To: "Jose E. Marchesi" <jose.marchesi@oracle.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 14:01:37 -0600 [thread overview]
Message-ID: <Y/0MIXoJ9h+8ASXr@maniforge> (raw)
In-Reply-To: <87bkle9a7e.fsf@oracle.com>
On Mon, Feb 27, 2023 at 08:31:33PM +0100, Jose E. Marchesi wrote:
>
> > 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
Oh man, I love ASCII-art, bombastic or not. I personally prefer this
over the single-line version, but I think either way is fine. It's
pretty clear what it's conveying.
>
> 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.
Fair enough, let's leave off MSB / LSB.
> >>
> >> 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:
Someone should standardize how manuals describe reserved bits ;-)
> 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."
Sounds good to me!
Thanks,
David
prev parent reply other threads:[~2023-02-27 20:01 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 ` [Bpf] " Jose E. Marchesi
2023-02-27 20:01 ` David Vernet [this message]
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=Y/0MIXoJ9h+8ASXr@maniforge \
--to=void@manifault.com \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@ietf.org \
--cc=bpf@vger.kernel.org \
--cc=jose.marchesi@oracle.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