diff mbox series

[bpf-next,v2] bpf, docs: Explain helper functions

Message ID 20230206191647.2075-1-dthaler1968@googlemail.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series [bpf-next,v2] bpf, docs: Explain helper functions | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers fail 17 maintainers not CCed: john.fastabend@gmail.com ast@kernel.org llvm@lists.linux.dev daniel@iogearbox.net sdf@google.com andrii@kernel.org corbet@lwn.net linux-doc@vger.kernel.org trix@redhat.com jolsa@kernel.org song@kernel.org martin.lau@linux.dev haoluo@google.com yhs@fb.com ndesaulniers@google.com nathan@kernel.org kpsingh@kernel.org
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
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: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 45 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-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 pending Logs for test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs on aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 pending Logs for test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32 on aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 pending Logs for test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_progs_no_alu32_parallel on aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_progs_no_alu32_parallel on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-29 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_progs_parallel on aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-32 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-34 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-35 success Logs for test_verifier on aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-36 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-37 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-38 pending Logs for test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_progs_parallel on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-33 success Logs for test_progs_parallel on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_maps on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain }}
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 success Logs for build for aarch64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-5 fail 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-17
bpf/vmtest-bpf-next-VM_Test-8 success Logs for llvm-toolchain
bpf/vmtest-bpf-next-VM_Test-9 success Logs for set-matrix

Commit Message

Dave Thaler Feb. 6, 2023, 7:16 p.m. UTC
From: Dave Thaler <dthaler@microsoft.com>

Add text explaining helper functions.
Note that text about runtime functions (kfuncs) is part of a separate patch,
not this one.

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
---
V1 -> V2: addressed comments from Alexei and Stanislav
---
 Documentation/bpf/clang-notes.rst     |  5 +++++
 Documentation/bpf/instruction-set.rst | 22 +++++++++++++++++++++-
 2 files changed, 26 insertions(+), 1 deletion(-)

Comments

David Vernet Feb. 8, 2023, 3:10 p.m. UTC | #1
On Mon, Feb 06, 2023 at 07:16:47PM +0000, Dave Thaler wrote:
> From: Dave Thaler <dthaler@microsoft.com>
> 
> Add text explaining helper functions.
> Note that text about runtime functions (kfuncs) is part of a separate patch,
> not this one.
> 
> Signed-off-by: Dave Thaler <dthaler@microsoft.com>
> ---
> V1 -> V2: addressed comments from Alexei and Stanislav
> ---
>  Documentation/bpf/clang-notes.rst     |  5 +++++
>  Documentation/bpf/instruction-set.rst | 22 +++++++++++++++++++++-
>  2 files changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/bpf/clang-notes.rst b/Documentation/bpf/clang-notes.rst
> index 528feddf2db..40c6185513a 100644
> --- a/Documentation/bpf/clang-notes.rst
> +++ b/Documentation/bpf/clang-notes.rst
> @@ -20,6 +20,11 @@ Arithmetic instructions
>  For CPU versions prior to 3, Clang v7.0 and later can enable ``BPF_ALU`` support with
>  ``-Xclang -target-feature -Xclang +alu32``.  In CPU version 3, support is automatically included.
>  
> +Reserved instructions
> +====================

small nit: Missing a =

> +
> +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d) instruction if ``-O0`` is used.

Are we calling this out here to say that BPF_CALL in clang -O0 builds is
not supported? That would seem to be the case given that we say that
BPF_CALL | BPF_X | BPF_JMP in reserved and not permitted in
instruction-set.rst. If that's not the case, can we add a bit more
verbiage here describing why this is done / why it's interesting and/or
relevant to the reader?

FWIW, most of our selftests don't seem to compile with clang -O0.

> +Note that ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function integer
> +would be read from a specified register, is reserved and currently not permitted.

