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 ; 21 Jan 2019 19:54:18 -0000 Received: from mga17.intel.com ([192.55.52.151]) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1gkeqV-0003N4-HV for speck@linutronix.de; Sat, 19 Jan 2019 01:50:48 +0100 From: Andi Kleen Subject: [MODERATED] [PATCH v5 03/27] MDSv5 16 Date: Fri, 18 Jan 2019 16:50:18 -0800 Message-Id: <6bfd31477bf279d9af286a17ad6b87c7f6656ddf.1547858934.git.ak@linux.intel.com> In-Reply-To: References: In-Reply-To: References: To: speck@linutronix.de Cc: Andi Kleen List-ID: From: Andi Kleen Subject: x86/speculation/mds: Support clearing CPU data on kernel exit Add infrastructure for clearing CPU data on kernel exit Instead of clearing unconditionally we support clearing lazily when some kernel subsystem touched sensitive data and sets the new TIF_CLEAR_CPU flag. We handle TIF_CLEAR_CPU in kernel exit, similar to other kernel exit action flags. The flushing is provided by new microcode as a new side effect of the otherwise unused VERW instruction. So far this patch doesn't do anything, it relies on later patches to set TIF_CLEAR_CPU. Suggested-by: Linus Torvalds Tested-by: Neelima Krishnan Signed-off-by: Andi Kleen --- arch/x86/entry/common.c | 8 +++++++- arch/x86/include/asm/clearcpu.h | 23 +++++++++++++++++++++++ arch/x86/include/asm/thread_info.h | 2 ++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/clearcpu.h diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 7bc105f47d21..924f8dab2068 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -132,7 +133,7 @@ static long syscall_trace_enter(struct pt_regs *regs) } #define EXIT_TO_USERMODE_LOOP_FLAGS \ - (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ + (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | _TIF_CLEAR_CPU |\ _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY | _TIF_PATCH_PENDING) static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) @@ -170,6 +171,11 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) if (cached_flags & _TIF_USER_RETURN_NOTIFY) fire_user_return_notifiers(); + if (cached_flags & _TIF_CLEAR_CPU) { + clear_thread_flag(TIF_CLEAR_CPU); + clear_cpu(); + } + /* Disable IRQs and retry */ local_irq_disable(); diff --git a/arch/x86/include/asm/clearcpu.h b/arch/x86/include/asm/clearcpu.h new file mode 100644 index 000000000000..530ef619ac1b --- /dev/null +++ b/arch/x86/include/asm/clearcpu.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_CLEARCPU_H +#define _ASM_CLEARCPU_H 1 + +#include +#include +#include +#include + +/* + * Clear CPU buffers to avoid side channels. + * We use microcode as a side effect of the obsolete VERW instruction + */ + +static inline void clear_cpu(void) +{ + unsigned kernel_ds = __KERNEL_DS; + /* Has to be memory form, don't modify to use an register */ + alternative_input("verw %[kernelds]", "", X86_FEATURE_NO_VERW, + [kernelds] "m" (kernel_ds)); +} + +#endif diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index e0eccbcb8447..0c1e3d71018e 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -95,6 +95,7 @@ struct thread_info { #define TIF_MEMDIE 20 /* is terminating due to OOM killer */ #define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */ #define TIF_IO_BITMAP 22 /* uses I/O bitmap */ +#define TIF_CLEAR_CPU 23 /* clear CPU on kernel exit */ #define TIF_FORCED_TF 24 /* true if TF in eflags artificially */ #define TIF_BLOCKSTEP 25 /* set when we want DEBUGCTLMSR_BTF */ #define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */ @@ -123,6 +124,7 @@ struct thread_info { #define _TIF_NOHZ (1 << TIF_NOHZ) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP) +#define _TIF_CLEAR_CPU (1 << TIF_CLEAR_CPU) #define _TIF_FORCED_TF (1 << TIF_FORCED_TF) #define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP) #define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES) -- 2.17.2