| From e87892448a51b8bdbc9f96a722cd62cb675f2d31 Mon Sep 17 00:00:00 2001 |
| From: Petteri Aimonen <jpa@git.mail.kapsi.fi> |
| Date: Tue, 16 Jun 2020 11:12:57 +0200 |
| Subject: [PATCH] x86/fpu: Reset MXCSR to default in kernel_fpu_begin() |
| |
| commit 7ad816762f9bf89e940e618ea40c43138b479e10 upstream. |
| |
| Previously, kernel floating point code would run with the MXCSR control |
| register value last set by userland code by the thread that was active |
| on the CPU core just before kernel call. This could affect calculation |
| results if rounding mode was changed, or a crash if a FPU/SIMD exception |
| was unmasked. |
| |
| Restore MXCSR to the kernel's default value. |
| |
| [ bp: Carve out from a bigger patch by Petteri, add feature check, add |
| FNINIT call too (amluto). ] |
| |
| Signed-off-by: Petteri Aimonen <jpa@git.mail.kapsi.fi> |
| Signed-off-by: Borislav Petkov <bp@suse.de> |
| Link: https://bugzilla.kernel.org/show_bug.cgi?id=207979 |
| Link: https://lkml.kernel.org/r/20200624114646.28953-2-bp@alien8.de |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h |
| index 44c48e34d799..00eac7f1529b 100644 |
| --- a/arch/x86/include/asm/fpu/internal.h |
| +++ b/arch/x86/include/asm/fpu/internal.h |
| @@ -619,6 +619,11 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) |
| * MXCSR and XCR definitions: |
| */ |
| |
| +static inline void ldmxcsr(u32 mxcsr) |
| +{ |
| + asm volatile("ldmxcsr %0" :: "m" (mxcsr)); |
| +} |
| + |
| extern unsigned int mxcsr_feature_mask; |
| |
| #define XCR_XFEATURE_ENABLED_MASK 0x00000000 |
| diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c |
| index 649fbc3fcf9f..8ba0e53dec75 100644 |
| --- a/arch/x86/kernel/fpu/core.c |
| +++ b/arch/x86/kernel/fpu/core.c |
| @@ -113,6 +113,12 @@ static void __kernel_fpu_begin(void) |
| } |
| } |
| __cpu_invalidate_fpregs_state(); |
| + |
| + if (boot_cpu_has(X86_FEATURE_XMM)) |
| + ldmxcsr(MXCSR_DEFAULT); |
| + |
| + if (boot_cpu_has(X86_FEATURE_FPU)) |
| + asm volatile ("fninit"); |
| } |
| |
| static void __kernel_fpu_end(void) |
| -- |
| 2.27.0 |
| |