--- /dev/null
+From e45122893a9870813f9bd7b4add4f613e6f29008 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Wed, 20 Jan 2021 21:09:48 -0800
+Subject: x86/fpu: Add kernel_fpu_begin_mask() to selectively initialize state
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit e45122893a9870813f9bd7b4add4f613e6f29008 upstream.
+
+Currently, requesting kernel FPU access doesn't distinguish which parts of
+the extended ("FPU") state are needed. This is nice for simplicity, but
+there are a few cases in which it's suboptimal:
+
+ - The vast majority of in-kernel FPU users want XMM/YMM/ZMM state but do
+ not use legacy 387 state. These users want MXCSR initialized but don't
+ care about the FPU control word. Skipping FNINIT would save time.
+ (Empirically, FNINIT is several times slower than LDMXCSR.)
+
+ - Code that wants MMX doesn't want or need MXCSR initialized.
+ _mmx_memcpy(), for example, can run before CR4.OSFXSR gets set, and
+ initializing MXCSR will fail because LDMXCSR generates an #UD when the
+ aforementioned CR4 bit is not set.
+
+ - Any future in-kernel users of XFD (eXtended Feature Disable)-capable
+ dynamic states will need special handling.
+
+Add a more specific API that allows callers to specify exactly what they
+want.
+
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Tested-by: Krzysztof Piotr Olędzki <ole@ans.pl>
+Link: https://lkml.kernel.org/r/aff1cac8b8fc7ee900cf73e8f2369966621b053f.1611205691.git.luto@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/fpu/api.h | 15 +++++++++++++--
+ arch/x86/kernel/fpu/core.c | 9 +++++----
+ 2 files changed, 18 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/include/asm/fpu/api.h
++++ b/arch/x86/include/asm/fpu/api.h
+@@ -16,14 +16,25 @@
+ * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It
+ * disables preemption so be careful if you intend to use it for long periods
+ * of time.
+- * If you intend to use the FPU in softirq you need to check first with
++ * If you intend to use the FPU in irq/softirq you need to check first with
+ * irq_fpu_usable() if it is possible.
+ */
+-extern void kernel_fpu_begin(void);
++
++/* Kernel FPU states to initialize in kernel_fpu_begin_mask() */
++#define KFPU_387 _BITUL(0) /* 387 state will be initialized */
++#define KFPU_MXCSR _BITUL(1) /* MXCSR will be initialized */
++
++extern void kernel_fpu_begin_mask(unsigned int kfpu_mask);
+ extern void kernel_fpu_end(void);
+ extern bool irq_fpu_usable(void);
+ extern void fpregs_mark_activate(void);
+
++/* Code that is unaware of kernel_fpu_begin_mask() can use this */
++static inline void kernel_fpu_begin(void)
++{
++ kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR);
++}
++
+ /*
+ * Use fpregs_lock() while editing CPU's FPU registers or fpu->state.
+ * A context switch will (and softirq might) save CPU's FPU registers to
+--- a/arch/x86/kernel/fpu/core.c
++++ b/arch/x86/kernel/fpu/core.c
+@@ -121,7 +121,7 @@ int copy_fpregs_to_fpstate(struct fpu *f
+ }
+ EXPORT_SYMBOL(copy_fpregs_to_fpstate);
+
+-void kernel_fpu_begin(void)
++void kernel_fpu_begin_mask(unsigned int kfpu_mask)
+ {
+ preempt_disable();
+
+@@ -141,13 +141,14 @@ void kernel_fpu_begin(void)
+ }
+ __cpu_invalidate_fpregs_state();
+
+- if (boot_cpu_has(X86_FEATURE_XMM))
++ /* Put sane initial values into the control registers. */
++ if (likely(kfpu_mask & KFPU_MXCSR) && boot_cpu_has(X86_FEATURE_XMM))
+ ldmxcsr(MXCSR_DEFAULT);
+
+- if (boot_cpu_has(X86_FEATURE_FPU))
++ if (unlikely(kfpu_mask & KFPU_387) && boot_cpu_has(X86_FEATURE_FPU))
+ asm volatile ("fninit");
+ }
+-EXPORT_SYMBOL_GPL(kernel_fpu_begin);
++EXPORT_SYMBOL_GPL(kernel_fpu_begin_mask);
+
+ void kernel_fpu_end(void)
+ {