Thread (9 messages) read the whole thread 9 messages, 3 authors, 2021-01-15

Re: [PATCH] x86/lib: don't use MMX before FPU initialization

From: Krzysztof Mazur <hidden>
Date: 2021-01-14 14:51:52
Also in: lkml
Subsystem: the rest, x86 architecture (32-bit and 64-bit) · Maintainers: Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen

On Thu, Jan 14, 2021 at 03:07:37PM +0100, Borislav Petkov wrote:
On Thu, Jan 14, 2021 at 01:36:57PM +0100, Krzysztof Mazur wrote:
quoted
The OSFXSR must be set only on CPUs with SSE. There
are some CPUs with 3DNow!, but without SSE and FXSR (like AMD
Geode LX, which is still used in many embedded systems).
So, I've changed that to:

if (unlikely(in_interrupt()) || (boot_cpu_has(X86_FEATURE_XMM) &&
		unlikely(!(cr4_read_shadow() & X86_CR4_OSFXSR))))
Why?

X86_CR4_OSFXSR won't ever be set on those CPUs but the test will be
performed anyway. So there's no need for boot_cpu_has().
Because the MMX version should be always used on those CPUs, even without
OSFXSR set. If the CPU does not support SSE, it is safe to
call kernel_fpu_begin() without OSFXSR set.
"!(cr4_read_shadow() & X86_CR4_OSFXSR)" will be always true on
those CPUs, and without boot_cpu_has() MMX version will be never used.

There are two cases:

3DNow! without SSE		always use MMX version
3DNow! + SSE (K7)		use MMX version only if FXSR is enabled

Thanks.

Best regards,
Krzysiek
-- >8 --
Subject: [PATCH] x86/lib: don't use mmx_memcpy() too early

The MMX 3DNow! optimized memcpy() is used very early,
even before FPU is initialized in the kernel. It worked fine, but commit
7ad816762f9bf89e940e618ea40c43138b479e10 ("x86/fpu: Reset MXCSR
to default in kernel_fpu_begin()") broke that. After that
commit the kernel_fpu_begin() assumes that FXSR is enabled in
the CR4 register on all processors with SSE. Because memcpy() is used
before FXSR is enabled, the kernel crashes just after "Booting the kernel."
message. It affects all kernels with CONFIG_X86_USE_3DNOW (enabled when
some AMD/Cyrix processors are selected) on processors with SSE
(like AMD K7, which supports both MMX 3DNow! and SSE).

Fixes: 7ad816762f9b ("x86/fpu: Reset MXCSR to default in kernel_fpu_begin()")
Cc: Thomas Gleixner <redacted>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <redacted> # 5.8+
Signed-off-by: Krzysztof Mazur <redacted>
---
 arch/x86/lib/mmx_32.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/lib/mmx_32.c b/arch/x86/lib/mmx_32.c
index 4321fa02e18d..70aa769570e6 100644
--- a/arch/x86/lib/mmx_32.c
+++ b/arch/x86/lib/mmx_32.c
@@ -25,13 +25,20 @@
 
 #include <asm/fpu/api.h>
 #include <asm/asm.h>
+#include <asm/tlbflush.h>
 
 void *_mmx_memcpy(void *to, const void *from, size_t len)
 {
 	void *p;
 	int i;
 
-	if (unlikely(in_interrupt()))
+	/*
+	 * kernel_fpu_begin() assumes that FXSR is enabled on all processors
+	 * with SSE. Thus, MMX-optimized version can't be used
+	 * before the kernel enables FXSR (OSFXSR bit in the CR4 register).
+	 */
+	if (unlikely(in_interrupt()) || (boot_cpu_has(X86_FEATURE_XMM) &&
+			unlikely(!(cr4_read_shadow() & X86_CR4_OSFXSR))))
 		return __memcpy(to, from, len);
 
 	p = to;
-- 
2.27.0.rc1.207.gb85828341f
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help