> +
>  Atomic operations
>  =================
>  
> diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst
> index 2d3fe59bd26..89a13f1cdeb 100644
> --- a/Documentation/bpf/instruction-set.rst
> +++ b/Documentation/bpf/instruction-set.rst
> @@ -191,7 +191,7 @@ BPF_JSET  0x40   PC += off if dst & src
>  BPF_JNE   0x50   PC += off if dst != src
>  BPF_JSGT  0x60   PC += off if dst > src     signed
>  BPF_JSGE  0x70   PC += off if dst >= src    signed
> -BPF_CALL  0x80   function call
> +BPF_CALL  0x80   function call              see `Helper functions`_
>  BPF_EXIT  0x90   function / program return  BPF_JMP only
>  BPF_JLT   0xa0   PC += off if dst < src     unsigned
>  BPF_JLE   0xb0   PC += off if dst <= src    unsigned
> @@ -202,6 +202,26 @@ BPF_JSLE  0xd0   PC += off if dst <= src    signed
>  The eBPF program needs to store the return value into register R0 before doing a
>  BPF_EXIT.
>  
> +Helper functions
> +~~~~~~~~~~~~~~~~
> +
> +Helper functions are a concept whereby BPF programs can call into a
> +set of function calls exposed by the runtime.  Each helper
> +function is identified by an integer used in a ``BPF_CALL`` instruction.
> +The available helper functions may differ for each program type.
> +
> +Conceptually, each helper function is implemented with a commonly shared function
> +signature defined as:
> +
> +  u64 function(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
> +
> +In actuality, each helper function is defined as taking between 0 and 5 arguments,
> +with the remaining registers being ignored.  The definition of a helper function
> +is responsible for specifying the type (e.g., integer, pointer, etc.) of the value returned,
> +the number of arguments, and the type of each argument.
> +
> +Note that ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function integer
> +would be read from a specified register, is reserved and currently not permitted.
>  
>  Load and store instructions
>  ===========================
> -- 
> 2.33.4
> 
> -- 
> Bpf mailing list
> Bpf@ietf.org
> https://www.ietf.org/mailman/listinfo/bpf
Dave Thaler Feb. 8, 2023, 5:26 p.m. UTC | #2
David Vernet wrote:
> > +Reserved instructions
> > +====================
> 
> small nit: Missing a =

Ack.

> > +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d)
> instruction if ``-O0`` is used.
> 
> Are we calling this out here to say that BPF_CALL in clang -O0 builds is not
> supported? That would seem to be the case given that we say that BPF_CALL
> | BPF_X | BPF_JMP in reserved and not permitted in instruction-set.rst. 

Yes, exactly.  I could update the language to add something like
"... so BPF_CALL in clang -O0 builds is not supported".

Dave
David Vernet Feb. 8, 2023, 5:29 p.m. UTC | #3
On Wed, Feb 08, 2023 at 05:26:34PM +0000, Dave Thaler wrote:
> David Vernet wrote:
> > > +Reserved instructions
> > > +====================
> > 
> > small nit: Missing a =
> 
> Ack.
> 
> > > +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d)
> > instruction if ``-O0`` is used.
> > 
> > Are we calling this out here to say that BPF_CALL in clang -O0 builds is not
> > supported? That would seem to be the case given that we say that BPF_CALL
> > | BPF_X | BPF_JMP in reserved and not permitted in instruction-set.rst. 
> 
> Yes, exactly.  I could update the language to add something like
> "... so BPF_CALL in clang -O0 builds is not supported".

Gotcha, that sounds good to me. Thanks for being so thorough in
documenting all of this tribal knowledge.
Alexei Starovoitov Feb. 8, 2023, 5:31 p.m. UTC | #4
On Wed, Feb 8, 2023 at 9:26 AM Dave Thaler
<dthaler=40microsoft.com@dmarc.ietf.org> wrote:
>
> David Vernet wrote:
> > > +Reserved instructions
> > > +====================
> >
> > small nit: Missing a =
>
> Ack.
>
> > > +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d)
> > instruction if ``-O0`` is used.
> >
> > Are we calling this out here to say that BPF_CALL in clang -O0 builds is not
> > supported? That would seem to be the case given that we say that BPF_CALL
> > | BPF_X | BPF_JMP in reserved and not permitted in instruction-set.rst.
>
> Yes, exactly.  I could update the language to add something like
> "... so BPF_CALL in clang -O0 builds is not supported".

