mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-25 23:02:51 -04:00
Add two passes before the main verifier pass:
bpf_compute_const_regs() is a forward dataflow analysis that tracks
register values in R0-R9 across the program using fixed-point
iteration in reverse postorder. Each register is tracked with
a six-state lattice:
UNVISITED -> CONST(val) / MAP_PTR(map_index) /
MAP_VALUE(map_index, offset) / SUBPROG(num) -> UNKNOWN
At merge points, if two paths produce the same state and value for
a register, it stays; otherwise it becomes UNKNOWN.
The analysis handles:
- MOV, ADD, SUB, AND with immediate or register operands
- LD_IMM64 for plain constants, map FDs, map values, and subprogs
- LDX from read-only maps: constant-folds the load by reading the
map value directly via bpf_map_direct_read()
Results that fit in 32 bits are stored per-instruction in
insn_aux_data and bitmasks.
bpf_prune_dead_branches() uses the computed constants to evaluate
conditional branches. When both operands of a conditional jump are
known constants, the branch outcome is determined statically and the
instruction is rewritten to an unconditional jump.
The CFG postorder is then recomputed to reflect new control flow.
This eliminates dead edges so that subsequent liveness analysis
doesn't propagate through dead code.
Also add runtime sanity check to validate that precomputed
constants match the verifier's tracked state.
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260403024422.87231-5-alexei.starovoitov@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
76 lines
3.0 KiB
Makefile
76 lines
3.0 KiB
Makefile
# SPDX-License-Identifier: GPL-2.0
|
|
obj-y := core.o
|
|
ifneq ($(CONFIG_BPF_JIT_ALWAYS_ON),y)
|
|
# ___bpf_prog_run() needs GCSE disabled on x86; see 3193c0836f203 for details
|
|
cflags-nogcse-$(CONFIG_X86)$(CONFIG_CC_IS_GCC) := -fno-gcse
|
|
endif
|
|
CFLAGS_core.o += -Wno-override-init $(cflags-nogcse-yy)
|
|
|
|
obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o log.o token.o liveness.o const_fold.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += bpf_iter.o map_iter.o task_iter.o prog_iter.o link_iter.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o bloom_filter.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o bpf_insn_array.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += bpf_local_storage.o bpf_task_storage.o
|
|
obj-${CONFIG_BPF_LSM} += bpf_inode_storage.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += disasm.o mprog.o
|
|
obj-$(CONFIG_BPF_JIT) += trampoline.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += btf.o memalloc.o rqspinlock.o stream.o
|
|
ifeq ($(CONFIG_MMU)$(CONFIG_64BIT),yy)
|
|
obj-$(CONFIG_BPF_SYSCALL) += arena.o range_tree.o
|
|
endif
|
|
obj-$(CONFIG_BPF_JIT) += dispatcher.o
|
|
ifeq ($(CONFIG_NET),y)
|
|
obj-$(CONFIG_BPF_SYSCALL) += devmap.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += cpumap.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += offload.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += net_namespace.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += tcx.o
|
|
endif
|
|
ifeq ($(CONFIG_PERF_EVENTS),y)
|
|
obj-$(CONFIG_BPF_SYSCALL) += stackmap.o
|
|
endif
|
|
ifeq ($(CONFIG_CGROUPS),y)
|
|
obj-$(CONFIG_BPF_SYSCALL) += cgroup_iter.o bpf_cgrp_storage.o
|
|
endif
|
|
obj-$(CONFIG_CGROUP_BPF) += cgroup.o
|
|
ifeq ($(CONFIG_INET),y)
|
|
obj-$(CONFIG_BPF_SYSCALL) += reuseport_array.o
|
|
endif
|
|
ifeq ($(CONFIG_SYSFS),y)
|
|
obj-$(CONFIG_DEBUG_INFO_BTF) += sysfs_btf.o
|
|
endif
|
|
ifeq ($(CONFIG_BPF_JIT),y)
|
|
obj-$(CONFIG_BPF_SYSCALL) += bpf_struct_ops.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += cpumask.o
|
|
# bpf_lsm_proto.o must precede bpf_lsm.o. The current pahole logic
|
|
# deduplicates function prototypes within
|
|
# btf_encoder__add_saved_func() by keeping the first instance seen. We
|
|
# need the function prototype(s) in bpf_lsm_proto.o to take precedence
|
|
# over those within bpf_lsm.o. Having bpf_lsm_proto.o precede
|
|
# bpf_lsm.o ensures its DWARF CU is processed early, forcing the
|
|
# generated BTF to contain the overrides.
|
|
#
|
|
# Notably, this is a temporary workaround whilst the deduplication
|
|
# semantics within pahole are revisited accordingly.
|
|
obj-${CONFIG_BPF_LSM} += bpf_lsm_proto.o bpf_lsm.o
|
|
endif
|
|
ifneq ($(CONFIG_CRYPTO),)
|
|
obj-$(CONFIG_BPF_SYSCALL) += crypto.o
|
|
endif
|
|
obj-$(CONFIG_BPF_PRELOAD) += preload/
|
|
|
|
obj-$(CONFIG_BPF_SYSCALL) += relo_core.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += btf_iter.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += btf_relocate.o
|
|
obj-$(CONFIG_BPF_SYSCALL) += kmem_cache_iter.o
|
|
ifeq ($(CONFIG_DMA_SHARED_BUFFER),y)
|
|
obj-$(CONFIG_BPF_SYSCALL) += dmabuf_iter.o
|
|
endif
|
|
|
|
CFLAGS_REMOVE_percpu_freelist.o = $(CC_FLAGS_FTRACE)
|
|
CFLAGS_REMOVE_bpf_lru_list.o = $(CC_FLAGS_FTRACE)
|
|
CFLAGS_REMOVE_queue_stack_maps.o = $(CC_FLAGS_FTRACE)
|
|
CFLAGS_REMOVE_lpm_trie.o = $(CC_FLAGS_FTRACE)
|
|
CFLAGS_REMOVE_ringbuf.o = $(CC_FLAGS_FTRACE)
|
|
CFLAGS_REMOVE_rqspinlock.o = $(CC_FLAGS_FTRACE)
|