mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 21:54:06 +08:00
x86/fpu: Split out the boot time FPU init code into fpu/init.c
Move boot time FPU initialization code into init.c, to better isolate it into its own domain. Reviewed-by: Borislav Petkov <bp@alien8.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
f89e32e0a3
commit
0c86753790
@ -2,4 +2,4 @@
|
||||
# Build rules for the FPU support code:
|
||||
#
|
||||
|
||||
obj-y += core.o xsave.o
|
||||
obj-y += init.o core.o xsave.o
|
||||
|
@ -139,94 +139,6 @@ void fpu__save(struct task_struct *tsk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fpu__save);
|
||||
|
||||
unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
|
||||
unsigned int xstate_size;
|
||||
EXPORT_SYMBOL_GPL(xstate_size);
|
||||
static struct i387_fxsave_struct fx_scratch;
|
||||
|
||||
static void mxcsr_feature_mask_init(void)
|
||||
{
|
||||
unsigned long mask = 0;
|
||||
|
||||
if (cpu_has_fxsr) {
|
||||
memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct));
|
||||
asm volatile("fxsave %0" : "+m" (fx_scratch));
|
||||
mask = fx_scratch.mxcsr_mask;
|
||||
if (mask == 0)
|
||||
mask = 0x0000ffbf;
|
||||
}
|
||||
mxcsr_feature_mask &= mask;
|
||||
}
|
||||
|
||||
static void fpstate_xstate_init_size(void)
|
||||
{
|
||||
/*
|
||||
* Note that xstate_size might be overwriten later during
|
||||
* xsave_init().
|
||||
*/
|
||||
|
||||
if (!cpu_has_fpu) {
|
||||
/*
|
||||
* Disable xsave as we do not support it if i387
|
||||
* emulation is enabled.
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
|
||||
xstate_size = sizeof(struct i387_soft_struct);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_has_fxsr)
|
||||
xstate_size = sizeof(struct i387_fxsave_struct);
|
||||
else
|
||||
xstate_size = sizeof(struct i387_fsave_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called on the boot CPU at bootup to set up the initial FPU state that
|
||||
* is later cloned into all processes.
|
||||
*
|
||||
* Also called on secondary CPUs to set up the FPU state of their
|
||||
* idle threads.
|
||||
*/
|
||||
void fpu__cpu_init(void)
|
||||
{
|
||||
unsigned long cr0;
|
||||
unsigned long cr4_mask = 0;
|
||||
|
||||
#ifndef CONFIG_MATH_EMULATION
|
||||
if (!cpu_has_fpu) {
|
||||
pr_emerg("No FPU found and no math emulation present\n");
|
||||
pr_emerg("Giving up\n");
|
||||
for (;;)
|
||||
asm volatile("hlt");
|
||||
}
|
||||
#endif
|
||||
if (cpu_has_fxsr)
|
||||
cr4_mask |= X86_CR4_OSFXSR;
|
||||
if (cpu_has_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 (!cpu_has_fpu)
|
||||
cr0 |= X86_CR0_EM;
|
||||
write_cr0(cr0);
|
||||
|
||||
/*
|
||||
* fpstate_xstate_init_size() is only called once, to avoid overriding
|
||||
* 'xstate_size' during (secondary CPU) bootup or during CPU hotplug.
|
||||
*/
|
||||
if (xstate_size == 0)
|
||||
fpstate_xstate_init_size();
|
||||
|
||||
mxcsr_feature_mask_init();
|
||||
xsave_init();
|
||||
eager_fpu_init();
|
||||
}
|
||||
|
||||
void fpstate_init(struct fpu *fpu)
|
||||
{
|
||||
if (!cpu_has_fpu) {
|
||||
|
93
arch/x86/kernel/fpu/init.c
Normal file
93
arch/x86/kernel/fpu/init.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* x86 FPU boot time init code
|
||||
*/
|
||||
#include <asm/fpu-internal.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
unsigned int mxcsr_feature_mask __read_mostly = 0xffffffffu;
|
||||
unsigned int xstate_size;
|
||||
EXPORT_SYMBOL_GPL(xstate_size);
|
||||
static struct i387_fxsave_struct fx_scratch;
|
||||
|
||||
static void mxcsr_feature_mask_init(void)
|
||||
{
|
||||
unsigned long mask = 0;
|
||||
|
||||
if (cpu_has_fxsr) {
|
||||
memset(&fx_scratch, 0, sizeof(struct i387_fxsave_struct));
|
||||
asm volatile("fxsave %0" : "+m" (fx_scratch));
|
||||
mask = fx_scratch.mxcsr_mask;
|
||||
if (mask == 0)
|
||||
mask = 0x0000ffbf;
|
||||
}
|
||||
mxcsr_feature_mask &= mask;
|
||||
}
|
||||
|
||||
static void fpstate_xstate_init_size(void)
|
||||
{
|
||||
/*
|
||||
* Note that xstate_size might be overwriten later during
|
||||
* xsave_init().
|
||||
*/
|
||||
|
||||
if (!cpu_has_fpu) {
|
||||
/*
|
||||
* Disable xsave as we do not support it if i387
|
||||
* emulation is enabled.
|
||||
*/
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVE);
|
||||
setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT);
|
||||
xstate_size = sizeof(struct i387_soft_struct);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpu_has_fxsr)
|
||||
xstate_size = sizeof(struct i387_fxsave_struct);
|
||||
else
|
||||
xstate_size = sizeof(struct i387_fsave_struct);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called on the boot CPU at bootup to set up the initial FPU state that
|
||||
* is later cloned into all processes.
|
||||
*
|
||||
* Also called on secondary CPUs to set up the FPU state of their
|
||||
* idle threads.
|
||||
*/
|
||||
void fpu__cpu_init(void)
|
||||
{
|
||||
unsigned long cr0;
|
||||
unsigned long cr4_mask = 0;
|
||||
|
||||
#ifndef CONFIG_MATH_EMULATION
|
||||
if (!cpu_has_fpu) {
|
||||
pr_emerg("No FPU found and no math emulation present\n");
|
||||
pr_emerg("Giving up\n");
|
||||
for (;;)
|
||||
asm volatile("hlt");
|
||||
}
|
||||
#endif
|
||||
if (cpu_has_fxsr)
|
||||
cr4_mask |= X86_CR4_OSFXSR;
|
||||
if (cpu_has_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 (!cpu_has_fpu)
|
||||
cr0 |= X86_CR0_EM;
|
||||
write_cr0(cr0);
|
||||
|
||||
/*
|
||||
* fpstate_xstate_init_size() is only called once, to avoid overriding
|
||||
* 'xstate_size' during (secondary CPU) bootup or during CPU hotplug.
|
||||
*/
|
||||
if (xstate_size == 0)
|
||||
fpstate_xstate_init_size();
|
||||
|
||||
mxcsr_feature_mask_init();
|
||||
xsave_init();
|
||||
eager_fpu_init();
|
||||
}
|
Loading…
Reference in New Issue
Block a user