From 0b55bb51916f446629f5f8183c125d834fea8b1a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Jan 2021 09:28:17 +0100 Subject: [PATCH] 5.10-stable patches added patches: x86-fpu-add-kernel_fpu_begin_mask-to-selectively-initialize-state.patch --- queue-5.10/series | 1 + ...mask-to-selectively-initialize-state.patch | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 queue-5.10/x86-fpu-add-kernel_fpu_begin_mask-to-selectively-initialize-state.patch diff --git a/queue-5.10/series b/queue-5.10/series index b3ffe95e03f..affe4c15002 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -116,6 +116,7 @@ counter-ti-eqep-remove-floor.patch powerpc-64s-fix-scv-entry-fallback-flush-vs-interrupt.patch cifs-do-not-fail-__smb_send_rqst-if-non-fatal-signals-are-pending.patch irqchip-mips-cpu-set-ipi-domain-parent-chip.patch +x86-fpu-add-kernel_fpu_begin_mask-to-selectively-initialize-state.patch x86-mmx-use-kfpu_387-for-mmx-string-operations.patch x86-setup-don-t-remove-e820_type_ram-for-pfn-0.patch proc_sysctl-fix-oops-caused-by-incorrect-command-parameters.patch diff --git a/queue-5.10/x86-fpu-add-kernel_fpu_begin_mask-to-selectively-initialize-state.patch b/queue-5.10/x86-fpu-add-kernel_fpu_begin_mask-to-selectively-initialize-state.patch new file mode 100644 index 00000000000..0a9b9418bcf --- /dev/null +++ b/queue-5.10/x86-fpu-add-kernel_fpu_begin_mask-to-selectively-initialize-state.patch @@ -0,0 +1,102 @@ +From e45122893a9870813f9bd7b4add4f613e6f29008 Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +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 + +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 +Signed-off-by: Borislav Petkov +Tested-by: Krzysztof Piotr Olędzki +Link: https://lkml.kernel.org/r/aff1cac8b8fc7ee900cf73e8f2369966621b053f.1611205691.git.luto@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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) + { -- 2.47.3