aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryu-cheng yu <yu-cheng.yu@intel.com>2016-01-06 17:24:53 -0500
committerIngo Molnar <mingo@kernel.org>2016-01-12 05:51:21 -0500
commita5fe93a549c54838063d2952dd9643b0b18aa67f (patch)
tree21f291bf9c27b7e62182b4ced5be5696f0b5396b
parenteb7c5f872e697b0aebd846cf3a3328d71e9decb2 (diff)
x86/fpu: Disable MPX when eagerfpu is off
This issue is a fallout from the command-line parsing move. When "eagerfpu=off" is given as a command-line input, the kernel should disable MPX support. The decision for turning off MPX was made in fpu__init_system_ctx_switch(), which is after the selection of the XSAVE format. This patch fixes it by getting that decision done earlier in fpu__init_system_xstate(). Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Borislav Petkov <bp@suse.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com> Cc: Ravi V. Shankar <ravi.v.shankar@intel.com> Cc: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: yu-cheng yu <yu-cheng.yu@intel.com> Link: http://lkml.kernel.org/r/1452119094-7252-4-git-send-email-yu-cheng.yu@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/include/asm/fpu/internal.h1
-rw-r--r--arch/x86/kernel/fpu/init.c56
-rw-r--r--arch/x86/kernel/fpu/xstate.c3
3 files changed, 46 insertions, 14 deletions
diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
index eadcdd5bb946..0fd440df63f1 100644
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -42,6 +42,7 @@ extern void fpu__init_cpu_xstate(void);
42extern void fpu__init_system(struct cpuinfo_x86 *c); 42extern void fpu__init_system(struct cpuinfo_x86 *c);
43extern void fpu__init_check_bugs(void); 43extern void fpu__init_check_bugs(void);
44extern void fpu__resume_cpu(void); 44extern void fpu__resume_cpu(void);
45extern u64 fpu__get_supported_xfeatures_mask(void);
45 46
46/* 47/*
47 * Debugging facility: 48 * Debugging facility:
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
index 3a45fcd0b924..f0ab36844a6d 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -274,7 +274,45 @@ static void __init fpu__init_system_xstate_size_legacy(void)
274static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; 274static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO;
275 275
276/* 276/*
277 * Find supported xfeatures based on cpu features and command-line input.
278 * This must be called after fpu__init_parse_early_param() is called and
279 * xfeatures_mask is enumerated.
280 */
281u64 __init fpu__get_supported_xfeatures_mask(void)
282{
283 /* Support all xfeatures known to us */
284 if (eagerfpu != DISABLE)
285 return XCNTXT_MASK;
286
287 /* Warning of xfeatures being disabled for no eagerfpu mode */
288 if (xfeatures_mask & XFEATURE_MASK_EAGER) {
289 pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
290 xfeatures_mask & XFEATURE_MASK_EAGER);
291 }
292
293 /* Return a mask that masks out all features requiring eagerfpu mode */
294 return ~XFEATURE_MASK_EAGER;
295}
296
297/*
298 * Disable features dependent on eagerfpu.
299 */
300static void __init fpu__clear_eager_fpu_features(void)
301{
302 setup_clear_cpu_cap(X86_FEATURE_MPX);
303}
304
305/*
277 * Pick the FPU context switching strategy: 306 * Pick the FPU context switching strategy:
307 *
308 * When eagerfpu is AUTO or ENABLE, we ensure it is ENABLE if either of
309 * the following is true:
310 *
311 * (1) the cpu has xsaveopt, as it has the optimization and doing eager
312 * FPU switching has a relatively low cost compared to a plain xsave;
313 * (2) the cpu has xsave features (e.g. MPX) that depend on eager FPU
314 * switching. Should the kernel boot with noxsaveopt, we support MPX
315 * with eager FPU switching at a higher cost.
278 */ 316 */
279static void __init fpu__init_system_ctx_switch(void) 317static void __init fpu__init_system_ctx_switch(void)
280{ 318{
@@ -286,19 +324,11 @@ static void __init fpu__init_system_ctx_switch(void)
286 WARN_ON_FPU(current->thread.fpu.fpstate_active); 324 WARN_ON_FPU(current->thread.fpu.fpstate_active);
287 current_thread_info()->status = 0; 325 current_thread_info()->status = 0;
288 326
289 /* Auto enable eagerfpu for xsaveopt */
290 if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE) 327 if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE)
291 eagerfpu = ENABLE; 328 eagerfpu = ENABLE;
292 329
293 if (xfeatures_mask & XFEATURE_MASK_EAGER) { 330 if (xfeatures_mask & XFEATURE_MASK_EAGER)
294 if (eagerfpu == DISABLE) { 331 eagerfpu = ENABLE;
295 pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
296 xfeatures_mask & XFEATURE_MASK_EAGER);
297 xfeatures_mask &= ~XFEATURE_MASK_EAGER;
298 } else {
299 eagerfpu = ENABLE;
300 }
301 }
302 332
303 if (eagerfpu == ENABLE) 333 if (eagerfpu == ENABLE)
304 setup_force_cpu_cap(X86_FEATURE_EAGER_FPU); 334 setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
@@ -316,10 +346,12 @@ static void __init fpu__init_parse_early_param(void)
316 * No need to check "eagerfpu=auto" again, since it is the 346 * No need to check "eagerfpu=auto" again, since it is the
317 * initial default. 347 * initial default.
318 */ 348 */
319 if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) 349 if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) {
320 eagerfpu = DISABLE; 350 eagerfpu = DISABLE;
321 else if (cmdline_find_option_bool(boot_command_line, "eagerfpu=on")) 351 fpu__clear_eager_fpu_features();
352 } else if (cmdline_find_option_bool(boot_command_line, "eagerfpu=on")) {
322 eagerfpu = ENABLE; 353 eagerfpu = ENABLE;
354 }
323 355
324 if (cmdline_find_option_bool(boot_command_line, "no387")) 356 if (cmdline_find_option_bool(boot_command_line, "no387"))
325 setup_clear_cpu_cap(X86_FEATURE_FPU); 357 setup_clear_cpu_cap(X86_FEATURE_FPU);
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index d489f277a8a0..d425cda5ae6d 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -633,8 +633,7 @@ void __init fpu__init_system_xstate(void)
633 BUG(); 633 BUG();
634 } 634 }
635 635
636 /* Support only the state known to the OS: */ 636 xfeatures_mask &= fpu__get_supported_xfeatures_mask();
637 xfeatures_mask = xfeatures_mask & XCNTXT_MASK;
638 637
639 /* Enable xstate instructions to be able to continue with initialization: */ 638 /* Enable xstate instructions to be able to continue with initialization: */
640 fpu__init_cpu_xstate(); 639 fpu__init_cpu_xstate();