diff mbox series

[bpf-next,v2] bpf, docs: Add callx instructions in new conformance group

Message ID 20240212211310.8282-1-dthaler1968@gmail.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series [bpf-next,v2] bpf, docs: Add callx instructions in new conformance group | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
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/build_tools success No tools touched, skip
netdev/cc_maintainers warning 15 maintainers not CCed: ast@kernel.org daniel@iogearbox.net john.fastabend@gmail.com jolsa@kernel.org linux-doc@vger.kernel.org yonghong.song@linux.dev andrii@kernel.org song@kernel.org martin.lau@linux.dev sdf@google.com void@manifault.com corbet@lwn.net eddyz87@gmail.com kpsingh@kernel.org haoluo@google.com
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 warning WARNING: From:/Signed-off-by: email address mismatch: 'From: Dave Thaler <dthaler1968@googlemail.com>' != 'Signed-off-by: Dave Thaler <dthaler1968@gmail.com>'
netdev/build_clang_rust success No Rust files in patch. Skipping build
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-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-18 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18 and -O2 optimization
bpf/vmtest-bpf-next-VM_Test-42 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17 and -O2 optimization
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_maps, false, 360) / test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc

Commit Message

Dave Thaler Feb. 12, 2024, 9:13 p.m. UTC
* Add a "callx" conformance group
* Add callx rows to table
* Update helper function to section to be agnostic between BPF_K vs
  BPF_X
* Rename "legacy" conformance group to "packet"

Based on mailing list discussion at
https://mailarchive.ietf.org/arch/msg/bpf/l5tNEgL-Wo7qSEuaGssOl5VChKk/

v1->v2: Incorporated feedback from Will Hawkins

Signed-off-by: Dave Thaler <dthaler1968@gmail.com>
---
 .../bpf/standardization/instruction-set.rst   | 32 ++++++++++++-------
 1 file changed, 21 insertions(+), 11 deletions(-)

Comments

David Vernet Feb. 12, 2024, 9:21 p.m. UTC | #1
On Mon, Feb 12, 2024 at 01:13:10PM -0800, Dave Thaler wrote:
> * Add a "callx" conformance group
> * Add callx rows to table
> * Update helper function to section to be agnostic between BPF_K vs
>   BPF_X
> * Rename "legacy" conformance group to "packet"
> 
> Based on mailing list discussion at
> https://mailarchive.ietf.org/arch/msg/bpf/l5tNEgL-Wo7qSEuaGssOl5VChKk/
> 
> v1->v2: Incorporated feedback from Will Hawkins
> 
> Signed-off-by: Dave Thaler <dthaler1968@gmail.com>

Acked-by: David Vernet <void@manifault.com>
Jose E. Marchesi Feb. 12, 2024, 9:28 p.m. UTC | #2
> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X only, see `Program-local functions`_

If the instruction requires a register operand, why not using one of the
register fields?  Is there any reason for not doing that?
Dave Thaler Feb. 12, 2024, 9:46 p.m. UTC | #3
Jose E. Marchesi <jose.marchesi@oracle.com> writes:
> > +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X
only,
> see `Program-local functions`_
> 
> If the instruction requires a register operand, why not using one of the
> register fields?  Is there any reason for not doing that?

Yeah, the reason is because this is document what clang has done by default
for a long time now.  The IETF WG charter says:

> The BPF working group is initially tasked with documenting the existing
> state of the BPF ecosystem

So extensions can always add new instructions and deprecate old ones
but the initial version of the ISA needs to document "the existing state
of the BPF ecosystem".  I know gcc used a different field but one has to
go out of your way to specify a command line option to get that to happen,
whereas clang uses callx as documented when you don't do -O2, without
requiring any extra command line options.

I agree with you that it would have been better to use the src register
since the BPF_X bit is supposed to mean that, but that ship apparently
sailed long ago with clang.

Dave
Yonghong Song Feb. 12, 2024, 9:49 p.m. UTC | #4
On 2/12/24 1:28 PM, Jose E. Marchesi wrote:
>> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X only, see `Program-local functions`_
> If the instruction requires a register operand, why not using one of the
> register fields?  Is there any reason for not doing that?

