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 Feb 2019 14:19:16 -0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1gwpBy-0007g1-JN for speck@linutronix.de; Thu, 21 Feb 2019 15:19:15 +0100 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 4FA1DB183 for ; Thu, 21 Feb 2019 14:19:08 +0000 (UTC) Date: Thu, 21 Feb 2019 15:18:59 +0100 From: Borislav Petkov Subject: [MODERATED] Re: [patch V2 09/10] MDS basics+ 9 Message-ID: <20190221141859.GH13125@zn.tnic> References: <20190220150753.665964899@linutronix.de> <20190220151400.787843957@linutronix.de> MIME-Version: 1.0 In-Reply-To: <20190220151400.787843957@linutronix.de> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable To: speck@linutronix.de List-ID: On Wed, Feb 20, 2019 at 04:08:02PM +0100, speck for Thomas Gleixner wrote: > To avoid the expensive CPU buffer flushing on every transition from kernel > to user space it is desired to provide a conditional mitigation mode. >=20 > Provide the infrastructure which is required to implement this: >=20 > - A static key to enable conditional mode CPU buffer flushing. >=20 > - A per CPU variable which indicates that CPU buffers need to > be flushed on return to user space. The variable is defined > next to __preempt_count to it ends up in a cacheline which so > is required on return to user space anyway. >=20 > - The conditinal flush mechanics on return to user space. conditional >=20 > - A helper function to set the flush request. Is in processor.h for now to > avoid include hell, but might move to a separate header. >=20 > Signed-off-by: Thomas Gleixner > --- > arch/x86/entry/common.c | 6 ++++++ > arch/x86/include/asm/nospec-branch.h | 3 +++ > arch/x86/include/asm/processor.h | 13 +++++++++++++ > arch/x86/kernel/cpu/bugs.c | 1 + > arch/x86/kernel/cpu/common.c | 7 +++++++ > 5 files changed, 30 insertions(+) >=20 > --- a/arch/x86/entry/common.c > +++ b/arch/x86/entry/common.c > @@ -183,6 +183,12 @@ static void exit_to_usermode_loop(struct > =20 > static inline void mds_user_clear_cpu_buffers(void) > { > + if (static_branch_likely(&mds_user_clear_cond)) { > + if (__this_cpu_read(mds_cond_clear)) { > + __this_cpu_write(mds_cond_clear, 0); > + mds_clear_cpu_buffers(); > + } > + } > if (static_branch_likely(&mds_user_clear_always)) > mds_clear_cpu_buffers(); > } > --- a/arch/x86/include/asm/nospec-branch.h > +++ b/arch/x86/include/asm/nospec-branch.h > @@ -9,6 +9,7 @@ > #include > #include > #include > +#include > =20 > /* > * Fill the CPU return stack buffer. > @@ -319,7 +320,9 @@ DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ > DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb); > =20 > DECLARE_STATIC_KEY_FALSE(mds_user_clear_always); > +DECLARE_STATIC_KEY_FALSE(mds_user_clear_cond); > DECLARE_STATIC_KEY_FALSE(mds_idle_clear); > +DECLARE_PER_CPU(unsigned int, mds_cond_clear); > =20 > #include > =20 > --- a/arch/x86/include/asm/processor.h > +++ b/arch/x86/include/asm/processor.h > @@ -24,6 +24,7 @@ struct vm86; > #include > #include > #include > +#include > =20 > #include > #include > @@ -998,4 +999,16 @@ enum mds_mitigations { > MDS_MITIGATION_HOPE, > }; > =20 > +/** > + * mds_request_buffer_clear - Set the request to clear CPU buffers > + * > + * This is invoked from contexts which identify a necessarity to clear CPU ^ necessity > + * buffers on the next return to user space. > + */ > +static inline void mds_request_buffer_clear(void) > +{ > + if (static_branch_likely(&mds_user_clear_cond)) > + this_cpu_write(mds_cond_clear, 1); > +} > + > #endif /* _ASM_X86_PROCESSOR_H */ > --- a/arch/x86/kernel/cpu/bugs.c > +++ b/arch/x86/kernel/cpu/bugs.c > @@ -66,6 +66,7 @@ DEFINE_STATIC_KEY_FALSE(switch_mm_always > =20 > /* Control MDS CPU buffer clear before returning to user space */ > DEFINE_STATIC_KEY_FALSE(mds_user_clear_always); > +DEFINE_STATIC_KEY_FALSE(mds_user_clear_cond); > /* Control MDS CPU buffer clear before idling (halt, mwait) */ > DEFINE_STATIC_KEY_FALSE(mds_idle_clear); > =20 > --- a/arch/x86/kernel/cpu/common.c > +++ b/arch/x86/kernel/cpu/common.c > @@ -8,6 +8,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -1544,6 +1545,9 @@ DEFINE_PER_CPU(unsigned int, irq_count) > DEFINE_PER_CPU(int, __preempt_count) =3D INIT_PREEMPT_COUNT; > EXPORT_PER_CPU_SYMBOL(__preempt_count); > =20 > +/* Indicator for return to user space or VMENTER to clear CPU buffers */ > +DEFINE_PER_CPU(unsigned int, mds_cond_clear); > + > /* May not be marked __init: used by software suspend */ > void syscall_init(void) > { > @@ -1617,6 +1621,9 @@ EXPORT_PER_CPU_SYMBOL(current_task); > DEFINE_PER_CPU(int, __preempt_count) =3D INIT_PREEMPT_COUNT; > EXPORT_PER_CPU_SYMBOL(__preempt_count); > =20 > +/* Indicator for return to user space or VMENTER to clear CPU buffers */ > +DEFINE_PER_CPU(unsigned int, mds_cond_clear); > + Why not define it once in the bitness-agnostic place over #ifdef CONFIG_X86_6= 4? --=20 Regards/Gruss, Boris. SUSE Linux GmbH, GF: Felix Imend=C3=B6rffer, Jane Smithard, Graham Norton, HR= B 21284 (AG N=C3=BCrnberg) --=20