All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andi Kleen <andi@firstfloor.org>
To: speck@linutronix.de
Cc: Andi Kleen <ak@linux.intel.com>
Subject: [MODERATED] [PATCH v2 3/8] MDSv2 5
Date: Mon, 10 Dec 2018 09:53:35 -0800	[thread overview]
Message-ID: <0d6a3fbe4c511152a0f5350e62e9e09ec545f709.1544464266.git.ak@linux.intel.com> (raw)
In-Reply-To: <cover.1544464266.git.ak@linux.intel.com>
In-Reply-To: <cover.1544464266.git.ak@linux.intel.com>

From: Andi Kleen <ak@linux.intel.com>
Subject:  x86/speculation/mds: Clear CPU buffers on entering
 idle

When entering idle the internal state of the current CPU might
become visible to the thread sibling because the CPU "frees" some
internal resources.

To ensure there is no MDS leakage always clear the CPU state
before doing any idling. We only do this if SMT is enabled,
as otherwise there is no leakage possible.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 arch/x86/include/asm/irqflags.h      |  3 +++
 arch/x86/include/asm/mwait.h         |  4 ++++
 arch/x86/include/asm/nospec-branch.h |  5 +++++
 arch/x86/kernel/cpu/bugs.c           | 23 +++++++++++++++++++++++
 arch/x86/kernel/kvm.c                |  1 +
 arch/x86/kernel/process.c            |  4 ++++
 arch/x86/kernel/smpboot.c            |  1 +
 7 files changed, 41 insertions(+)

diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
index 058e40fed167..0b6560f0defb 100644
--- a/arch/x86/include/asm/irqflags.h
+++ b/arch/x86/include/asm/irqflags.h
@@ -3,6 +3,7 @@
 #define _X86_IRQFLAGS_H_
 
 #include <asm/processor-flags.h>
+#include <asm/nospec-branch.h>
 
 #ifndef __ASSEMBLY__
 
@@ -96,6 +97,7 @@ static inline notrace void arch_local_irq_enable(void)
  */
 static inline __cpuidle void arch_safe_halt(void)
 {
+	clear_cpu_buffers_idle();
 	native_safe_halt();
 }
 
@@ -105,6 +107,7 @@ static inline __cpuidle void arch_safe_halt(void)
  */
 static inline __cpuidle void halt(void)
 {
+	clear_cpu_buffers_idle();
 	native_halt();
 }
 
diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
index 39a2fb29378a..36edad498d19 100644
--- a/arch/x86/include/asm/mwait.h
+++ b/arch/x86/include/asm/mwait.h
@@ -40,6 +40,8 @@ static inline void __monitorx(const void *eax, unsigned long ecx,
 
 static inline void __mwait(unsigned long eax, unsigned long ecx)
 {
+	clear_cpu_buffers_idle();
+
 	/* "mwait %eax, %ecx;" */
 	asm volatile(".byte 0x0f, 0x01, 0xc9;"
 		     :: "a" (eax), "c" (ecx));
@@ -82,6 +84,8 @@ static inline void __mwaitx(unsigned long eax, unsigned long ebx,
 static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
 {
 	trace_hardirqs_on();
+	clear_cpu_buffers_idle();
+
 	/* "mwait %eax, %ecx;" */
 	asm volatile("sti; .byte 0x0f, 0x01, 0xc9;"
 		     :: "a" (eax), "c" (ecx));
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index f780f29e351f..3a2843062dfb 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -9,6 +9,7 @@
 #include <asm/alternative-asm.h>
 #include <asm/cpufeatures.h>
 #include <asm/msr-index.h>
+#include <asm/segment.h>
 
 /*
  * Fill the CPU return stack buffer.
@@ -386,4 +387,8 @@ do {								\
 # endif
 #endif
 
+#ifndef __ASSEMBLY__
+void clear_cpu_buffers_idle(void);
+#endif
+
 #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 5cac243849d8..8200b41b8db9 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -1051,6 +1051,29 @@ static void mds_select_mitigation(void)
 		setup_clear_cpu_cap(X86_FEATURE_MB_CLEAR);
 }
 
+/*
+ * Clear CPU buffers before going idle, so that no state is leaked to SMT
+ * siblings taking over thread resources.
+ * Out of line to avoid include hell.
+ *
+ * Assumes that interrupts are disabled and only get reenabled
+ * before idle, otherwise the data from a racing interrupt might not
+ * get cleared. There are some callers who violate this,
+ * but they only in very uncommon cases.
+ */
+void clear_cpu_buffers_idle(void)
+{
+	if (cpu_smt_control != CPU_SMT_ENABLED)
+		return;
+	/* Has to be memory form, don't modify to use an register */
+	alternative_input("",
+		"pushq %[kernelds]; verw (%%rsp) ; addq $8,%%rsp \n",
+		X86_FEATURE_MB_CLEAR,
+		[kernelds] "i" (__KERNEL_DS));
+}
+
+EXPORT_SYMBOL(clear_cpu_buffers_idle);
+
 #ifdef CONFIG_SYSFS
 
 #define L1TF_DEFAULT_MSG "Mitigation: PTE Inversion"
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index ba4bfb7f6a36..357c66adc250 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -159,6 +159,7 @@ void kvm_async_pf_task_wait(u32 token, int interrupt_kernel)
 			/*
 			 * We cannot reschedule. So halt.
 			 */
+			clear_cpu_buffers_idle();
 			native_safe_halt();
 			local_irq_disable();
 		}
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 7d31192296a8..1eda5658ac55 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -586,6 +586,8 @@ void stop_this_cpu(void *dummy)
 	disable_local_APIC();
 	mcheck_cpu_clear(this_cpu_ptr(&cpu_info));
 
+	clear_cpu_buffers_idle();
+
 	/*
 	 * Use wbinvd on processors that support SME. This provides support
 	 * for performing a successful kexec when going from SME inactive
@@ -672,6 +674,8 @@ static __cpuidle void mwait_idle(void)
 			mb(); /* quirk */
 		}
 
+		clear_cpu_buffers_idle();
+
 		__monitor((void *)&current_thread_info()->flags, 0, 0);
 		if (!need_resched())
 			__sti_mwait(0, 0);
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index a9134d1910b9..96820e635491 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1662,6 +1662,7 @@ void hlt_play_dead(void)
 		wbinvd();
 
 	while (1) {
+		clear_cpu_buffers_idle();
 		native_halt();
 		/*
 		 * If NMI wants to wake up CPU0, start CPU0.
-- 
2.17.2

  parent reply	other threads:[~2018-12-10 22:36 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-10 17:53 [MODERATED] [PATCH v2 0/8] MDSv2 8 Andi Kleen
2018-12-10 17:53 ` [MODERATED] [PATCH v2 1/8] MDSv2 4 Andi Kleen
2018-12-11 14:14   ` [MODERATED] " Paolo Bonzini
2018-12-12 21:22   ` Konrad Rzeszutek Wilk
2018-12-12 21:28     ` Andi Kleen
2018-12-12 21:25   ` Konrad Rzeszutek Wilk
2018-12-10 17:53 ` [MODERATED] [PATCH v2 2/8] MDSv2 1 Andi Kleen
2018-12-10 22:49   ` [MODERATED] " Jiri Kosina
2018-12-11  0:03     ` Andi Kleen
2018-12-11  0:13     ` Kanth Ghatraju
2018-12-11  2:00       ` Andi Kleen
2018-12-11  5:36       ` Jiri Kosina
2018-12-11 10:03       ` Borislav Petkov
2018-12-12 21:31         ` Konrad Rzeszutek Wilk
2018-12-12 21:43           ` Andi Kleen
2018-12-12 22:17           ` Borislav Petkov
2018-12-12 22:40             ` Konrad Rzeszutek Wilk
2018-12-12 22:45               ` Borislav Petkov
2018-12-13 15:15                 ` Andrew Cooper
2018-12-13 16:52                   ` Borislav Petkov
2018-12-10 17:53 ` Andi Kleen [this message]
2018-12-10 23:00   ` [MODERATED] Re: [PATCH v2 3/8] MDSv2 5 Linus Torvalds
2018-12-11  0:03     ` Andi Kleen
2018-12-11  0:43       ` Linus Torvalds
2018-12-11  1:33         ` Linus Torvalds
2018-12-11  2:12           ` Andi Kleen
2018-12-11  2:20           ` Linus Torvalds
2018-12-11  3:25             ` Andi Kleen
2018-12-11 17:55               ` Linus Torvalds
2018-12-11 18:10                 ` Borislav Petkov
2018-12-11 18:21                 ` Linus Torvalds
2018-12-11 18:26                   ` Borislav Petkov
2018-12-11 19:47                   ` Andi Kleen
2018-12-11 21:22                   ` Thomas Gleixner
2018-12-12 14:02               ` [MODERATED] " Paolo Bonzini
2018-12-12 17:58                 ` Andi Kleen
2018-12-12 18:47                   ` Linus Torvalds
2018-12-13 19:44                     ` Linus Torvalds
2018-12-13 20:48                       ` Andi Kleen
2018-12-13 20:56                         ` Linus Torvalds
2018-12-15  0:30                         ` Andi Kleen
2018-12-11  2:10         ` Andi Kleen
2018-12-11  0:09     ` Andrew Cooper
2018-12-10 17:53 ` [MODERATED] [PATCH v2 4/8] MDSv2 0 Andi Kleen
2018-12-12 21:45   ` [MODERATED] " Konrad Rzeszutek Wilk
2018-12-12 22:09     ` Andi Kleen
2018-12-12 22:36       ` Konrad Rzeszutek Wilk
2018-12-10 17:53 ` [MODERATED] [PATCH v2 5/8] MDSv2 7 Andi Kleen
2018-12-11  0:33   ` [MODERATED] " Andrew Cooper
2018-12-12 18:05     ` Andrew Cooper
2018-12-12 21:41   ` Konrad Rzeszutek Wilk
2018-12-12 22:12     ` Andi Kleen
2018-12-10 17:53 ` [MODERATED] [PATCH v2 6/8] MDSv2 3 Andi Kleen
2018-12-11  0:37   ` [MODERATED] " Andrew Cooper
2018-12-11  0:46     ` Luck, Tony
2018-12-11  1:02       ` Andrew Cooper
2018-12-11  1:53       ` Andi Kleen
2018-12-10 17:53 ` [MODERATED] [PATCH v2 7/8] MDSv2 6 Andi Kleen
2018-12-10 17:53 ` [MODERATED] [PATCH v2 8/8] MDSv2 2 Andi Kleen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0d6a3fbe4c511152a0f5350e62e9e09ec545f709.1544464266.git.ak@linux.intel.com \
    --to=andi@firstfloor.org \
    --cc=ak@linux.intel.com \
    --cc=speck@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.