[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <46816abe4f68ac3eb9b80231bf64ba8edcebc2f7.1480536936.git.luto@kernel.org>
Date: Wed, 30 Nov 2016 12:34:55 -0800
From: Andy Lutomirski <luto@...nel.org>
To: x86@...nel.org
Cc: One Thousand Gnomes <gnomes@...rguk.ukuu.org.uk>,
Borislav Petkov <bp@...en8.de>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Brian Gerst <brgerst@...il.com>,
Matthew Whitehead <tedheadster@...il.com>,
Henrique de Moraes Holschuh <hmh@....eng.br>,
Andy Lutomirski <luto@...nel.org>
Subject: [PATCH 4/4] x86/asm: Change sync_core() to use MOV to CR2 to serialize
Aside from being excessively slow, CPUID is problematic: Linux runs
on a handful of CPUs that don't have CPUID. MOV to CR2 is always
available, so use it instead.
Signed-off-by: Andy Lutomirski <luto@...nel.org>
---
arch/x86/include/asm/processor.h | 31 ++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 64fbc937d586..0388f3d85700 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -593,31 +593,16 @@ static __always_inline void cpu_relax(void)
/* Stop speculative execution and prefetching of modified code. */
static inline void sync_core(void)
{
- int tmp;
-
-#ifdef CONFIG_X86_32
- /*
- * Do a CPUID if available, otherwise do a jump. The jump
- * can conveniently enough be the jump around CPUID.
- */
- asm volatile("cmpl %2,%1\n\t"
- "jl 1f\n\t"
- "cpuid\n"
- "1:"
- : "=a" (tmp)
- : "rm" (boot_cpu_data.cpuid_level), "ri" (0), "0" (1)
- : "ebx", "ecx", "edx", "memory");
-#else
/*
- * CPUID is a barrier to speculative execution.
- * Prefetched instructions are automatically
- * invalidated when modified.
+ * MOV to CR2 is architecturally defined as a serializing
+ * instruction. It's nice because it works on all CPUs, it
+ * doesn't clobber registers, and (unlike CPUID) it won't force
+ * a VM exit.
+ *
+ * 0xbf172b23 is random poison just in case something ends up
+ * caring about this value.
*/
- asm volatile("cpuid"
- : "=a" (tmp)
- : "0" (1)
- : "ebx", "ecx", "edx", "memory");
-#endif
+ write_cr2(0xbf172b23);
}
extern void select_idle_routine(const struct cpuinfo_x86 *c);
--
2.9.3
Powered by blists - more mailing lists