Talked to Alexei and we think using dst_reg for the register for callx 
insn is better. I will craft a llvm patch for this today. Thanks!
Dave Thaler Feb. 12, 2024, 9:52 p.m. UTC | #5
> -----Original Message-----
> From: Yonghong Song <yonghong.song@linux.dev>
> Sent: Monday, February 12, 2024 1:49 PM
> To: Jose E. Marchesi <jose.marchesi@oracle.com>; 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 v2] bpf, docs: Add callx instructions in new
> conformance group
> 
> 
> On 2/12/24 1:28 PM, Jose E. Marchesi wrote:
> >> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X
> only, see `Program-local functions`_
> > If the instruction requires a register operand, why not using one of
> > the register fields?  Is there any reason for not doing that?
> 
> Talked to Alexei and we think using dst_reg for the register for callx insn is
> better. I will craft a llvm patch for this today. Thanks!

Why dst_reg instead of src_reg?
BPF_X is supposed to mean use src_reg.

But this thread is about reserving/documenting the existing practice,
since anyone trying to use it would run into interop issues because
of existing clang.   Should we document both and list one as deprecated?

Dave
Yonghong Song Feb. 12, 2024, 10:48 p.m. UTC | #6
On 2/12/24 1:52 PM, dthaler1968@googlemail.com wrote:
>> -----Original Message-----
>> From: Yonghong Song <yonghong.song@linux.dev>
>> Sent: Monday, February 12, 2024 1:49 PM
>> To: Jose E. Marchesi <jose.marchesi@oracle.com>; 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 v2] bpf, docs: Add callx instructions in new
>> conformance group
>>
>>
>> On 2/12/24 1:28 PM, Jose E. Marchesi wrote:
>>>> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X
>> only, see `Program-local functions`_
>>> If the instruction requires a register operand, why not using one of
>>> the register fields?  Is there any reason for not doing that?
>> Talked to Alexei and we think using dst_reg for the register for callx insn is
>> better. I will craft a llvm patch for this today. Thanks!
> Why dst_reg instead of src_reg?
> BPF_X is supposed to mean use src_reg.

Let us use dst_reg. Currently, for BPF_K, we have src_reg for a bunch
of flags (pseudo call, kfunc call, etc.). So for BPF_X, let us preserve this
property as well in case in the future we will introduce variants for
callx. The following is the llvm diff:

https://github.com/llvm/llvm-project/pull/81546

>
> But this thread is about reserving/documenting the existing practice,
> since anyone trying to use it would run into interop issues because
> of existing clang.   Should we document both and list one as deprecated?

I think just documenting the new encoding is good enough. But other
people can chime in just in case that I missed something.

>
> Dave
>
Dave Thaler Feb. 13, 2024, 1:18 a.m. UTC | #7
> -----Original Message-----
> From: Yonghong Song <yonghong.song@linux.dev>
> Sent: Monday, February 12, 2024 2:49 PM
> To: dthaler1968@googlemail.com; 'Jose E. Marchesi'
> <jose.marchesi@oracle.com>; 'Dave Thaler'
> <dthaler1968=40googlemail.com@dmarc.ietf.org>
> Cc: bpf@vger.kernel.org; bpf@ietf.org
> Subject: Re: [Bpf] [PATCH bpf-next v2] bpf, docs: Add callx instructions in new
> conformance group
> 
> 
> On 2/12/24 1:52 PM, dthaler1968@googlemail.com wrote:
> >> -----Original Message-----
> >> From: Yonghong Song <yonghong.song@linux.dev>
> >> Sent: Monday, February 12, 2024 1:49 PM
> >> To: Jose E. Marchesi <jose.marchesi@oracle.com>; 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 v2] bpf, docs: Add callx
> >> instructions in new conformance group
> >>
> >>
> >> On 2/12/24 1:28 PM, Jose E. Marchesi wrote:
> >>>> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X
> >> only, see `Program-local functions`_
> >>> If the instruction requires a register operand, why not using one of
> >>> the register fields?  Is there any reason for not doing that?
> >> Talked to Alexei and we think using dst_reg for the register for
> >> callx insn is better. I will craft a llvm patch for this today. Thanks!
> > Why dst_reg instead of src_reg?
> > BPF_X is supposed to mean use src_reg.
> 
> Let us use dst_reg. Currently, for BPF_K, we have src_reg for a bunch of flags
> (pseudo call, kfunc call, etc.). So for BPF_X, let us preserve this property as
> well in case in the future we will introduce variants for callx.