That will not be a correct statement.
BPF_CALL is a valid insn regardless of optimization flags.
BPF_CALLX will be a valid insn when the verifier support is added.
Compilers need to make a choice which insn to use on a case by case basis.
When compilers have no choice, but to use call by register they will
use callx. That what happens with = (void *)1 hack that we use for
helpers.
It can happen with -O2 just as well.
David Vernet Feb. 8, 2023, 5:40 p.m. UTC | #5
On Wed, Feb 08, 2023 at 09:31:18AM -0800, Alexei Starovoitov wrote:
> On Wed, Feb 8, 2023 at 9:26 AM Dave Thaler
> <dthaler=40microsoft.com@dmarc.ietf.org> wrote:
> >
> > David Vernet wrote:
> > > > +Reserved instructions
> > > > +====================
> > >
> > > small nit: Missing a =
> >
> > Ack.
> >
> > > > +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d)
> > > instruction if ``-O0`` is used.
> > >
> > > Are we calling this out here to say that BPF_CALL in clang -O0 builds is not
> > > supported? That would seem to be the case given that we say that BPF_CALL
> > > | BPF_X | BPF_JMP in reserved and not permitted in instruction-set.rst.
> >
> > Yes, exactly.  I could update the language to add something like
> > "... so BPF_CALL in clang -O0 builds is not supported".
> 
> That will not be a correct statement.
> BPF_CALL is a valid insn regardless of optimization flags.
> BPF_CALLX will be a valid insn when the verifier support is added.
> Compilers need to make a choice which insn to use on a case by case basis.
> When compilers have no choice, but to use call by register they will
> use callx. That what happens with = (void *)1 hack that we use for
> helpers.
> It can happen with -O2 just as well.

In that case, I suggest we update the verbiage in instruction-set.rst to
say:

Note that ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper
function integer would be read from a specified register, is not
currently supported by the verifier. Any programs with this instruction
will fail to load until such support is added.

And then we can update this section to say something similar, or just
remove it altogether per Alexei's point that it's an implementation
detail of the compiler which could change at any time.
Dave Thaler Feb. 8, 2023, 5:45 p.m. UTC | #6
> -----Original Message-----
> From: David Vernet <void@manifault.com>
> Sent: Wednesday, February 8, 2023 9:40 AM
> To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> Cc: Dave Thaler <dthaler@microsoft.com>; Dave Thaler
> <dthaler1968@googlemail.com>; bpf@vger.kernel.org; bpf@ietf.org
> Subject: Re: [Bpf] [PATCH bpf-next v2] bpf, docs: Explain helper functions
> 
> On Wed, Feb 08, 2023 at 09:31:18AM -0800, Alexei Starovoitov wrote:
> > On Wed, Feb 8, 2023 at 9:26 AM Dave Thaler
> > <dthaler=40microsoft.com@dmarc.ietf.org> wrote:
> > >
> > > David Vernet wrote:
> > > > > +Reserved instructions
> > > > > +====================
> > > >
> > > > small nit: Missing a =
> > >
> > > Ack.
> > >
> > > > > +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP``
> > > > > +(0x8d)
> > > > instruction if ``-O0`` is used.
> > > >
> > > > Are we calling this out here to say that BPF_CALL in clang -O0
> > > > builds is not supported? That would seem to be the case given that
> > > > we say that BPF_CALL
> > > > | BPF_X | BPF_JMP in reserved and not permitted in instruction-set.rst.
> > >
> > > Yes, exactly.  I could update the language to add something like
> > > "... so BPF_CALL in clang -O0 builds is not supported".
> >
> > That will not be a correct statement.
> > BPF_CALL is a valid insn regardless of optimization flags.
> > BPF_CALLX will be a valid insn when the verifier support is added.
> > Compilers need to make a choice which insn to use on a case by case basis.
> > When compilers have no choice, but to use call by register they will
> > use callx. That what happens with = (void *)1 hack that we use for
> > helpers.
> > It can happen with -O2 just as well.
> 
> In that case, I suggest we update the verbiage in instruction-set.rst to
> say:
> 
> Note that ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function
> integer would be read from a specified register, is not currently supported by
> the verifier. Any programs with this instruction will fail to load until such
> support is added.

