@@ -54,9 +54,10 @@ static short xsave_cpuid_features[] __initdata = {
54
54
};
55
55
56
56
/*
57
- * Mask of xstate features supported by the CPU and the kernel:
57
+ * This represents the full set of bits that should ever be set in a kernel
58
+ * XSAVE buffer, both supervisor and user xstates.
58
59
*/
59
- u64 xfeatures_mask __read_mostly ;
60
+ u64 xfeatures_mask_all __read_mostly ;
60
61
61
62
static unsigned int xstate_offsets [XFEATURE_MAX ] = { [ 0 ... XFEATURE_MAX - 1 ] = -1 };
62
63
static unsigned int xstate_sizes [XFEATURE_MAX ] = { [ 0 ... XFEATURE_MAX - 1 ] = -1 };
@@ -76,7 +77,7 @@ unsigned int fpu_user_xstate_size;
76
77
*/
77
78
int cpu_has_xfeatures (u64 xfeatures_needed , const char * * feature_name )
78
79
{
79
- u64 xfeatures_missing = xfeatures_needed & ~xfeatures_mask ;
80
+ u64 xfeatures_missing = xfeatures_needed & ~xfeatures_mask_all ;
80
81
81
82
if (unlikely (feature_name )) {
82
83
long xfeature_idx , max_idx ;
@@ -150,7 +151,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
150
151
* None of the feature bits are in init state. So nothing else
151
152
* to do for us, as the memory layout is up to date.
152
153
*/
153
- if ((xfeatures & xfeatures_mask ) == xfeatures_mask )
154
+ if ((xfeatures & xfeatures_mask_all ) == xfeatures_mask_all )
154
155
return ;
155
156
156
157
/*
@@ -177,7 +178,7 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
177
178
* in a special way already:
178
179
*/
179
180
feature_bit = 0x2 ;
180
- xfeatures = (xfeatures_mask & ~xfeatures ) >> 2 ;
181
+ xfeatures = (xfeatures_mask_user () & ~xfeatures ) >> 2 ;
181
182
182
183
/*
183
184
* Update all the remaining memory layouts according to their
@@ -205,29 +206,38 @@ void fpstate_sanitize_xstate(struct fpu *fpu)
205
206
*/
206
207
void fpu__init_cpu_xstate (void )
207
208
{
208
- if (!boot_cpu_has (X86_FEATURE_XSAVE ) || !xfeatures_mask )
209
+ u64 unsup_bits ;
210
+
211
+ if (!boot_cpu_has (X86_FEATURE_XSAVE ) || !xfeatures_mask_all )
209
212
return ;
210
213
/*
211
214
* Unsupported supervisor xstates should not be found in
212
215
* the xfeatures mask.
213
216
*/
214
- WARN_ONCE ((xfeatures_mask & XFEATURE_MASK_SUPERVISOR_UNSUPPORTED ),
215
- "x86/fpu: Found unsupported supervisor xstates.\n" );
217
+ unsup_bits = xfeatures_mask_all & XFEATURE_MASK_SUPERVISOR_UNSUPPORTED ;
218
+ WARN_ONCE (unsup_bits , "x86/fpu: Found unsupported supervisor xstates: 0x%llx\n" ,
219
+ unsup_bits );
216
220
217
- xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR_UNSUPPORTED ;
221
+ xfeatures_mask_all &= ~XFEATURE_MASK_SUPERVISOR_UNSUPPORTED ;
218
222
219
223
cr4_set_bits (X86_CR4_OSXSAVE );
220
- xsetbv (XCR_XFEATURE_ENABLED_MASK , xfeatures_mask );
224
+
225
+ /*
226
+ * XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features
227
+ * managed by XSAVE{C, OPT, S} and XRSTOR{S}. Only XSAVE user
228
+ * states can be set here.
229
+ */
230
+ xsetbv (XCR_XFEATURE_ENABLED_MASK , xfeatures_mask_user ());
221
231
}
222
232
223
233
/*
224
234
* Note that in the future we will likely need a pair of
225
235
* functions here: one for user xstates and the other for
226
236
* system xstates. For now, they are the same.
227
237
*/
228
- static int xfeature_enabled (enum xfeature xfeature )
238
+ static bool xfeature_enabled (enum xfeature xfeature )
229
239
{
230
- return !!( xfeatures_mask & ( 1UL << xfeature ) );
240
+ return xfeatures_mask_all & BIT_ULL ( xfeature );
231
241
}
232
242
233
243
/*
@@ -414,7 +424,7 @@ static void __init setup_init_fpu_buf(void)
414
424
415
425
if (boot_cpu_has (X86_FEATURE_XSAVES ))
416
426
init_fpstate .xsave .header .xcomp_bv = XCOMP_BV_COMPACTED_FORMAT |
417
- xfeatures_mask ;
427
+ xfeatures_mask_all ;
418
428
419
429
/*
420
430
* Init all the features state with header.xfeatures being 0x0
@@ -474,7 +484,7 @@ int using_compacted_format(void)
474
484
int validate_user_xstate_header (const struct xstate_header * hdr )
475
485
{
476
486
/* No unknown or supervisor features may be set */
477
- if (hdr -> xfeatures & ~( xfeatures_mask & XFEATURE_MASK_USER_SUPPORTED ))
487
+ if (hdr -> xfeatures & ~xfeatures_mask_user ( ))
478
488
return - EINVAL ;
479
489
480
490
/* Userspace must use the uncompacted format */
@@ -609,7 +619,7 @@ static void do_extra_xstate_size_checks(void)
609
619
610
620
611
621
/*
612
- * Get total size of enabled xstates in XCR0/xfeatures_mask .
622
+ * Get total size of enabled xstates in XCR0 | IA32_XSS .
613
623
*
614
624
* Note the SDM's wording here. "sub-function 0" only enumerates
615
625
* the size of the *user* states. If we use it to size a buffer
@@ -699,7 +709,7 @@ static int __init init_xstate_size(void)
699
709
*/
700
710
static void fpu__init_disable_system_xstate (void )
701
711
{
702
- xfeatures_mask = 0 ;
712
+ xfeatures_mask_all = 0 ;
703
713
cr4_clear_bits (X86_CR4_OSXSAVE );
704
714
setup_clear_cpu_cap (X86_FEATURE_XSAVE );
705
715
}
@@ -734,16 +744,21 @@ void __init fpu__init_system_xstate(void)
734
744
return ;
735
745
}
736
746
747
+ /*
748
+ * Find user xstates supported by the processor.
749
+ */
737
750
cpuid_count (XSTATE_CPUID , 0 , & eax , & ebx , & ecx , & edx );
738
- xfeatures_mask = eax + ((u64 )edx << 32 );
751
+ xfeatures_mask_all = eax + ((u64 )edx << 32 );
739
752
740
- if ((xfeatures_mask & XFEATURE_MASK_FPSSE ) != XFEATURE_MASK_FPSSE ) {
753
+ /* Place supervisor features in xfeatures_mask_all here */
754
+ if ((xfeatures_mask_user () & XFEATURE_MASK_FPSSE ) != XFEATURE_MASK_FPSSE ) {
741
755
/*
742
756
* This indicates that something really unexpected happened
743
757
* with the enumeration. Disable XSAVE and try to continue
744
758
* booting without it. This is too early to BUG().
745
759
*/
746
- pr_err ("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n" , xfeatures_mask );
760
+ pr_err ("x86/fpu: FP/SSE not present amongst the CPU's xstate features: 0x%llx.\n" ,
761
+ xfeatures_mask_all );
747
762
goto out_disable ;
748
763
}
749
764
@@ -752,10 +767,10 @@ void __init fpu__init_system_xstate(void)
752
767
*/
753
768
for (i = 0 ; i < ARRAY_SIZE (xsave_cpuid_features ); i ++ ) {
754
769
if (!boot_cpu_has (xsave_cpuid_features [i ]))
755
- xfeatures_mask &= ~BIT (i );
770
+ xfeatures_mask_all &= ~BIT_ULL (i );
756
771
}
757
772
758
- xfeatures_mask &= fpu__get_supported_xfeatures_mask ();
773
+ xfeatures_mask_all &= fpu__get_supported_xfeatures_mask ();
759
774
760
775
/* Enable xstate instructions to be able to continue with initialization: */
761
776
fpu__init_cpu_xstate ();
@@ -767,16 +782,15 @@ void __init fpu__init_system_xstate(void)
767
782
* Update info used for ptrace frames; use standard-format size and no
768
783
* supervisor xstates:
769
784
*/
770
- update_regset_xstate_info (fpu_user_xstate_size ,
771
- xfeatures_mask & XFEATURE_MASK_USER_SUPPORTED );
785
+ update_regset_xstate_info (fpu_user_xstate_size , xfeatures_mask_user ());
772
786
773
787
fpu__init_prepare_fx_sw_frame ();
774
788
setup_init_fpu_buf ();
775
789
setup_xstate_comp_offsets ();
776
790
print_xstate_offset_size ();
777
791
778
792
pr_info ("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n" ,
779
- xfeatures_mask ,
793
+ xfeatures_mask_all ,
780
794
fpu_kernel_xstate_size ,
781
795
boot_cpu_has (X86_FEATURE_XSAVES ) ? "compacted" : "standard" );
782
796
return ;
@@ -795,7 +809,7 @@ void fpu__resume_cpu(void)
795
809
* Restore XCR0 on xsave capable CPUs:
796
810
*/
797
811
if (boot_cpu_has (X86_FEATURE_XSAVE ))
798
- xsetbv (XCR_XFEATURE_ENABLED_MASK , xfeatures_mask );
812
+ xsetbv (XCR_XFEATURE_ENABLED_MASK , xfeatures_mask_user () );
799
813
}
800
814
801
815
/*
@@ -840,10 +854,9 @@ void *get_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
840
854
841
855
/*
842
856
* We should not ever be requesting features that we
843
- * have not enabled. Remember that xfeatures_mask is
844
- * what we write to the XCR0 register.
857
+ * have not enabled.
845
858
*/
846
- WARN_ONCE (!(xfeatures_mask & BIT_ULL (xfeature_nr )),
859
+ WARN_ONCE (!(xfeatures_mask_all & BIT_ULL (xfeature_nr )),
847
860
"get of unsupported state" );
848
861
/*
849
862
* This assumes the last 'xsave*' instruction to
@@ -996,7 +1009,7 @@ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int of
996
1009
*/
997
1010
memset (& header , 0 , sizeof (header ));
998
1011
header .xfeatures = xsave -> header .xfeatures ;
999
- header .xfeatures &= XFEATURE_MASK_USER_SUPPORTED ;
1012
+ header .xfeatures &= xfeatures_mask_user () ;
1000
1013
1001
1014
/*
1002
1015
* Copy xregs_state->header:
@@ -1080,7 +1093,7 @@ int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned i
1080
1093
*/
1081
1094
memset (& header , 0 , sizeof (header ));
1082
1095
header .xfeatures = xsave -> header .xfeatures ;
1083
- header .xfeatures &= XFEATURE_MASK_USER_SUPPORTED ;
1096
+ header .xfeatures &= xfeatures_mask_user () ;
1084
1097
1085
1098
/*
1086
1099
* Copy xregs_state->header:
0 commit comments