diff mbox series

[bpf-next] Shift operations are defined to use a mask

Message ID 20230509180845.1236-1-dthaler1968@googlemail.com (mailing list archive)
State Accepted
Commit 8819495a754e71d3c3fde991c26ad832af995136
Delegated to: BPF
Headers show
Series [bpf-next] Shift operations are defined to use a mask | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers warning 14 maintainers not CCed: void@manifault.com daniel@iogearbox.net yhs@fb.com kpsingh@kernel.org martin.lau@linux.dev john.fastabend@gmail.com song@kernel.org sdf@google.com andrii@kernel.org corbet@lwn.net jolsa@kernel.org haoluo@google.com ast@kernel.org linux-doc@vger.kernel.org
netdev/build_clang success Errors and warnings before: 8 this patch: 8
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 25 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32 on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_no_alu32_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_progs_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-29 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-32 success Logs for test_verifier on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-34 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-35 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-36 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-33 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-20 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain_full }}
bpf/vmtest-bpf-next-VM_Test-2 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 fail Logs for build for aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-8 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-9 success Logs for veristat

Commit Message

Dave Thaler May 9, 2023, 6:08 p.m. UTC
From: Dave Thaler <dthaler@microsoft.com>

Update the documentation regarding shift operations to explain the
use of a mask, since otherwise shifting by a value out of range
(like negative) is undefined.

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
---
 Documentation/bpf/instruction-set.rst | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Comments

Yonghong Song May 10, 2023, 1:34 p.m. UTC | #1
On 5/9/23 11:08 AM, Dave Thaler wrote:
> From: Dave Thaler <dthaler@microsoft.com>
> 
> Update the documentation regarding shift operations to explain the
> use of a mask, since otherwise shifting by a value out of range
> (like negative) is undefined.
> 
> Signed-off-by: Dave Thaler <dthaler@microsoft.com>

LGTM with a few nit below.

Acked-by: Yonghong Song <yhs@fb.com>

> ---
>   Documentation/bpf/instruction-set.rst | 9 ++++++---
>   1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst
> index 492980ece1a..6644842cd3e 100644
> --- a/Documentation/bpf/instruction-set.rst
> +++ b/Documentation/bpf/instruction-set.rst
> @@ -163,13 +163,13 @@ BPF_MUL   0x20   dst \*= src
>   BPF_DIV   0x30   dst = (src != 0) ? (dst / src) : 0
>   BPF_OR    0x40   dst \|= src
>   BPF_AND   0x50   dst &= src
> -BPF_LSH   0x60   dst <<= src
> -BPF_RSH   0x70   dst >>= src
> +BPF_LSH   0x60   dst <<= (src & mask)
> +BPF_RSH   0x70   dst >>= (src & mask)
>   BPF_NEG   0x80   dst = ~src
>   BPF_MOD   0x90   dst = (src != 0) ? (dst % src) : dst
>   BPF_XOR   0xa0   dst ^= src
>   BPF_MOV   0xb0   dst = src
> -BPF_ARSH  0xc0   sign extending shift right
> +BPF_ARSH  0xc0   sign extending dst >>= (src & mask)

		    dst s>>= (src & mask)
?

>   BPF_END   0xd0   byte swap operations (see `Byte swap instructions`_ below)
>   ========  =====  ==========================================================
>   
> @@ -204,6 +204,9 @@ for ``BPF_ALU64``, 'imm' is first sign extended to 64 bits and the result
>   interpreted as an unsigned 64-bit value. There are no instructions for
>   signed division or modulo.
>   
> +Shift operations use a mask of 0x3F (63) for 64-bit operations and 0x1F (31)
> +for 32-bit operations.
> +
>   Byte swap instructions
>   ~~~~~~~~~~~~~~~~~~~~~~
>
Dave Thaler May 10, 2023, 3:45 p.m. UTC | #2
Yonghong Song <yhs@meta.com> wrote:
> On 5/9/23 11:08 AM, Dave Thaler wrote:
> > From: Dave Thaler <dthaler@microsoft.com>
> >
> > Update the documentation regarding shift operations to explain the use
> > of a mask, since otherwise shifting by a value out of range (like
> > negative) is undefined.
> >
> > Signed-off-by: Dave Thaler <dthaler@microsoft.com>
> 
> LGTM with a few nit below.
> 
> Acked-by: Yonghong Song <yhs@fb.com>
[...]
> > -BPF_ARSH  0xc0   sign extending shift right
> > +BPF_ARSH  0xc0   sign extending dst >>= (src & mask)
> 
> 		    dst s>>= (src & mask)
> ?

