@@ -600,8 +600,9 @@ struct fpu_state_config {
* @default_size:
*
* The default size of the register state buffer. Includes all
- * supported features except independent managed features and
- * features which have to be requested by user space before usage.
+ * supported features except independent managed features,
+ * guest-only features and features which have to be requested by
+ * user space before usage.
*/
unsigned int default_size;
@@ -617,8 +618,8 @@ struct fpu_state_config {
* @default_features:
*
* The default supported features bitmap. Does not include
- * independent managed features and features which have to
- * be requested by user space before usage.
+ * independent managed features, guest-only features and features
+ * which have to be requested by user space before usage.
*/
u64 default_features;
/*
@@ -45,9 +45,13 @@
/* Features which are dynamically enabled for a process on request */
#define XFEATURE_MASK_USER_DYNAMIC XFEATURE_MASK_XTILE_DATA
+/* Supervisor features which are enabled only in guest FPUs */
+#define XFEATURE_MASK_GUEST_SUPERVISOR 0
+
/* All currently supported supervisor features */
#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (XFEATURE_MASK_PASID | \
- XFEATURE_MASK_CET_USER)
+ XFEATURE_MASK_CET_USER | \
+ XFEATURE_MASK_GUEST_SUPERVISOR)
/*
* A supervisor state component may not always contain valuable information,
@@ -776,14 +776,22 @@ static void __init init_default_features(u64 kernel_max_features, u64 user_max_f
u64 kfeatures = kernel_max_features;
u64 ufeatures = user_max_features;
- /* Default feature sets should not include dynamic xfeatures. */
- kfeatures &= ~XFEATURE_MASK_USER_DYNAMIC;
+ /*
+ * 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;
- guest_default_cfg.features = kfeatures;
+ /*
+ * Ensure VCPU FPU container only reserves a space for guest-only
+ * 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;
}
@@ -61,6 +61,11 @@ static inline u64 xfeatures_mask_supervisor(void)
return fpu_kernel_cfg.max_features & XFEATURE_MASK_SUPERVISOR_SUPPORTED;
}
+static inline u64 xfeatures_mask_guest_supervisor(void)
+{
+ return fpu_kernel_cfg.max_features & XFEATURE_MASK_GUEST_SUPERVISOR;
+}
+
static inline u64 xfeatures_mask_independent(void)
{
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))