Skip to content

Commit 2ae996e

Browse files
ChangSeokBaesuryasaimadhu
authored andcommitted
x86/fpu: Calculate the default sizes independently
When dynamically enabled states are supported the maximum and default sizes for the kernel buffers and user space interfaces are not longer identical. Put the necessary calculations in place which only take the default enabled features into account. Signed-off-by: Chang S. Bae <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent eec2113 commit 2ae996e

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

arch/x86/kernel/fpu/xstate.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -781,35 +781,40 @@ static bool __init is_supported_xstate_size(unsigned int test_xstate_size)
781781
static int __init init_xstate_size(void)
782782
{
783783
/* Recompute the context size for enabled features: */
784-
unsigned int user_size, kernel_size;
784+
unsigned int user_size, kernel_size, kernel_default_size;
785+
bool compacted = cpu_feature_enabled(X86_FEATURE_XSAVES);
785786

786787
/* Uncompacted user space size */
787788
user_size = get_xsave_size_user();
788789

789790
/*
790791
* XSAVES kernel size includes supervisor states and
791-
* uses compacted format.
792+
* uses compacted format when available.
792793
*
793794
* XSAVE does not support supervisor states so
794795
* kernel and user size is identical.
795796
*/
796-
if (cpu_feature_enabled(X86_FEATURE_XSAVES))
797+
if (compacted)
797798
kernel_size = get_xsaves_size_no_independent();
798799
else
799800
kernel_size = user_size;
800801

801-
/* Ensure we have the space to store all enabled features. */
802-
if (!is_supported_xstate_size(kernel_size))
802+
kernel_default_size =
803+
xstate_calculate_size(fpu_kernel_cfg.default_features, compacted);
804+
805+
/* Ensure we have the space to store all default enabled features. */
806+
if (!is_supported_xstate_size(kernel_default_size))
803807
return -EINVAL;
804808

805809
if (!paranoid_xstate_size_valid(kernel_size))
806810
return -EINVAL;
807811

808-
/* Keep it the same for now */
809812
fpu_kernel_cfg.max_size = kernel_size;
810-
fpu_kernel_cfg.default_size = kernel_size;
811813
fpu_user_cfg.max_size = user_size;
812-
fpu_user_cfg.default_size = user_size;
814+
815+
fpu_kernel_cfg.default_size = kernel_default_size;
816+
fpu_user_cfg.default_size =
817+
xstate_calculate_size(fpu_user_cfg.default_features, false);
813818

814819
return 0;
815820
}
@@ -894,15 +899,21 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
894899
fpu_kernel_cfg.max_features &= ~BIT_ULL(i);
895900
}
896901

902+
if (!cpu_feature_enabled(X86_FEATURE_XFD))
903+
fpu_kernel_cfg.max_features &= ~XFEATURE_MASK_USER_DYNAMIC;
904+
897905
fpu_kernel_cfg.max_features &= XFEATURE_MASK_USER_SUPPORTED |
898906
XFEATURE_MASK_SUPERVISOR_SUPPORTED;
899907

900908
fpu_user_cfg.max_features = fpu_kernel_cfg.max_features;
901909
fpu_user_cfg.max_features &= XFEATURE_MASK_USER_SUPPORTED;
902910

903-
/* Identical for now */
911+
/* Clean out dynamic features from default */
904912
fpu_kernel_cfg.default_features = fpu_kernel_cfg.max_features;
913+
fpu_kernel_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC;
914+
905915
fpu_user_cfg.default_features = fpu_user_cfg.max_features;
916+
fpu_user_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC;
906917

907918
/* Store it for paranoia check at the end */
908919
xfeatures = fpu_kernel_cfg.max_features;
@@ -913,6 +924,7 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
913924
if (err)
914925
goto out_disable;
915926

927+
/* Reset the state for the current task */
916928
fpstate_reset(&current->thread.fpu);
917929

918930
/*

0 commit comments

Comments
 (0)