# Kernel self-patching

The Linux kernel rewrites its own text segment at boot to specialize a generic binary for the specific machine it landed on. Three mechanisms cooperate, each addressing a different cost:

## jump_label — feature flags for free

A `static_branch_unlikely(&some_key)` looks like `if (some_flag)` in source, but the compiler emits a `NOP` (or a `JMP`) at that site and registers a patch entry. `jump_label_init()` walks the registered table at boot and rewrites every site according to whether the key is currently enabled.

A disabled feature costs **zero CPU cycles** in hot paths — no register read, no branch predictor entry, no cache miss. Switching the flag re-patches every site. The kernel uses this for tracing hooks, perf events, debug instrumentation, and anything else that wants to be invisible when off.

## static_call — direct calls instead of indirect

`static_call(func)(args)` looks like an indirect call but gets patched at boot into a direct call to the currently-bound function. Faster than a function pointer, no Spectre/Meltdown speculative-execution concern. Scheduler dispatch, KVM, tracepoints all use it.

## alternative_instructions — per-CPU instruction selection

The boldest of the three. The kernel ships with `ALTERNATIVE` macro sites that describe two (or more) variants of the same code — for example, an AVX-512 memcpy and a fallback. `alternative_instructions()` runs in Phase 4 after CPUID has discovered the actual feature set, then patches every `ALTERNATIVE` site to keep only the variant that fits this CPU.

The same `vmlinux` Debian ships boots optimally on every x86_64 chip Debian supports: the boot-time patching produces a binary tailored to AVX-512 on a Zen 5, to plain SSE on a 15-year-old Atom, to the Spectre-mitigation flavor the chip needs, all from one source.

## Why three separate mechanisms

They patch the same address space but solve different problems:

| Mechanism | Patches | Decides at | Cost when "off" |
|-----------|---------|------------|------------------|
| `jump_label` | NOP / JMP | runtime, mutable | zero |
| `static_call` | call target | runtime, mutable | direct-call cost |
| `alternative_instructions` | instruction sequence | boot, immutable | fallback variant runs |

`jump_label` and `static_call` can be flipped at runtime. `alternative_instructions` runs once at boot — once you've discarded the AVX-512 path on a chip that doesn't have it, you can't get it back without rebooting.

## Prerequisites

Self-patching needs `poking_init()` (the machinery that lets the kernel safely rewrite its own code despite `rodata` and W^X), which is why `mm_core_init()` brings it up early. And it needs to happen *before* `mark_readonly()` in Phase 6 — once `rodata` is locked at the page-table level, the patching window closes.

## Cross-references

- [[linux-kernel-startup]] — where these three mechanisms run in the boot sequence
- [[linux-boot-phases]] — the "lock the doors last" rule that depends on patching happening first
