From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (146.0.238.70:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 19 Feb 2019 13:38:10 -0000 Received: from localhost ([127.0.0.1] helo=nanos.tec.linutronix.de) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1gw5b0-0004A6-Hw for speck@linutronix.de; Tue, 19 Feb 2019 14:38:02 +0100 Message-Id: <20190219125345.964363293@linutronix.de> Date: Tue, 19 Feb 2019 13:44:08 +0100 From: Thomas Gleixner References: <20190219124406.449727187@linutronix.de> MIME-Version: 1.0 Subject: [patch 2/8] MDS basics 2 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: Subject: [patch 2/8] x86/speculation/mds: Add mds_clear_cpu_buffer() From: Thomas Gleixner The Microarchitectural Data Sampling (MDS) vulernabilities are mitigated by clearing the affected CPU buffers. The mechanism for clearing the buffers uses the unused and obsolete VERW instruction in combination with a microcode update which triggers a CPU buffer clear when VERW is executed. Provide a inline function with the assembly magic. The argument of the VERW instruction must be a memory operand. The function takes a pointer to a static key, so different call sites can depend on different static keys for controlling the invocation. This avoids the conditionals at the call sites and allows for fine grained control, e.g. the SMT only CPU buffer clearing on idle entry can be enabled independent of the exit to user space clear. Signed-off-by: Thomas Gleixner --- arch/x86/include/asm/nospec-branch.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -314,6 +314,25 @@ do { \ preempt_enable(); \ } while (0) +#include + +/** + * mds_clear_cpu_buffers - Mitigation for MDS vulnerability + * + * This uses the otherwise unused and obsolete VERW instruction in + * combination with microcode which triggers a CPU buffer flush when the + * instruction is executed. + */ +static inline void mds_clear_cpu_buffers(struct static_key_false *key) +{ + if (static_branch_likely(key)) { + static const u16 ds = __KERNEL_DS; + + /* Has to be memory form, don't modify to use a register */ + asm volatile("verw %[ds]" : : "i" (0), [ds] "m" (ds)); + } +} + DECLARE_STATIC_KEY_FALSE(switch_to_cond_stibp); DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ibpb); DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb);