[RFC PATCH 02/10] x86/fpu: Split fpu_xfd_enabled from fpu_state_size_dynamic

From: Jiaxun Yang
Date: Thu Dec 02 2021 - 19:36:51 EST


Following patches will make fpu_state_size_dynamic nolonger depend
on XFD, so split XFD related static branch from fpu_state_size_dynamic.

Also make fpu_state_size_dynamic available on both x86 and x86_64.

Signed-off-by: Jiaxun Yang <j.yang-87@xxxxxxxxxxxx>
---
arch/x86/include/asm/fpu/xstate.h | 11 +++++++++--
arch/x86/kernel/fpu/core.c | 3 ++-
arch/x86/kernel/fpu/xstate.c | 31 +++++++++++++++++++------------
arch/x86/kernel/fpu/xstate.h | 2 +-
4 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
index fb83534e92f6..c46d3dd591bd 100644
--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -111,15 +111,22 @@ void xrstors(struct xregs_state *xsave, u64 mask);

int xfd_enable_feature(u64 xfd_err);

-#ifdef CONFIG_X86_64
DECLARE_STATIC_KEY_FALSE(__fpu_state_size_dynamic);

static __always_inline __pure bool fpu_state_size_dynamic(void)
{
return static_branch_unlikely(&__fpu_state_size_dynamic);
}
+
+#ifdef CONFIG_X86_64
+DECLARE_STATIC_KEY_FALSE(__fpu_xfd_enabled);
+
+static __always_inline __pure bool fpu_xfd_enabled(void)
+{
+ return static_branch_unlikely(&__fpu_xfd_enabled);
+}
#else
-static __always_inline __pure bool fpu_state_size_dynamic(void)
+static __always_inline __pure bool fpu_xfd_enabled(void)
{
return false;
}
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index dd3777ac0443..88dbbbde7a3a 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -26,8 +26,9 @@
#define CREATE_TRACE_POINTS
#include <asm/trace/fpu.h>

-#ifdef CONFIG_X86_64
DEFINE_STATIC_KEY_FALSE(__fpu_state_size_dynamic);
+#ifdef CONFIG_X86_64
+DEFINE_STATIC_KEY_FALSE(__fpu_xfd_enabled);
DEFINE_PER_CPU(u64, xfd_state);
#endif

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index d28829403ed0..353c661f8027 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -995,7 +995,7 @@ void fpu__resume_cpu(void)
xfeatures_mask_independent());
}

- if (fpu_state_size_dynamic())
+ if (fpu_xfd_enabled())
wrmsrl(MSR_IA32_XFD, current->thread.fpu.fpstate->xfd);
}

@@ -1422,6 +1422,23 @@ void fpstate_clear_xstate_component(struct fpstate *fps, unsigned int xfeature)
EXPORT_SYMBOL_GPL(fpstate_clear_xstate_component);
#endif

+static int __init xstate_update_static_branch(void)
+{
+ if (fpu_kernel_cfg.max_features != fpu_kernel_cfg.default_features)
+ static_branch_enable(&__fpu_state_size_dynamic);
+
+#ifdef CONFIG_X86_64
+ /*
+ * If init_fpstate.xfd has bits set then dynamic features are
+ * available and the dynamic sizing must be enabled.
+ */
+ if (init_fpstate.xfd)
+ static_branch_enable(&__fpu_xfd_enabled);
+#endif
+ return 0;
+}
+arch_initcall(xstate_update_static_branch)
+
#ifdef CONFIG_X86_64

#ifdef CONFIG_X86_DEBUG_FPU
@@ -1481,17 +1498,7 @@ void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rstor)
}
#endif /* CONFIG_X86_DEBUG_FPU */

-static int __init xfd_update_static_branch(void)
-{
- /*
- * If init_fpstate.xfd has bits set then dynamic features are
- * available and the dynamic sizing must be enabled.
- */
- if (init_fpstate.xfd)
- static_branch_enable(&__fpu_state_size_dynamic);
- return 0;
-}
-arch_initcall(xfd_update_static_branch)
+

void fpstate_free(struct fpu *fpu)
{
diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h
index 86ea7c0fa2f6..f6bebaeea4ad 100644
--- a/arch/x86/kernel/fpu/xstate.h
+++ b/arch/x86/kernel/fpu/xstate.h
@@ -140,7 +140,7 @@ static inline void xfd_validate_state(struct fpstate *fpstate, u64 mask, bool rs
#ifdef CONFIG_X86_64
static inline void xfd_update_state(struct fpstate *fpstate)
{
- if (fpu_state_size_dynamic()) {
+ if (fpu_xfd_enabled()) {
u64 xfd = fpstate->xfd;

if (__this_cpu_read(xfd_state) != xfd) {
--
2.30.2