|
@@ -48,13 +48,7 @@ void fpu__init_cpu(void)
|
|
|
fpu__init_cpu_xstate();
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * The earliest FPU detection code.
|
|
|
- *
|
|
|
- * Set the X86_FEATURE_FPU CPU-capability bit based on
|
|
|
- * trying to execute an actual sequence of FPU instructions:
|
|
|
- */
|
|
|
-static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
|
|
|
+static bool fpu__probe_without_cpuid(void)
|
|
|
{
|
|
|
unsigned long cr0;
|
|
|
u16 fsw, fcw;
|
|
@@ -65,14 +59,21 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
|
|
|
cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
|
|
|
write_cr0(cr0);
|
|
|
|
|
|
- if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
|
|
|
- asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
|
|
|
- : "+m" (fsw), "+m" (fcw));
|
|
|
+ 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);
|
|
|
|
|
|
- if (fsw == 0 && (fcw & 0x103f) == 0x003f)
|
|
|
- set_cpu_cap(c, X86_FEATURE_FPU);
|
|
|
+ return fsw == 0 && (fcw & 0x103f) == 0x003f;
|
|
|
+}
|
|
|
+
|
|
|
+static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
|
|
|
+{
|
|
|
+ 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
|
|
|
- clear_cpu_cap(c, X86_FEATURE_FPU);
|
|
|
+ setup_clear_cpu_cap(X86_FEATURE_FPU);
|
|
|
}
|
|
|
|
|
|
#ifndef CONFIG_MATH_EMULATION
|