Ah yes, that makes sense.

> The following is the llvm diff:
> 
> https://github.com/llvm/llvm-project/pull/81546

Which llvm release is it targeted for?
18.1.0-rc3? 18.1.1?  later?

> > But this thread is about reserving/documenting the existing practice,
> > since anyone trying to use it would run into interop issues because
> > of existing clang.   Should we document both and list one as deprecated?
> 
> I think just documenting the new encoding is good enough. But other
> people can chime in just in case that I missed something.

Ok.

Dave
Yonghong Song Feb. 13, 2024, 1:23 a.m. UTC | #8
On 2/12/24 5:18 PM, dthaler1968@googlemail.com wrote:
>> -----Original Message-----
>> From: Yonghong Song <yonghong.song@linux.dev>
>> Sent: Monday, February 12, 2024 2:49 PM
>> To: dthaler1968@googlemail.com; 'Jose E. Marchesi'
>> <jose.marchesi@oracle.com>; 'Dave Thaler'
>> <dthaler1968=40googlemail.com@dmarc.ietf.org>
>> Cc: bpf@vger.kernel.org; bpf@ietf.org
>> Subject: Re: [Bpf] [PATCH bpf-next v2] bpf, docs: Add callx instructions in new
>> conformance group
>>
>>
>> On 2/12/24 1:52 PM, dthaler1968@googlemail.com wrote:
>>>> -----Original Message-----
>>>> From: Yonghong Song <yonghong.song@linux.dev>
>>>> Sent: Monday, February 12, 2024 1:49 PM
>>>> To: Jose E. Marchesi <jose.marchesi@oracle.com>; 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 v2] bpf, docs: Add callx
>>>> instructions in new conformance group
>>>>
>>>>
>>>> On 2/12/24 1:28 PM, Jose E. Marchesi wrote:
>>>>>> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X
>>>> only, see `Program-local functions`_
>>>>> If the instruction requires a register operand, why not using one of
>>>>> the register fields?  Is there any reason for not doing that?
>>>> Talked to Alexei and we think using dst_reg for the register for
>>>> callx insn is better. I will craft a llvm patch for this today. Thanks!
>>> Why dst_reg instead of src_reg?
>>> BPF_X is supposed to mean use src_reg.
>> Let us use dst_reg. Currently, for BPF_K, we have src_reg for a bunch of flags
>> (pseudo call, kfunc call, etc.). So for BPF_X, let us preserve this property as
>> well in case in the future we will introduce variants for callx.
> Ah yes, that makes sense.
>
>> The following is the llvm diff:
>>
>> https://github.com/llvm/llvm-project/pull/81546
> Which llvm release is it targeted for?
> 18.1.0-rc3? 18.1.1?  later?

llvm19

>
>>> But this thread is about reserving/documenting the existing practice,
>>> since anyone trying to use it would run into interop issues because
>>> of existing clang.   Should we document both and list one as deprecated?
>> I think just documenting the new encoding is good enough. But other
>> people can chime in just in case that I missed something.
> Ok.
>
> Dave
>
Jose E. Marchesi Feb. 13, 2024, 6:11 a.m. UTC | #9
> On 2/12/24 1:52 PM, dthaler1968@googlemail.com wrote:
>>> -----Original Message-----
>>> From: Yonghong Song <yonghong.song@linux.dev>
>>> Sent: Monday, February 12, 2024 1:49 PM
>>> To: Jose E. Marchesi <jose.marchesi@oracle.com>; 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 v2] bpf, docs: Add callx instructions in new
>>> conformance group
>>>
>>>
>>> On 2/12/24 1:28 PM, Jose E. Marchesi wrote:
>>>>> +BPF_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X
>>> only, see `Program-local functions`_
>>>> If the instruction requires a register operand, why not using one of
>>>> the register fields?  Is there any reason for not doing that?
>>> Talked to Alexei and we think using dst_reg for the register for callx insn is
>>> better. I will craft a llvm patch for this today. Thanks!
>> Why dst_reg instead of src_reg?
>> BPF_X is supposed to mean use src_reg.
>
> Let us use dst_reg. Currently, for BPF_K, we have src_reg for a bunch
> of flags (pseudo call, kfunc call, etc.). So for BPF_X, let us preserve this
> property as well in case in the future we will introduce variants for
> callx. The following is the llvm diff:
>
> https://github.com/llvm/llvm-project/pull/81546