The problem with that wording is that it implies that there is "the" verifier,
whereas the point of standard documentation (since this file is also being used
to generate the IETF spec) is to keep statements about any specific verifier
or compiler out of instruction-set.rst.  That's why there's separate files like
clang-notes.rst for the clang compiler, etc.   The instruction set rst is,
in my view, should apply across all compilers, all verifiers, all runtimes, etc.
It could potentially say certain things are optional to support, but there is
a distinction between "defined" vs "reserved" where it currently means
such support is "reserved" not "defined".
 
Dave
David Vernet Feb. 9, 2023, 4:04 p.m. UTC | #7
On Wed, Feb 08, 2023 at 05:45:59PM +0000, Dave Thaler wrote:
> > -----Original Message-----
> > From: David Vernet <void@manifault.com>
> > Sent: Wednesday, February 8, 2023 9:40 AM
> > To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
> > Cc: Dave Thaler <dthaler@microsoft.com>; Dave Thaler
> > <dthaler1968@googlemail.com>; bpf@vger.kernel.org; bpf@ietf.org
> > Subject: Re: [Bpf] [PATCH bpf-next v2] bpf, docs: Explain helper functions
> > 
> > On Wed, Feb 08, 2023 at 09:31:18AM -0800, Alexei Starovoitov wrote:
> > > On Wed, Feb 8, 2023 at 9:26 AM Dave Thaler
> > > <dthaler=40microsoft.com@dmarc.ietf.org> wrote:
> > > >
> > > > David Vernet wrote:
> > > > > > +Reserved instructions
> > > > > > +====================
> > > > >
> > > > > small nit: Missing a =
> > > >
> > > > Ack.
> > > >
> > > > > > +Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP``
> > > > > > +(0x8d)
> > > > > instruction if ``-O0`` is used.
> > > > >
> > > > > Are we calling this out here to say that BPF_CALL in clang -O0
> > > > > builds is not supported? That would seem to be the case given that
> > > > > we say that BPF_CALL
> > > > > | BPF_X | BPF_JMP in reserved and not permitted in instruction-set.rst.
> > > >
> > > > Yes, exactly.  I could update the language to add something like
> > > > "... so BPF_CALL in clang -O0 builds is not supported".
> > >
> > > That will not be a correct statement.
> > > BPF_CALL is a valid insn regardless of optimization flags.
> > > BPF_CALLX will be a valid insn when the verifier support is added.
> > > Compilers need to make a choice which insn to use on a case by case basis.
> > > When compilers have no choice, but to use call by register they will
> > > use callx. That what happens with = (void *)1 hack that we use for
> > > helpers.
> > > It can happen with -O2 just as well.
> > 
> > In that case, I suggest we update the verbiage in instruction-set.rst to
> > say:
> > 
> > Note that ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function
> > integer would be read from a specified register, is not currently supported by
> > the verifier. Any programs with this instruction will fail to load until such
> > support is added.
> 
> The problem with that wording is that it implies that there is "the" verifier,
> whereas the point of standard documentation (since this file is also being used
> to generate the IETF spec) is to keep statements about any specific verifier
> or compiler out of instruction-set.rst.  That's why there's separate files like

Yes, good point.

> clang-notes.rst for the clang compiler, etc.   The instruction set rst is,
> in my view, should apply across all compilers, all verifiers, all runtimes, etc.
> It could potentially say certain things are optional to support, but there is
> a distinction between "defined" vs "reserved" where it currently means
> such support is "reserved" not "defined".

