@@ -142,7 +142,8 @@ static unsigned int xfeature_get_offset(u64 xcomp_bv, int xfeature)
142142 * Non-compacted format and legacy features use the cached fixed
143143 * offsets.
144144 */
145- if (!cpu_feature_enabled (X86_FEATURE_XSAVES ) || xfeature <= XFEATURE_SSE )
145+ if (!cpu_feature_enabled (X86_FEATURE_XCOMPACTED ) ||
146+ xfeature <= XFEATURE_SSE )
146147 return xstate_offsets [xfeature ];
147148
148149 /*
@@ -369,12 +370,12 @@ static void __init setup_init_fpu_buf(void)
369370 /*
370371 * All components are now in init state. Read the state back so
371372 * that init_fpstate contains all non-zero init state. This only
372- * works with XSAVE, but not with XSAVEOPT and XSAVES because
373+ * works with XSAVE, but not with XSAVEOPT and XSAVEC/S because
373374 * those use the init optimization which skips writing data for
374375 * components in init state.
375376 *
376377 * XSAVE could be used, but that would require to reshuffle the
377- * data when XSAVES is available because XSAVES uses xstate
378+ * data when XSAVEC/S is available because XSAVEC/S uses xstate
378379 * compaction. But doing so is a pointless exercise because most
379380 * components have an all zeros init state except for the legacy
380381 * ones (FP and SSE). Those can be saved with FXSAVE into the
@@ -584,7 +585,8 @@ static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
584585 */
585586static bool __init paranoid_xstate_size_valid (unsigned int kernel_size )
586587{
587- bool compacted = cpu_feature_enabled (X86_FEATURE_XSAVES );
588+ bool compacted = cpu_feature_enabled (X86_FEATURE_XCOMPACTED );
589+ bool xsaves = cpu_feature_enabled (X86_FEATURE_XSAVES );
588590 unsigned int size = FXSAVE_SIZE + XSAVE_HDR_SIZE ;
589591 int i ;
590592
@@ -595,7 +597,7 @@ static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
595597 * Supervisor state components can be managed only by
596598 * XSAVES.
597599 */
598- if (!compacted && xfeature_is_supervisor (i )) {
600+ if (!xsaves && xfeature_is_supervisor (i )) {
599601 XSTATE_WARN_ON (1 );
600602 return false;
601603 }
@@ -612,8 +614,11 @@ static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
612614 * the size of the *user* states. If we use it to size a buffer
613615 * that we use 'XSAVES' on, we could potentially overflow the
614616 * buffer because 'XSAVES' saves system states too.
617+ *
618+ * This also takes compaction into account. So this works for
619+ * XSAVEC as well.
615620 */
616- static unsigned int __init get_xsaves_size (void )
621+ static unsigned int __init get_compacted_size (void )
617622{
618623 unsigned int eax , ebx , ecx , edx ;
619624 /*
@@ -623,6 +628,10 @@ static unsigned int __init get_xsaves_size(void)
623628 * containing all the state components
624629 * corresponding to bits currently set in
625630 * XCR0 | IA32_XSS.
631+ *
632+ * When XSAVES is not available but XSAVEC is (virt), then there
633+ * are no supervisor states, but XSAVEC still uses compacted
634+ * format.
626635 */
627636 cpuid_count (XSTATE_CPUID , 1 , & eax , & ebx , & ecx , & edx );
628637 return ebx ;
@@ -632,13 +641,13 @@ static unsigned int __init get_xsaves_size(void)
632641 * Get the total size of the enabled xstates without the independent supervisor
633642 * features.
634643 */
635- static unsigned int __init get_xsaves_size_no_independent (void )
644+ static unsigned int __init get_xsave_compacted_size (void )
636645{
637646 u64 mask = xfeatures_mask_independent ();
638647 unsigned int size ;
639648
640649 if (!mask )
641- return get_xsaves_size ();
650+ return get_compacted_size ();
642651
643652 /* Disable independent features. */
644653 wrmsrl (MSR_IA32_XSS , xfeatures_mask_supervisor ());
@@ -647,7 +656,7 @@ static unsigned int __init get_xsaves_size_no_independent(void)
647656 * Ask the hardware what size is required of the buffer.
648657 * This is the size required for the task->fpu buffer.
649658 */
650- size = get_xsaves_size ();
659+ size = get_compacted_size ();
651660
652661 /* Re-enable independent features so XSAVES will work on them again. */
653662 wrmsrl (MSR_IA32_XSS , xfeatures_mask_supervisor () | mask );
@@ -687,20 +696,21 @@ static int __init init_xstate_size(void)
687696{
688697 /* Recompute the context size for enabled features: */
689698 unsigned int user_size , kernel_size , kernel_default_size ;
690- bool compacted = cpu_feature_enabled (X86_FEATURE_XSAVES );
699+ bool compacted = cpu_feature_enabled (X86_FEATURE_XCOMPACTED );
691700
692701 /* Uncompacted user space size */
693702 user_size = get_xsave_size_user ();
694703
695704 /*
696- * XSAVES kernel size includes supervisor states and
697- * uses compacted format when available.
705+ * XSAVES kernel size includes supervisor states and uses compacted
706+ * format. XSAVEC uses compacted format, but does not save
707+ * supervisor states.
698708 *
699- * XSAVE does not support supervisor states so
700- * kernel and user size is identical.
709+ * XSAVE[OPT] do not support supervisor states so kernel and user
710+ * size is identical.
701711 */
702712 if (compacted )
703- kernel_size = get_xsaves_size_no_independent ();
713+ kernel_size = get_xsave_compacted_size ();
704714 else
705715 kernel_size = user_size ;
706716
@@ -813,8 +823,11 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
813823 if (!cpu_feature_enabled (X86_FEATURE_XFD ))
814824 fpu_kernel_cfg .max_features &= ~XFEATURE_MASK_USER_DYNAMIC ;
815825
816- fpu_kernel_cfg .max_features &= XFEATURE_MASK_USER_SUPPORTED |
817- XFEATURE_MASK_SUPERVISOR_SUPPORTED ;
826+ if (!cpu_feature_enabled (X86_FEATURE_XSAVES ))
827+ fpu_kernel_cfg .max_features &= XFEATURE_MASK_USER_SUPPORTED ;
828+ else
829+ fpu_kernel_cfg .max_features &= XFEATURE_MASK_USER_SUPPORTED |
830+ XFEATURE_MASK_SUPERVISOR_SUPPORTED ;
818831
819832 fpu_user_cfg .max_features = fpu_kernel_cfg .max_features ;
820833 fpu_user_cfg .max_features &= XFEATURE_MASK_USER_SUPPORTED ;
@@ -837,6 +850,11 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
837850 */
838851 init_fpstate .xfd = fpu_user_cfg .max_features & XFEATURE_MASK_USER_DYNAMIC ;
839852
853+ /* Set up compaction feature bit */
854+ if (cpu_feature_enabled (X86_FEATURE_XSAVEC ) ||
855+ cpu_feature_enabled (X86_FEATURE_XSAVES ))
856+ setup_force_cpu_cap (X86_FEATURE_XCOMPACTED );
857+
840858 /* Enable xstate instructions to be able to continue with initialization: */
841859 fpu__init_cpu_xstate ();
842860
@@ -873,7 +891,7 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
873891 pr_info ("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n" ,
874892 fpu_kernel_cfg .max_features ,
875893 fpu_kernel_cfg .max_size ,
876- boot_cpu_has (X86_FEATURE_XSAVES ) ? "compacted" : "standard" );
894+ boot_cpu_has (X86_FEATURE_XCOMPACTED ) ? "compacted" : "standard" );
877895 return ;
878896
879897out_disable :
@@ -917,7 +935,7 @@ static void *__raw_xsave_addr(struct xregs_state *xsave, int xfeature_nr)
917935 if (WARN_ON_ONCE (!xfeature_enabled (xfeature_nr )))
918936 return NULL ;
919937
920- if (cpu_feature_enabled (X86_FEATURE_XSAVES )) {
938+ if (cpu_feature_enabled (X86_FEATURE_XCOMPACTED )) {
921939 if (WARN_ON_ONCE (!(xcomp_bv & BIT_ULL (xfeature_nr ))))
922940 return NULL ;
923941 }
@@ -1215,7 +1233,7 @@ static int copy_uabi_to_xstate(struct fpstate *fpstate, const void *kbuf,
12151233 }
12161234
12171235 for (i = 0 ; i < XFEATURE_MAX ; i ++ ) {
1218- u64 mask = (( u64 ) 1 << i );
1236+ mask = BIT_ULL ( i );
12191237
12201238 if (hdr .xfeatures & mask ) {
12211239 void * dst = __raw_xsave_addr (xsave , i );
@@ -1525,7 +1543,7 @@ static int __xstate_request_perm(u64 permitted, u64 requested, bool guest)
15251543 * vendors into extending XFD for the pre AMX states, especially
15261544 * AVX512.
15271545 */
1528- bool compacted = cpu_feature_enabled (X86_FEATURE_XSAVES );
1546+ bool compacted = cpu_feature_enabled (X86_FEATURE_XCOMPACTED );
15291547 struct fpu * fpu = & current -> group_leader -> thread .fpu ;
15301548 struct fpu_state_perm * perm ;
15311549 unsigned int ksize , usize ;
0 commit comments