Merge branch 'x86/cpu' into x86/core
[sfrench/cifs-2.6.git] / include / asm-x86 / processor.h
index 6d5648945ebf86fff45e85b5fe3cf64c6a65697e..10471cfab145a82012ac7e32abdda0752db371df 100644 (file)
@@ -732,6 +732,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);