Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
0bf23f3d IM |
2 | /* |
3 | * x86 FPU bug checks: | |
4 | */ | |
5 | #include <asm/fpu/internal.h> | |
6 | ||
7 | /* | |
8 | * Boot time CPU/FPU FDIV bug detection code: | |
9 | */ | |
10 | ||
11 | static double __initdata x = 4195835.0; | |
12 | static double __initdata y = 3145727.0; | |
13 | ||
14 | /* | |
15 | * This used to check for exceptions.. | |
16 | * However, it turns out that to support that, | |
17 | * the XMM trap handlers basically had to | |
18 | * be buggy. So let's have a correct XMM trap | |
19 | * handler, and forget about printing out | |
20 | * some status at boot. | |
21 | * | |
22 | * We should really only care about bugs here | |
23 | * anyway. Not features. | |
24 | */ | |
de82fbc3 | 25 | void __init fpu__init_check_bugs(void) |
0bf23f3d IM |
26 | { |
27 | s32 fdiv_bug; | |
28 | ||
de82fbc3 BP |
29 | /* kernel_fpu_begin/end() relies on patched alternative instructions. */ |
30 | if (!boot_cpu_has(X86_FEATURE_FPU)) | |
31 | return; | |
32 | ||
0bf23f3d IM |
33 | kernel_fpu_begin(); |
34 | ||
35 | /* | |
36 | * trap_init() enabled FXSR and company _before_ testing for FP | |
37 | * problems here. | |
38 | * | |
39 | * Test for the divl bug: http://en.wikipedia.org/wiki/Fdiv_bug | |
40 | */ | |
41 | __asm__("fninit\n\t" | |
42 | "fldl %1\n\t" | |
43 | "fdivl %2\n\t" | |
44 | "fmull %2\n\t" | |
45 | "fldl %1\n\t" | |
46 | "fsubp %%st,%%st(1)\n\t" | |
47 | "fistpl %0\n\t" | |
48 | "fwait\n\t" | |
49 | "fninit" | |
50 | : "=m" (*&fdiv_bug) | |
51 | : "m" (*&x), "m" (*&y)); | |
52 | ||
53 | kernel_fpu_end(); | |
54 | ||
55 | if (fdiv_bug) { | |
56 | set_cpu_bug(&boot_cpu_data, X86_BUG_FDIV); | |
57 | pr_warn("Hmm, FPU with FDIV bug\n"); | |
58 | } | |
59 | } |