mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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:
parent
b018e998e6
commit
fd318eab4b
|
|
@ -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
|
||||
=================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user