[PATCH 3.16 02/63] x86/fpu: Default eagerfpu if FPU and FXSR are enabled
From: Ben Hutchings
Date: Fri Sep 21 2018 - 20:26:06 EST
3.16.58-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
This is a limited version of commit 58122bf1d856 "x86/fpu: Default
eagerfpu=on on all CPUs". That commit revealed bugs in the use of
eagerfpu together with math emulation or without the FXSR feature.
Although those bugs have been fixed upstream, the fixes do not seem to
be practical to backport to 3.16.
The security issue that motivates using eagerfpu (CVE-2018-3665) is an
information leak through speculative execution, and most CPUs lacking
the FXSR feature also don't implement speculative execution. The
exceptions I am aware of are the Intel Pentium Pro and AMD K6 family,
which will remain vulnerable to this issue.
Move the eagerfpu variable and associated initialisation into
fpu_init(), since xstate_enable_boot_cpu() won't be called at all if
XSAVE is disabled.
Signed-off-by: Ben Hutchings <ben@xxxxxxxxxxxxxxx>
Cc: Andy Lutomirski <luto@xxxxxxxxxx>
Cc: x86@xxxxxxxxxx
---
--- a/arch/x86/kernel/xsave.c
+++ b/arch/x86/kernel/xsave.c
@@ -509,19 +509,6 @@ static void __init setup_init_fpu_buf(vo
xsave_state(init_xstate_buf, -1);
}
-static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO;
-static int __init eager_fpu_setup(char *s)
-{
- if (!strcmp(s, "on"))
- eagerfpu = ENABLE;
- else if (!strcmp(s, "off"))
- eagerfpu = DISABLE;
- else if (!strcmp(s, "auto"))
- eagerfpu = AUTO;
- return 1;
-}
-__setup("eagerfpu=", eager_fpu_setup);
-
/*
* Enable and initialize the xsave feature.
*/
@@ -560,17 +547,11 @@ static void __init xstate_enable_boot_cp
prepare_fx_sw_frame();
setup_init_fpu_buf();
- /* Auto enable eagerfpu for xsaveopt */
- if (cpu_has_xsaveopt && eagerfpu != DISABLE)
- eagerfpu = ENABLE;
-
if (pcntxt_mask & XSTATE_EAGER) {
- if (eagerfpu == DISABLE) {
+ if (!boot_cpu_has(X86_FEATURE_EAGER_FPU)) {
pr_err("eagerfpu not present, disabling some xstate features: 0x%llx\n",
pcntxt_mask & XSTATE_EAGER);
pcntxt_mask &= ~XSTATE_EAGER;
- } else {
- eagerfpu = ENABLE;
}
}
@@ -613,9 +594,6 @@ void eager_fpu_init(void)
clear_used_math();
current_thread_info()->status = 0;
- if (eagerfpu == ENABLE)
- setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
-
if (!cpu_has_eager_fpu) {
stts();
return;
--- a/arch/x86/kernel/i387.c
+++ b/arch/x86/kernel/i387.c
@@ -159,6 +159,19 @@ static void init_thread_xstate(void)
xstate_size = sizeof(struct i387_fsave_struct);
}
+static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO;
+static int __init eager_fpu_setup(char *s)
+{
+ if (!strcmp(s, "on"))
+ eagerfpu = ENABLE;
+ else if (!strcmp(s, "off"))
+ eagerfpu = DISABLE;
+ else if (!strcmp(s, "auto"))
+ eagerfpu = AUTO;
+ return 1;
+}
+__setup("eagerfpu=", eager_fpu_setup);
+
/*
* Called at bootup to set up the initial FPU state that is later cloned
* into all processes.
@@ -197,6 +210,17 @@ void fpu_init(void)
if (xstate_size == 0)
init_thread_xstate();
+ /*
+ * We should always enable eagerfpu, but it doesn't work properly
+ * here without fpu and fxsr.
+ */
+ if (eagerfpu == AUTO)
+ eagerfpu = (boot_cpu_has(X86_FEATURE_FPU) &&
+ boot_cpu_has(X86_FEATURE_FXSR)) ?
+ ENABLE : DISABLE;
+ if (eagerfpu == ENABLE)
+ setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
+
mxcsr_feature_mask_init();
xsave_init();
eager_fpu_init();