I had thought about that, but based on Jose's LSF/MM/BPF 
presentation yesterday there are multiple such syntaxes.

">>=" vs "s>>=" is only one of several.  There's ">>" vs ">>>",
there's assembly-like, etc.   So I thought that it would take
more text to define "s>>" as meaning signing extending right
shift, than just saying sign extending ">>=" here.  And I didn't
want to just assume the reader knows what "s>>" means
without defining it since neither the C standard nor gcc use
"s>>".

Thanks for the Ack.

Dave
Yonghong Song May 10, 2023, 11:28 p.m. UTC | #3
On 5/10/23 8:45 AM, Dave Thaler wrote:
> Yonghong Song <yhs@meta.com> wrote:
>> On 5/9/23 11:08 AM, Dave Thaler wrote:
>>> From: Dave Thaler <dthaler@microsoft.com>
>>>
>>> Update the documentation regarding shift operations to explain the use
>>> of a mask, since otherwise shifting by a value out of range (like
>>> negative) is undefined.
>>>
>>> Signed-off-by: Dave Thaler <dthaler@microsoft.com>
>>
>> LGTM with a few nit below.
>>
>> Acked-by: Yonghong Song <yhs@fb.com>
> [...]
>>> -BPF_ARSH  0xc0   sign extending shift right
>>> +BPF_ARSH  0xc0   sign extending dst >>= (src & mask)
>>
>> 		    dst s>>= (src & mask)
>> ?
> 
> I had thought about that, but based on Jose's LSF/MM/BPF
> presentation yesterday there are multiple such syntaxes.
> 
> ">>=" vs "s>>=" is only one of several.  There's ">>" vs ">>>",
> there's assembly-like, etc.   So I thought that it would take
> more text to define "s>>" as meaning signing extending right
> shift, than just saying sign extending ">>=" here.  And I didn't
> want to just assume the reader knows what "s>>" means
> without defining it since neither the C standard nor gcc use
> "s>>".

gcc will implement clang asm syntax as well. So for the consistency
of verifier log, bpftool xlated dump, and llvm-objdump result.
I think using "s>>=" syntax is the best.

The following table is the alu opcode in kernel/bpf/disasm.c
(used by both kernel verifier and bpftool xlated dump):

const char *const bpf_alu_string[16] = {
         [BPF_ADD >> 4]  = "+=",
         [BPF_SUB >> 4]  = "-=",
         [BPF_MUL >> 4]  = "*=",
         [BPF_DIV >> 4]  = "/=",
         [BPF_OR  >> 4]  = "|=",
         [BPF_AND >> 4]  = "&=",
         [BPF_LSH >> 4]  = "<<=",
         [BPF_RSH >> 4]  = ">>=",
         [BPF_NEG >> 4]  = "neg",
         [BPF_MOD >> 4]  = "%=",
         [BPF_XOR >> 4]  = "^=",
         [BPF_MOV >> 4]  = "=",
         [BPF_ARSH >> 4] = "s>>=",
         [BPF_END >> 4]  = "endian",
};

Also, in Documentation/bpf/instruction-set.rst:

