linux/arch
Anton Protopopov 493d9e0d60 bpf, x86: add support for indirect jumps
Add support for a new instruction

    BPF_JMP|BPF_X|BPF_JA, SRC=0, DST=Rx, off=0, imm=0

which does an indirect jump to a location stored in Rx.  The register
Rx should have type PTR_TO_INSN. This new type assures that the Rx
register contains a value (or a range of values) loaded from a
correct jump table – map of type instruction array.

For example, for a C switch LLVM will generate the following code:

    0:   r3 = r1                    # "switch (r3)"
    1:   if r3 > 0x13 goto +0x666   # check r3 boundaries
    2:   r3 <<= 0x3                 # adjust to an index in array of addresses
    3:   r1 = 0xbeef ll             # r1 is PTR_TO_MAP_VALUE, r1->map_ptr=M
    5:   r1 += r3                   # r1 inherits boundaries from r3
    6:   r1 = *(u64 *)(r1 + 0x0)    # r1 now has type INSN_TO_PTR
    7:   gotox r1                   # jit will generate proper code

Here the gotox instruction corresponds to one particular map. This is
possible however to have a gotox instruction which can be loaded from
different maps, e.g.

    0:   r1 &= 0x1
    1:   r2 <<= 0x3
    2:   r3 = 0x0 ll                # load from map M_1
    4:   r3 += r2
    5:   if r1 == 0x0 goto +0x4
    6:   r1 <<= 0x3
    7:   r3 = 0x0 ll                # load from map M_2
    9:   r3 += r1
    A:   r1 = *(u64 *)(r3 + 0x0)
    B:   gotox r1                   # jump to target loaded from M_1 or M_2

During check_cfg stage the verifier will collect all the maps which
point to inside the subprog being verified. When building the config,
the high 16 bytes of the insn_state are used, so this patch
(theoretically) supports jump tables of up to 2^16 slots.

During the later stage, in check_indirect_jump, it is checked that
the register Rx was loaded from a particular instruction array.

Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20251105090410.1250500-9-a.s.protopopov@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2025-11-05 17:53:23 -08:00
..
alpha assorted dead code removal around asm/pgtable.h 2025-10-03 11:37:50 -07:00
arc Ext4 bug fixes for 6.18-rc2, including 2025-10-15 07:51:57 -07:00
arm soc: fixes for 6.18, part 2 2025-10-24 11:15:17 -07:00
arm64 bpf-fixes 2025-10-31 18:22:26 -07:00
csky csky: abiv2: adapt to new folio flags field 2025-10-21 15:46:18 -07:00
hexagon Remove long-stale ext3 defconfig option 2025-10-15 07:57:28 -07:00
loongarch Use CONFIG_EXT4_FS instead of CONFIG_EXT3_FS in all of the defconfigs 2025-10-13 21:50:40 -04:00
m68k Ext4 bug fixes for 6.18-rc2, including 2025-10-15 07:51:57 -07:00
microblaze Ext4 bug fixes for 6.18-rc2, including 2025-10-15 07:51:57 -07:00
mips pci-v6.18-fixes-3 2025-10-24 16:43:08 -07:00
nios2 Summary of significant series in this pull request: 2025-10-02 18:18:33 -07:00
openrisc Ext4 bug fixes for 6.18-rc2, including 2025-10-15 07:51:57 -07:00
parisc Ext4 bug fixes for 6.18-rc2, including 2025-10-15 07:51:57 -07:00
powerpc powerpc/fadump: skip parameter area allocation when fadump is disabled 2025-10-13 09:41:31 +05:30
riscv riscv: hwprobe: avoid uninitialized variable use in hwprobe_arch_id() 2025-10-18 09:36:36 -06:00
s390 s390 fixes for 6.18-rc4 2025-10-31 12:50:35 -07:00
sh Remove long-stale ext3 defconfig option 2025-10-15 07:57:28 -07:00
sparc Remove long-stale ext3 defconfig option 2025-10-15 07:57:28 -07:00
um updates for UML, notably 2025-10-06 12:10:55 -07:00
x86 bpf, x86: add support for indirect jumps 2025-11-05 17:53:23 -08:00
xtensa Ext4 bug fixes for 6.18-rc2, including 2025-10-15 07:51:57 -07:00
.gitignore
Kconfig rust: cfi: only 64-bit arm and x86 support CFI_CLANG 2025-10-09 19:36:45 -06:00