diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 40621ee4d65b..d2f7ce45d4de 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -702,6 +702,11 @@ static int __init init_xstate_size(void) fpu_user_cfg.default_size = xstate_calculate_size(fpu_user_cfg.default_features, false); + guest_default_cfg.size = + xstate_calculate_size(guest_default_cfg.features, compacted); + guest_default_cfg.user_size = + xstate_calculate_size(guest_default_cfg.user_features, false); + return 0; } @@ -730,6 +735,30 @@ static void __init fpu__init_disable_system_xstate(unsigned int legacy_size) fpstate_reset(¤t->thread.fpu); } +static void __init init_default_features(u64 kernel_max_features, u64 user_max_features) +{ + u64 kfeatures = kernel_max_features; + u64 ufeatures = user_max_features; + + /* + * Default feature sets should not include dynamic and guest-only + * xfeatures at all: + */ + kfeatures &= ~(XFEATURE_MASK_USER_DYNAMIC | XFEATURE_MASK_GUEST_SUPERVISOR); + ufeatures &= ~XFEATURE_MASK_USER_DYNAMIC; + + fpu_kernel_cfg.default_features = kfeatures; + fpu_user_cfg.default_features = ufeatures; + + /* + * Ensure VCPU FPU container only reserves a space for + * guest-exclusive xfeatures. This distinction can save kernel + * memory by maintaining a necessary amount of XSAVE buffer. + */ + guest_default_cfg.features = kfeatures | xfeatures_mask_guest_supervisor(); + guest_default_cfg.user_features = ufeatures; +} + /* * Enable and initialize the xsave feature. * Called once per system bootup. @@ -801,12 +830,8 @@ void __init fpu__init_system_xstate(unsigned int legacy_size) fpu_user_cfg.max_features = fpu_kernel_cfg.max_features; fpu_user_cfg.max_features &= XFEATURE_MASK_USER_SUPPORTED; - /* Clean out dynamic features from default */ - fpu_kernel_cfg.default_features = fpu_kernel_cfg.max_features; - fpu_kernel_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC; - - fpu_user_cfg.default_features = fpu_user_cfg.max_features; - fpu_user_cfg.default_features &= ~XFEATURE_MASK_USER_DYNAMIC; + /* Now, given maximum feature set, determin default values: */ + init_default_features(fpu_kernel_cfg.max_features, fpu_user_cfg.max_features); /* Store it for paranoia check at the end */ xfeatures = fpu_kernel_cfg.max_features;