That makes sense. IMO we should just say that the instruction is valid
then, and not make a distinction. 'reserved' should imply that the bits
for the instruction in question have no definition whatsoever, e.g.
reserved bits in control registers in x86, etc. In this case, the
instruction is valid, we just haven't chosen to implement support for it
yet in the Linux verifier. That's par for the course for implementing
standards. Usually we don't implement something until it's needed.
kernel test robot Feb. 12, 2023, 11:20 p.m. UTC | #8
Hi Dave,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on bpf-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Dave-Thaler/bpf-docs-Explain-helper-functions/20230207-031845
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
patch link:    https://lore.kernel.org/r/20230206191647.2075-1-dthaler1968%40googlemail.com
patch subject: [PATCH bpf-next v2] bpf, docs: Explain helper functions
reproduce:
        # https://github.com/intel-lab-lkp/linux/commit/b579d93fed53b16ad7241911226cbeb3b42f8266
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Dave-Thaler/bpf-docs-Explain-helper-functions/20230207-031845
        git checkout b579d93fed53b16ad7241911226cbeb3b42f8266
        make menuconfig
        # enable CONFIG_COMPILE_TEST, CONFIG_WARN_MISSING_DOCUMENTS, CONFIG_WARN_ABI_ERRORS
        make htmldocs

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202302130706.NBSii5FS-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> Documentation/bpf/clang-notes.rst:24: WARNING: Title underline too short.

vim +24 Documentation/bpf/clang-notes.rst

    22	
    23	Reserved instructions
  > 24	====================
    25
diff mbox series

Patch

diff --git a/Documentation/bpf/clang-notes.rst b/Documentation/bpf/clang-notes.rst
index 528feddf2db..40c6185513a 100644
--- a/Documentation/bpf/clang-notes.rst
+++ b/Documentation/bpf/clang-notes.rst
@@ -20,6 +20,11 @@  Arithmetic instructions
 For CPU versions prior to 3, Clang v7.0 and later can enable ``BPF_ALU`` support with
 ``-Xclang -target-feature -Xclang +alu32``.  In CPU version 3, support is automatically included.
 
+Reserved instructions
+====================
+
+Clang will generate the reserved ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d) instruction if ``-O0`` is used.
+
 Atomic operations
 =================
 
diff --git a/Documentation/bpf/instruction-set.rst b/Documentation/bpf/instruction-set.rst
index 2d3fe59bd26..89a13f1cdeb 100644
--- a/Documentation/bpf/instruction-set.rst
+++ b/Documentation/bpf/instruction-set.rst
@@ -191,7 +191,7 @@  BPF_JSET  0x40   PC += off if dst & src
 BPF_JNE   0x50   PC += off if dst != src
 BPF_JSGT  0x60   PC += off if dst > src     signed
 BPF_JSGE  0x70   PC += off if dst >= src    signed
-BPF_CALL  0x80   function call
+BPF_CALL  0x80   function call              see `Helper functions`_
 BPF_EXIT  0x90   function / program return  BPF_JMP only
 BPF_JLT   0xa0   PC += off if dst < src     unsigned
 BPF_JLE   0xb0   PC += off if dst <= src    unsigned
@@ -202,6 +202,26 @@  BPF_JSLE  0xd0   PC += off if dst <= src    signed
 The eBPF program needs to store the return value into register R0 before doing a
 BPF_EXIT.
 
+Helper functions
+~~~~~~~~~~~~~~~~
+
+Helper functions are a concept whereby BPF programs can call into a
+set of function calls exposed by the runtime.  Each helper
+function is identified by an integer used in a ``BPF_CALL`` instruction.
+The available helper functions may differ for each program type.
+
+Conceptually, each helper function is implemented with a commonly shared function
+signature defined as:
+
+  u64 function(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
+
+In actuality, each helper function is defined as taking between 0 and 5 arguments,
+with the remaining registers being ignored.  The definition of a helper function
+is responsible for specifying the type (e.g., integer, pointer, etc.) of the value returned,
+the number of arguments, and the type of each argument.
+
+Note that ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), where the helper function integer
+would be read from a specified register, is reserved and currently not permitted.
 
 Load and store instructions
 ===========================