========  =====  ==========================================================
code      value  description
========  =====  ==========================================================
BPF_ADD   0x00   dst += src
BPF_SUB   0x10   dst -= src
BPF_MUL   0x20   dst \*= src
BPF_DIV   0x30   dst = (src != 0) ? (dst / src) : 0
BPF_OR    0x40   dst \|= src
BPF_AND   0x50   dst &= src
BPF_LSH   0x60   dst <<= src
BPF_RSH   0x70   dst >>= src
BPF_NEG   0x80   dst = ~src
BPF_MOD   0x90   dst = (src != 0) ? (dst % src) : dst
BPF_XOR   0xa0   dst ^= src
BPF_MOV   0xb0   dst = src
BPF_ARSH  0xc0   sign extending shift right
BPF_END   0xd0   byte swap operations (see `Byte swap instructions`_ below)
========  =====  ==========================================================

In the above, the BPF_NEG is specified as
'dst = ~src`, which is not correct, it should be
'dst = -dst'.

See kernel/bpf/core.c:
         ALU_NEG:
                 DST = (u32) -DST;
                 CONT;
         ALU64_NEG:
                 DST = -DST;
                 CONT;

Could you help fix it?

> 
> Thanks for the Ack.
> 
> Dave
>
Dave Thaler May 11, 2023, 3:31 a.m. UTC | #4
Yonghong Song <yhs@meta.com> wrote: 
> On 5/10/23 8:45 AM, Dave Thaler wrote:
> > Yonghong Song <yhs@meta.com> wrote:
> >> On 5/9/23 11:08 AM, Dave Thaler wrote:
> >>> From: Dave Thaler <dthaler@microsoft.com>
> >>>
> >>> Update the documentation regarding shift operations to explain the
> >>> use of a mask, since otherwise shifting by a value out of range
> >>> (like
> >>> negative) is undefined.
> >>>
> >>> Signed-off-by: Dave Thaler <dthaler@microsoft.com>
> >>
> >> LGTM with a few nit below.
> >>
> >> Acked-by: Yonghong Song <yhs@fb.com>
> > [...]
> >>> -BPF_ARSH  0xc0   sign extending shift right
> >>> +BPF_ARSH  0xc0   sign extending dst >>= (src & mask)
> >>
> >> 		    dst s>>= (src & mask)
> >> ?
> >
> > I had thought about that, but based on Jose's LSF/MM/BPF presentation
> > yesterday there are multiple such syntaxes.
> >
> > ">>=" vs "s>>=" is only one of several.  There's ">>" vs ">>>",
> > there's assembly-like, etc.   So I thought that it would take
> > more text to define "s>>" as meaning signing extending right shift,
> > than just saying sign extending ">>=" here.  And I didn't want to just
> > assume the reader knows what "s>>" means without defining it since
> > neither the C standard nor gcc use "s>>".
> 
> gcc will implement clang asm syntax as well. So for the consistency of verifier
> log, bpftool xlated dump, and llvm-objdump result.
> I think using "s>>=" syntax is the best.

Just posting to the list what we discussed in person today.
I will do this in a subsequent submission since that comment also affects
the comparison operators, so treating it as separate from this patch.

