bpf, docs: Document callx instruction

Document callx: what it does, where the callee address comes from and
what is not supported.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260924031042.1690890-18-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-09-24 03:10:42 +00:00
parent b018e998e6
commit fd318eab4b
No known key found for this signature in database
2 changed files with 32 additions and 6 deletions

View File

@ -23,8 +23,11 @@ For CPU versions prior to 3, Clang v7.0 and later can enable ``BPF_ALU`` support
Jump instructions
=================
If ``-O0`` is used, Clang will generate the ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d)
instruction, which is not supported by the Linux kernel verifier.
Clang generates the ``BPF_CALL | BPF_X | BPF_JMP`` (0x8d) instruction for calls
through a function pointer. The Linux kernel verifier accepts it only when it
can prove that the register holds the address of a static BPF function, see
Documentation/bpf/linux-notes.rst. If ``-O0`` is used, Clang will generate this
instruction for helper calls as well, which is not supported.
Atomic operations
=================

View File

@ -15,10 +15,33 @@ Byte swap instructions
Jump instructions
=================
``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.
``BPF_CALL | BPF_X | BPF_JMP`` (0x8d), ``callx dst``, performs an indirect
call of a BPF function whose address is held in the ``dst`` register. The
``src``, ``offset`` and ``imm`` fields are reserved and must be zero.
The address of a BPF function gets into a register in one of two ways:
* it is loaded by a 64-bit immediate instruction with ``src`` =
``BPF_PSEUDO_FUNC``;
* it is read, with a 64-bit load, from a frozen read-only array map, that no
other program uses, that holds its read-only data: tables of functions,
structures of operations, vtables, where pointers to functions may be mixed
with other data. In the map a pointer to a function is the offset in bytes
of its first instruction in the program, and that is how the verifier
recognizes it. It is replaced with the address of the function when
the program is loaded. The program reads it from there, which requires
``CAP_PERFMON``.
In both cases only static functions can be referenced. Therefore all functions
that can be called indirectly are known to the verifier before it starts to
analyze the program, and ``callx`` is verified as a direct call of every
function that ``dst`` may point to at that instruction. The same rules apply:
the calls can not be recursive, and the depth of the call chain and its
combined stack size are limited.
Calling helper or kernel functions through a register, indirect calls of global
functions, and tail calls in functions that are called via ``callx`` are not
supported. ``callx`` requires the BPF JIT.
Maps
====