summaryrefslogtreecommitdiff
path: root/arch/x86/include
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-08-30 15:35:11 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-07 12:31:51 -0800
commit570bd39ac8505e57b1d62e56b84eea9de8473c15 (patch)
tree20fcb338c29222b130228294893ab186df77732f /arch/x86/include
parent71c6bd5af2d984fadd81611ad643bda52e82ad79 (diff)
Revert "x86, hotplug: Use mwait to offline a processor, fix the legacy case"
This reverts commit 226917b0735f31cf5c704e07fdd590d99bbfae58 (upstream ea53069231f9317062910d6e772cca4ce93de8c8 and a68e5c94f7d3dd64fef34dd5d97e365cae4bb42a and ce5f68246bf2385d6174856708d0b746dc378f20 all mushed together) as Jonathan Nieder reports that this causes a regression on some hardware. More details can be found at http://bugs.debian.org/622259 Cc: Jonathan Nieder <jrnieder@gmail.com> Cc: H. Peter Anvin <hpa@linux.intel.com> Cc: Len Brown <len.brown@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/x86/include')
-rw-r--r--arch/x86/include/asm/processor.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index da35a70f6129..fa04deade0a6 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -765,6 +765,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);