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();