arch/x86/kernel/fpu/init.c
Source file repositories/reference/linux-study-clean/arch/x86/kernel/fpu/init.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kernel/fpu/init.c- Extension
.c- Size
- 5268 bytes
- Lines
- 223
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
asm/fpu/api.hasm/tlbflush.hasm/setup.hlinux/sched.hlinux/sched/task.hlinux/init.hinternal.hlegacy.hxstate.h
Detected Declarations
function fpu__init_cpu_genericfunction fpu__init_cpufunction fpu__probe_without_cpuidfunction fpu__init_system_early_genericfunction fpu__init_system_mxcsrfunction fpu__init_system_genericfunction ALIGNfunction fpu__init_system_xstatefunction fpu__init_system_xstatefunction fpu__init_system
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
/*
* x86 FPU boot time init code:
*/
#include <asm/fpu/api.h>
#include <asm/tlbflush.h>
#include <asm/setup.h>
#include <linux/sched.h>
#include <linux/sched/task.h>
#include <linux/init.h>
#include "internal.h"
#include "legacy.h"
#include "xstate.h"
/*
* Initialize the registers found in all CPUs, CR0 and CR4:
*/
static void fpu__init_cpu_generic(void)
{
unsigned long cr0;
unsigned long cr4_mask = 0;
if (boot_cpu_has(X86_FEATURE_FXSR))
cr4_mask |= X86_CR4_OSFXSR;
if (boot_cpu_has(X86_FEATURE_XMM))
cr4_mask |= X86_CR4_OSXMMEXCPT;
if (cr4_mask)
cr4_set_bits(cr4_mask);
cr0 = read_cr0();
cr0 &= ~(X86_CR0_TS|X86_CR0_EM); /* clear TS and EM */
if (!boot_cpu_has(X86_FEATURE_FPU))
cr0 |= X86_CR0_EM;
write_cr0(cr0);
/* Flush out any pending x87 state: */
asm volatile ("fninit");
}
/*
* Enable all supported FPU features. Called when a CPU is brought online:
*/
void fpu__init_cpu(void)
{
fpu__init_cpu_generic();
fpu__init_cpu_xstate();
/* Start allowing kernel-mode FPU: */
this_cpu_write(kernel_fpu_allowed, true);
}
static bool __init fpu__probe_without_cpuid(void)
{
unsigned long cr0;
u16 fsw, fcw;
fsw = fcw = 0xffff;
cr0 = read_cr0();
cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
write_cr0(cr0);
asm volatile("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
pr_info("x86/fpu: Probing for FPU: FSW=0x%04hx FCW=0x%04hx\n", fsw, fcw);
return fsw == 0 && (fcw & 0x103f) == 0x003f;
}
static void __init fpu__init_system_early_generic(void)
{
set_thread_flag(TIF_NEED_FPU_LOAD);
if (!boot_cpu_has(X86_FEATURE_CPUID) &&
!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
if (fpu__probe_without_cpuid())
setup_force_cpu_cap(X86_FEATURE_FPU);
else
setup_clear_cpu_cap(X86_FEATURE_FPU);
}
if (!test_cpu_cap(&boot_cpu_data, X86_FEATURE_FPU)) {
pr_emerg("x86/fpu: Giving up, no FPU found and no math emulation present\n");
for (;;)
asm volatile("hlt");
}
}
Annotation
- Immediate include surface: `asm/fpu/api.h`, `asm/tlbflush.h`, `asm/setup.h`, `linux/sched.h`, `linux/sched/task.h`, `linux/init.h`, `internal.h`, `legacy.h`.
- Detected declarations: `function fpu__init_cpu_generic`, `function fpu__init_cpu`, `function fpu__probe_without_cpuid`, `function fpu__init_system_early_generic`, `function fpu__init_system_mxcsr`, `function fpu__init_system_generic`, `function ALIGN`, `function fpu__init_system_xstate`, `function fpu__init_system_xstate`, `function fpu__init_system`.
- Atlas domain: Architecture Layer / arch/x86.
- 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.