aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-01-21 13:41:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2018-01-21 13:41:48 -0500
commit319f1e04c7e7016233f998a1a48cd3d17da2108f (patch)
tree90119215525c4bcb0d1756c1468eeaebcdb9efba
parent66f816241895dc8a1614c1114c0a97b167e4ce64 (diff)
parentf23d74f6c66c3697e032550eeef3f640391a3a7d (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 kexec fix from Thomas Gleixner: "A single fix for the WBINVD issue introduced by the SME support which causes kexec fails on non AMD/SME capable CPUs. Issue WBINVD only when the CPU has SME and avoid doing so in a loop" [ Side note: this patch fixes the problem, but it isn't entirely clear why it is required. The wbinvd should just work regardless, but there seems to be some system - as opposed to CPU - issue, since the wbinvd causes more problems later in the shutdown sequence, but wbinvd instructions while the system is still active are not problematic. Possibly some SMI or pending machine check issue on the affected system ] * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mm: Rework wbinvd, hlt operation in stop_this_cpu()
-rw-r--r--arch/x86/kernel/process.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 832a6acd730f..cb368c2a22ab 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -380,19 +380,24 @@ void stop_this_cpu(void *dummy)
380 disable_local_APIC(); 380 disable_local_APIC();
381 mcheck_cpu_clear(this_cpu_ptr(&cpu_info)); 381 mcheck_cpu_clear(this_cpu_ptr(&cpu_info));
382 382
383 /*
384 * Use wbinvd on processors that support SME. This provides support
385 * for performing a successful kexec when going from SME inactive
386 * to SME active (or vice-versa). The cache must be cleared so that
387 * if there are entries with the same physical address, both with and
388 * without the encryption bit, they don't race each other when flushed
389 * and potentially end up with the wrong entry being committed to
390 * memory.
391 */
392 if (boot_cpu_has(X86_FEATURE_SME))
393 native_wbinvd();
383 for (;;) { 394 for (;;) {
384 /* 395 /*
385 * Use wbinvd followed by hlt to stop the processor. This 396 * Use native_halt() so that memory contents don't change
386 * provides support for kexec on a processor that supports 397 * (stack usage and variables) after possibly issuing the
387 * SME. With kexec, going from SME inactive to SME active 398 * native_wbinvd() above.
388 * requires clearing cache entries so that addresses without
389 * the encryption bit set don't corrupt the same physical
390 * address that has the encryption bit set when caches are
391 * flushed. To achieve this a wbinvd is performed followed by
392 * a hlt. Even if the processor is not in the kexec/SME
393 * scenario this only adds a wbinvd to a halting processor.
394 */ 399 */
395 asm volatile("wbinvd; hlt" : : : "memory"); 400 native_halt();
396 } 401 }
397} 402}
398 403