kernel/bpf/cfg.c
Source file repositories/reference/linux-study-clean/kernel/bpf/cfg.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/bpf/cfg.c- Extension
.c- Size
- 24720 bytes
- Lines
- 884
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bpf.hlinux/bpf_verifier.hlinux/filter.hlinux/sort.h
Detected Declarations
function mark_subprog_changes_pkt_datafunction mark_subprog_might_sleepfunction mark_subprog_might_throwfunction merge_callee_effectsfunction push_insnfunction visit_func_call_insnfunction copy_insn_arrayfunction cmp_ptr_to_u32function sort_insn_array_uniqfunction sort_uniquefunction create_jtfunction create_jtfunction visit_gotox_insnfunction subprogfunction visit_insnfunction BPF_CLASSfunction bpf_check_cfgfunction bpf_compute_postorderfunction components
Annotated Snippet
if (IS_ERR(jt_cur)) {
kvfree(jt);
return jt_cur;
}
/*
* This is enough to check one element. The full table is
* checked to fit inside the subprog later in create_jt()
*/
if (jt_cur->items[0] >= subprog_start && jt_cur->items[0] < subprog_end) {
u32 old_cnt = jt ? jt->cnt : 0;
jt = bpf_iarray_realloc(jt, old_cnt + jt_cur->cnt);
if (!jt) {
kvfree(jt_cur);
return ERR_PTR(-ENOMEM);
}
memcpy(jt->items + old_cnt, jt_cur->items, jt_cur->cnt << 2);
}
kvfree(jt_cur);
}
if (!jt) {
verbose(env, "no jump tables found for subprog starting at %u\n", subprog_start);
return ERR_PTR(-EINVAL);
}
jt->cnt = sort_insn_array_uniq(jt->items, jt->cnt);
return jt;
}
static struct bpf_iarray *
create_jt(int t, struct bpf_verifier_env *env)
{
struct bpf_subprog_info *subprog;
int subprog_start, subprog_end;
struct bpf_iarray *jt;
int i;
subprog = bpf_find_containing_subprog(env, t);
subprog_start = subprog->start;
subprog_end = (subprog + 1)->start;
jt = jt_from_subprog(env, subprog_start, subprog_end);
if (IS_ERR(jt))
return jt;
/* Check that the every element of the jump table fits within the given subprogram */
for (i = 0; i < jt->cnt; i++) {
if (jt->items[i] < subprog_start || jt->items[i] >= subprog_end) {
verbose(env, "jump table for insn %d points outside of the subprog [%u,%u]\n",
t, subprog_start, subprog_end);
kvfree(jt);
return ERR_PTR(-EINVAL);
}
}
return jt;
}
/* "conditional jump with N edges" */
static int visit_gotox_insn(int t, struct bpf_verifier_env *env)
{
int *insn_stack = env->cfg.insn_stack;
int *insn_state = env->cfg.insn_state;
bool keep_exploring = false;
struct bpf_iarray *jt;
int i, w;
jt = env->insn_aux_data[t].jt;
if (!jt) {
jt = create_jt(t, env);
if (IS_ERR(jt))
return PTR_ERR(jt);
env->insn_aux_data[t].jt = jt;
}
mark_prune_point(env, t);
for (i = 0; i < jt->cnt; i++) {
w = jt->items[i];
if (w < 0 || w >= env->prog->len) {
verbose(env, "indirect jump out of range from insn %d to %d\n", t, w);
return -EINVAL;
}
mark_jmp_point(env, w);
/* EXPLORED || DISCOVERED */
if (insn_state[w])
continue;
Annotation
- Immediate include surface: `linux/bpf.h`, `linux/bpf_verifier.h`, `linux/filter.h`, `linux/sort.h`.
- Detected declarations: `function mark_subprog_changes_pkt_data`, `function mark_subprog_might_sleep`, `function mark_subprog_might_throw`, `function merge_callee_effects`, `function push_insn`, `function visit_func_call_insn`, `function copy_insn_array`, `function cmp_ptr_to_u32`, `function sort_insn_array_uniq`, `function sort_unique`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.