Thank you.

I believe Will will be sending a patch to binutils to change the
pseudo-C syntax for the instruction to callx instead of callr.  We will
then adapt GCC accordingly, and both compilers will be doing exactly the
same regarding callx.

>>
>> But this thread is about reserving/documenting the existing practice,
>> since anyone trying to use it would run into interop issues because
>> of existing clang.   Should we document both and list one as deprecated?
>
> I think just documenting the new encoding is good enough. But other
> people can chime in just in case that I missed something.
>
>>
>> Dave
>>
diff mbox series

Patch

diff --git a/Documentation/bpf/standardization/instruction-set.rst b/Documentation/bpf/standardization/instruction-set.rst
index bdfe0cd0e..9861bac6b 100644
--- a/Documentation/bpf/standardization/instruction-set.rst
+++ b/Documentation/bpf/standardization/instruction-set.rst
@@ -127,7 +127,7 @@  This document defines the following conformance groups:
 * divmul32: includes 32-bit division, multiplication, and modulo instructions.
 * divmul64: includes divmul32, plus 64-bit division, multiplication,
   and modulo instructions.
-* legacy: deprecated packet access instructions.
+* packet: deprecated packet access instructions.
 
 Instruction encoding
 ====================
@@ -404,9 +404,12 @@  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    0x0  call_by_address(imm)             BPF_JMP | BPF_K only
+BPF_CALL  0x8    0x0  call_by_address(reg_val(imm))    BPF_JMP | BPF_X only
 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_CALL  0x8    0x1  call PC += reg_val(imm)          BPF_JMP | BPF_X only, see `Program-local functions`_
+BPF_CALL  0x8    0x2  call_by_btfid(imm)               BPF_JMP | BPF_K only
+BPF_CALL  0x8    0x2  call_by_btfid(reg_val(imm))      BPF_JMP | BPF_X only
 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
@@ -414,6 +417,12 @@  BPF_JSLT  0xc    any  PC += offset if dst < src        signed
 BPF_JSLE  0xd    any  PC += offset if dst <= src       signed
 ========  =====  ===  ===============================  =============================================
 
+where
+
+* reg_val(imm) gets the value of the register specified by 'imm'
+* call_by_address(value) means to call a helper function by the address specified by 'value' (see `Helper functions`_ for details)
+* call_by_btfid(value) means to call a helper function by the BTF ID specified by 'value' (see `Helper functions`_ for details)
+
 The BPF program needs to store the return value into register R0 before doing a
 ``BPF_EXIT``.
 
@@ -438,8 +447,9 @@  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
-base32 conformance group.
+All ``BPF_CALL | BPF_X`` instructions belong to the callx
+conformance group.  All other ``BPF_CALL`` instructions and all
+``BPF_JA`` instructions belong to the base32 conformance group.
 
 Helper functions
 ~~~~~~~~~~~~~~~~
@@ -447,13 +457,13 @@  Helper functions
 Helper functions are a concept whereby BPF programs can call into a
 set of function calls exposed by the underlying platform.
 
-Historically, each helper function was identified by an address
-encoded in the imm field.  The available helper functions may differ
-for each program type, but address values are unique across all program types.
+Historically, each helper function was identified by an address.
+The available helper functions may differ for each program type,
+but address values are unique across all program types.
 
 Platforms that support the BPF Type Format (BTF) support identifying
-a helper function by a BTF ID encoded in the imm field, where the BTF ID
-identifies the helper name and type.
+a helper function by a BTF ID, where the BTF ID identifies the helper
+name and type.
 
 Program-local functions
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -660,4 +670,4 @@  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.  However, these instructions are
 deprecated and should no longer be used.  All legacy packet access
-instructions belong to the "legacy" conformance group.
+instructions belong to the "packet" conformance group.