summaryrefslogtreecommitdiffstats
path: root/include/asm-x86/processor.h
diff options
context:
space:
mode:
authorIngo Molnar2008-09-04 13:02:35 +0200
committerIngo Molnar2008-09-04 13:02:35 +0200
commit42390cdec5f6e6e2ee54f308474a6ef7dd16aa5c (patch)
treee9684c84f53272319a5acd4b9c86503f30274a51 /include/asm-x86/processor.h
parentx86: use x2apic id reported by cpuid during topology discovery, fix (diff)
parentMerge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmo... (diff)
downloadkernel-qcow2-linux-42390cdec5f6e6e2ee54f308474a6ef7dd16aa5c.tar.gz
kernel-qcow2-linux-42390cdec5f6e6e2ee54f308474a6ef7dd16aa5c.tar.xz
kernel-qcow2-linux-42390cdec5f6e6e2ee54f308474a6ef7dd16aa5c.zip
Merge branch 'linus' into x86/x2apic
Conflicts: arch/x86/kernel/cpu/cyrix.c include/asm-x86/cpufeature.h Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/asm-x86/processor.h')
-rw-r--r--include/asm-x86/processor.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/include/asm-x86/processor.h b/include/asm-x86/processor.h
index 79338fe965d2..d2bf5fe8f4ff 100644
--- a/include/asm-x86/processor.h
+++ b/include/asm-x86/processor.h
@@ -729,6 +729,29 @@ extern unsigned long boot_option_idle_override;
extern unsigned long idle_halt;
extern unsigned long idle_nomwait;
+/*
+ * on systems with caches, caches must be flashed as the absolute
+ * last instruction before going into a suspended halt. Otherwise,
+ * dirty data can linger in the cache and become stale on resume,
+ * leading to strange errors.
+ *
+ * perform a variety of operations to guarantee that the compiler
+ * will not reorder instructions. wbinvd itself is serializing
+ * so the processor will not reorder.
+ *
+ * Systems without cache can just go into halt.
+ */
+static inline void wbinvd_halt(void)
+{
+ mb();
+ /* check for clflush to determine if wbinvd is legal */
+ if (cpu_has_clflush)
+ asm volatile("cli; wbinvd; 1: hlt; jmp 1b" : : : "memory");
+ else
+ while (1)
+ halt();
+}
+
extern void enable_sep_cpu(void);
extern int sysenter_setup(void);