arch/x86/kernel/alternative.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/alternative.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/alternative.c- Extension
.c- Size
- 79918 bytes
- Lines
- 3226
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/mmu_context.hlinux/perf_event.hlinux/vmalloc.hlinux/memory.hlinux/execmem.hasm/text-patching.hasm/insn.hasm/insn-eval.hasm/ibt.hasm/set_memory.hasm/nmi.h
Detected Declarations
struct patch_sitestruct smp_alt_modulestruct smp_text_poke_locfunction debug_altfunction setup_noreplace_smpfunction its_pages_protectfunction its_fini_corefunction its_init_modfunction its_fini_modfunction its_free_modfunction its_fini_corefunction skip_nopsfunction optimize_nopsfunction apply_relocfunction need_relocfunction __apply_relocationfunction text_poke_apply_relocationfunction BUG_funcfunction alt_replace_callfunction instr_vafunction analyze_patch_sitefunction prep_patch_sitefunction patch_sitefunction apply_alternativesfunction is_jcc32function emit_indirectfunction __emit_trampolinefunction emit_call_track_retpolinefunction emit_its_trampolinefunction cpu_wants_indirect_its_thunk_atfunction cpu_wants_indirect_its_thunk_atfunction patch_retpolinefunction apply_retpolinesfunction cpu_wants_rethunkfunction cpu_wants_rethunk_atfunction patch_returnfunction apply_returnsfunction apply_returnsfunction exact_endbrfunction poison_endbrfunction apply_seal_endbrfunction apply_seal_endbrfunction cfi_get_func_hashfunction cfi_get_func_arityfunction cfi_rehashfunction cfi_parse_cmdlinefunction decode_preamble_hashfunction decode_caller_hash
Annotated Snippet
struct patch_site {
u8 *instr;
struct alt_instr *alt;
u8 buff[MAX_PATCH_LEN];
u8 len;
};
static struct alt_instr * __init_or_module analyze_patch_site(struct patch_site *ps,
struct alt_instr *start,
struct alt_instr *end)
{
struct alt_instr *alt = start;
ps->instr = instr_va(start);
/*
* In case of nested ALTERNATIVE()s the outer alternative might add
* more padding. To ensure consistent patching find the max padding for
* all alt_instr entries for this site (nested alternatives result in
* consecutive entries).
* Find the last alt_instr eligible for patching at the site.
*/
for (; alt < end && instr_va(alt) == ps->instr; alt++) {
ps->len = max(ps->len, alt->instrlen);
BUG_ON(alt->cpuid >= (NCAPINTS + NBUGINTS) * 32);
/*
* Patch if either:
* - feature is present
* - feature not present but ALT_FLAG_NOT is set to mean,
* patch if feature is *NOT* present.
*/
if (!boot_cpu_has(alt->cpuid) != !(alt->flags & ALT_FLAG_NOT))
ps->alt = alt;
}
BUG_ON(ps->len > sizeof(ps->buff));
return alt;
}
static void __init_or_module prep_patch_site(struct patch_site *ps)
{
struct alt_instr *alt = ps->alt;
u8 buff_sz;
u8 *repl;
if (!alt) {
/* Nothing to patch, use original instruction. */
memcpy(ps->buff, ps->instr, ps->len);
return;
}
repl = (u8 *)&alt->repl_offset + alt->repl_offset;
DPRINTK(ALT, "feat: %d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d) flags: 0x%x",
alt->cpuid >> 5, alt->cpuid & 0x1f,
ps->instr, ps->instr, ps->len,
repl, alt->replacementlen, alt->flags);
memcpy(ps->buff, repl, alt->replacementlen);
buff_sz = alt->replacementlen;
if (alt->flags & ALT_FLAG_DIRECT_CALL)
buff_sz = alt_replace_call(ps->instr, ps->buff, alt);
for (; buff_sz < ps->len; buff_sz++)
ps->buff[buff_sz] = 0x90;
__apply_relocation(ps->buff, ps->instr, ps->len, repl, alt->replacementlen);
DUMP_BYTES(ALT, ps->instr, ps->len, "%px: old_insn: ", ps->instr);
DUMP_BYTES(ALT, repl, alt->replacementlen, "%px: rpl_insn: ", repl);
DUMP_BYTES(ALT, ps->buff, ps->len, "%px: final_insn: ", ps->instr);
}
static void __init_or_module patch_site(struct patch_site *ps)
{
optimize_nops(ps->instr, ps->buff, ps->len);
text_poke_early(ps->instr, ps->buff, ps->len);
}
/*
* Replace instructions with better alternatives for this CPU type. This runs
* before SMP is initialized to avoid SMP problems with self modifying code.
* This implies that asymmetric systems where APs have less capabilities than
* the boot processor are not handled. Tough. Make sure you disable such
* features by hand.
*
* Marked "noinline" to cause control flow change and thus insn cache
* to refetch changed I$ lines.
Annotation
- Immediate include surface: `linux/mmu_context.h`, `linux/perf_event.h`, `linux/vmalloc.h`, `linux/memory.h`, `linux/execmem.h`, `asm/text-patching.h`, `asm/insn.h`, `asm/insn-eval.h`.
- Detected declarations: `struct patch_site`, `struct smp_alt_module`, `struct smp_text_poke_loc`, `function debug_alt`, `function setup_noreplace_smp`, `function its_pages_protect`, `function its_fini_core`, `function its_init_mod`, `function its_fini_mod`, `function its_free_mod`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.