> The following table is the alu opcode in kernel/bpf/disasm.c (used by both
> kernel verifier and bpftool xlated dump):
> 
> const char *const bpf_alu_string[16] = {
>          [BPF_ADD >> 4]  = "+=",
>          [BPF_SUB >> 4]  = "-=",
>          [BPF_MUL >> 4]  = "*=",
>          [BPF_DIV >> 4]  = "/=",
>          [BPF_OR  >> 4]  = "|=",
>          [BPF_AND >> 4]  = "&=",
>          [BPF_LSH >> 4]  = "<<=",
>          [BPF_RSH >> 4]  = ">>=",
>          [BPF_NEG >> 4]  = "neg",
>          [BPF_MOD >> 4]  = "%=",
>          [BPF_XOR >> 4]  = "^=",
>          [BPF_MOV >> 4]  = "=",
>          [BPF_ARSH >> 4] = "s>>=",
>          [BPF_END >> 4]  = "endian",
> };
> 
> Also, in Documentation/bpf/instruction-set.rst:
> 
> ========  =====
> ==========================================================
> code      value  description
> ========  =====
> ==========================================================
> BPF_ADD   0x00   dst += src
> BPF_SUB   0x10   dst -= src
> BPF_MUL   0x20   dst \*= src
> BPF_DIV   0x30   dst = (src != 0) ? (dst / src) : 0
> BPF_OR    0x40   dst \|= src
> BPF_AND   0x50   dst &= src
> BPF_LSH   0x60   dst <<= src
> BPF_RSH   0x70   dst >>= src
> BPF_NEG   0x80   dst = ~src
> BPF_MOD   0x90   dst = (src != 0) ? (dst % src) : dst
> BPF_XOR   0xa0   dst ^= src
> BPF_MOV   0xb0   dst = src
> BPF_ARSH  0xc0   sign extending shift right
> BPF_END   0xd0   byte swap operations (see `Byte swap instructions`_ below)
> ========  =====
> ==========================================================
> 
> In the above, the BPF_NEG is specified as 'dst = ~src`, which is not correct, it
> should be 'dst = -dst'.
> 
> See kernel/bpf/core.c:
>          ALU_NEG:
>                  DST = (u32) -DST;
>                  CONT;
>          ALU64_NEG:
>                  DST = -DST;
>                  CONT;
> 
> Could you help fix it?

Yes I can put it into the same patch as the other change
discussed above.

Would like to see the current one merged so I can base
the next one on top of this one.

Thanks,
Dave
patchwork-bot+netdevbpf@kernel.org May 17, 2023, 2:30 p.m. UTC | #5
Hello:

This patch was applied to bpf/bpf-next.git (master)
by Daniel Borkmann <daniel@iogearbox.net>:

On Tue,  9 May 2023 18:08:45 +0000 you wrote:
> From: Dave Thaler <dthaler@microsoft.com>
> 
> Update the documentation regarding shift operations to explain the
> use of a mask, since otherwise shifting by a value out of range
> (like negative) is undefined.
> 
> Signed-off-by: Dave Thaler <dthaler@microsoft.com>
> 
> [...]

Here is the summary with links:
  - [bpf-next] Shift operations are defined to use a mask
    https://git.kernel.org/bpf/bpf-next/c/8819495a754e

You are awesome, thank you!
diff mbox series

Patch

diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst
index 492980ece1a..6644842cd3e 100644
--- a/Documentation/bpf/instruction-set.rst
+++ b/Documentation/bpf/instruction-set.rst
@@ -163,13 +163,13 @@  BPF_MUL   0x20   dst \*= src
 BPF_DIV   0x30   dst = (src != 0) ? (dst / src) : 0
 BPF_OR    0x40   dst \|= src
 BPF_AND   0x50   dst &= src
-BPF_LSH   0x60   dst <<= src
-BPF_RSH   0x70   dst >>= src
+BPF_LSH   0x60   dst <<= (src & mask)
+BPF_RSH   0x70   dst >>= (src & mask)
 BPF_NEG   0x80   dst = ~src
 BPF_MOD   0x90   dst = (src != 0) ? (dst % src) : dst
 BPF_XOR   0xa0   dst ^= src
 BPF_MOV   0xb0   dst = src
-BPF_ARSH  0xc0   sign extending shift right
+BPF_ARSH  0xc0   sign extending dst >>= (src & mask)
 BPF_END   0xd0   byte swap operations (see `Byte swap instructions`_ below)
 ========  =====  ==========================================================
 
@@ -204,6 +204,9 @@  for ``BPF_ALU64``, 'imm' is first sign extended to 64 bits and the result
 interpreted as an unsigned 64-bit value. There are no instructions for
 signed division or modulo.
 
+Shift operations use a mask of 0x3F (63) for 64-bit operations and 0x1F (31)
+for 32-bit operations.
+
 Byte swap instructions
 ~~~~~~~~~~~~~~~~~~~~~~