Skip to content

Commit 37ac78b

Browse files
amlutoIngo Molnar
authored andcommitted
x86/fpu: Fix CPUID-less FPU detection
The old code didn't work at all because it adjusted the current caps instead of the forced caps. Anything it did would be undone later during CPU identification. Fix that and, while we're at it, improve the logging and don't bother running it if CPUID is available. Reported-by: Matthew Whitehead <[email protected]> Signed-off-by: Andy Lutomirski <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Fenghua Yu <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: One Thousand Gnomes <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Yu-cheng Yu <[email protected]> Link: http://lkml.kernel.org/r/f1134e30cafa73c4e2e68119e9741793622cfd15.1484705016.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent 9170fb4 commit 37ac78b

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

arch/x86/kernel/fpu/init.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,7 @@ void fpu__init_cpu(void)
4848
fpu__init_cpu_xstate();
4949
}
5050

51-
/*
52-
* The earliest FPU detection code.
53-
*
54-
* Set the X86_FEATURE_FPU CPU-capability bit based on
55-
* trying to execute an actual sequence of FPU instructions:
56-
*/
57-
static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
51+
static bool fpu__probe_without_cpuid(void)
5852
{
5953
unsigned long cr0;
6054
u16 fsw, fcw;
@@ -65,14 +59,21 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
6559
cr0 &= ~(X86_CR0_TS | X86_CR0_EM);
6660
write_cr0(cr0);
6761

68-
if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
69-
asm volatile("fninit ; fnstsw %0 ; fnstcw %1"
70-
: "+m" (fsw), "+m" (fcw));
62+
asm volatile("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
63+
64+
pr_info("x86/fpu: Probing for FPU: FSW=0x%04hx FCW=0x%04hx\n", fsw, fcw);
7165

72-
if (fsw == 0 && (fcw & 0x103f) == 0x003f)
73-
set_cpu_cap(c, X86_FEATURE_FPU);
66+
return fsw == 0 && (fcw & 0x103f) == 0x003f;
67+
}
68+
69+
static void fpu__init_system_early_generic(struct cpuinfo_x86 *c)
70+
{
71+
if (!boot_cpu_has(X86_FEATURE_CPUID) &&
72+
!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) {
73+
if (fpu__probe_without_cpuid())
74+
setup_force_cpu_cap(X86_FEATURE_FPU);
7475
else
75-
clear_cpu_cap(c, X86_FEATURE_FPU);
76+
setup_clear_cpu_cap(X86_FEATURE_FPU);
7677
}
7778

7879
#ifndef CONFIG_MATH_EMULATION

0 commit comments

Comments
 (0)