@@ -273,8 +273,46 @@ static void __init fpu__init_system_xstate_size_legacy(void)
273
273
*/
274
274
static enum { AUTO , ENABLE , DISABLE } eagerfpu = AUTO ;
275
275
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
+ */
281
+ u64 __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
+ */
300
+ static void __init fpu__clear_eager_fpu_features (void )
301
+ {
302
+ setup_clear_cpu_cap (X86_FEATURE_MPX );
303
+ }
304
+
276
305
/*
277
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
*/
279
317
static void __init fpu__init_system_ctx_switch (void )
280
318
{
@@ -286,19 +324,11 @@ static void __init fpu__init_system_ctx_switch(void)
286
324
WARN_ON_FPU (current -> thread .fpu .fpstate_active );
287
325
current_thread_info ()-> status = 0 ;
288
326
289
- /* Auto enable eagerfpu for xsaveopt */
290
327
if (boot_cpu_has (X86_FEATURE_XSAVEOPT ) && eagerfpu != DISABLE )
291
328
eagerfpu = ENABLE ;
292
329
293
- if (xfeatures_mask & XFEATURE_MASK_EAGER ) {
294
- if (eagerfpu == DISABLE ) {
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
- }
330
+ if (xfeatures_mask & XFEATURE_MASK_EAGER )
331
+ eagerfpu = ENABLE ;
302
332
303
333
if (eagerfpu == ENABLE )
304
334
setup_force_cpu_cap (X86_FEATURE_EAGER_FPU );
@@ -316,10 +346,12 @@ static void __init fpu__init_parse_early_param(void)
316
346
* No need to check "eagerfpu=auto" again, since it is the
317
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
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
353
eagerfpu = ENABLE ;
354
+ }
323
355
324
356
if (cmdline_find_option_bool (boot_command_line , "no387" ))
325
357
setup_clear_cpu_cap (X86_FEATURE_FPU );
0 commit comments