Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754503AbeAKOVI (ORCPT + 1 other); Thu, 11 Jan 2018 09:21:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39326 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754267AbeAKOVG (ORCPT ); Thu, 11 Jan 2018 09:21:06 -0500 Date: Thu, 11 Jan 2018 08:20:39 -0600 From: Josh Poimboeuf To: David Woodhouse Cc: Andi Kleen , Paul Turner , LKML , Linus Torvalds , Greg Kroah-Hartman , Tim Chen , Dave Hansen , tglx@linutronix.de, Kees Cook , Rik van Riel , Peter Zijlstra , Andy Lutomirski , Jiri Kosina , gnomes@lxorguk.ukuu.org.uk, x86@kernel.org, bp@alien8.de, rga@amazon.de, thomas.lendacky@amd.com Subject: Re: [PATCH v2.1] x86/retpoline: Fill return stack buffer on vmexit Message-ID: <20180111142038.sqhflhikcailqnwi@treble> References: <1515670638-8552-1-git-send-email-dwmw@amazon.co.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <1515670638-8552-1-git-send-email-dwmw@amazon.co.uk> User-Agent: Mutt/1.6.0.1 (2016-04-01) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 11 Jan 2018 14:21:06 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Thu, Jan 11, 2018 at 11:37:18AM +0000, David Woodhouse wrote: > In accordance with the Intel and AMD documentation, we need to overwrite > all entries in the RSB on exiting a guest, to prevent malicious branch > target predictions from affecting the host kernel. This is needed both > for retpoline and for IBRS. > > Signed-off-by: David Woodhouse > --- > v2: Reduce the size of the ALTERNATIVE insns, fix .align (again)! > Sent in private email for testing, hence this second public post is > v2.1: Add CONFIG_RETPOLINE around RSB stuffing > > Sorry, Josh, objtool broke again! :) > > arch/x86/include/asm/nospec-branch.h | 76 ++++++++++++++++++++++++++++++++++++ > arch/x86/kvm/svm.c | 4 ++ > arch/x86/kvm/vmx.c | 4 ++ > 3 files changed, 84 insertions(+) > > diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h > index 7d70ea9..b55ff79 100644 > --- a/arch/x86/include/asm/nospec-branch.h > +++ b/arch/x86/include/asm/nospec-branch.h > @@ -7,6 +7,50 @@ > #include > #include > > +/* > + * Fill the CPU return stack buffer. > + * > + * Each entry in the RSB, if used for a speculative 'ret', contains an > + * infinite 'pause; jmp' loop to capture speculative execution. > + * > + * This is required in various cases for retpoline and IBRS-based > + * mitigations for the Spectre variant 2 vulnerability. Sometimes to > + * eliminate potentially bogus entries from the RSB, and sometimes > + * purely to ensure that it doesn't get empty, which on some CPUs would > + * allow predictions from other (unwanted!) sources to be used. > + * > + * We define a CPP macro such that it can be used from both .S files and > + * inline assembly. It's possible to do a .macro and then include that > + * from C via asm(".include ") but let's not go there. > + */ > + > +#define RSB_CLEAR_LOOPS 32 /* To forcibly overwrite all entries */ > +#define RSB_FILL_LOOPS 16 /* To avoid underflow */ > + > +#define __FILL_RETURN_BUFFER_PREP(reg, nr) \ > + mov $(nr/2), reg > + > +#define __FILL_RETURN_BUFFER(reg, nr, sp, uniq) \ > + .align 16; \ > +.Ldo_call1_ ## uniq: \ > + call .Ldo_call2_ ## uniq; \ > +.Ltrap1_ ## uniq: \ > + pause; \ > + jmp .Ltrap1_ ## uniq; \ > + .align 16; \ > +.Ldo_call2_ ## uniq: \ > + call .Ldo_loop_ ## uniq; \ > +.Ltrap2_ ## uniq: \ > + pause; \ > + jmp .Ltrap2_ ## uniq; \ > + .align 16; \ > +.Ldo_loop_ ## uniq: \ > + dec reg; \ > + jnz .Ldo_call1_ ## uniq; \ > + add $(BITS_PER_LONG/8) * nr, sp; \ > +.Lskip_rsb_ ## uniq:; > + > + > #ifdef __ASSEMBLY__ > > /* > @@ -61,6 +105,19 @@ > #endif > .endm > > + /* > + * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP > + * monstrosity above, manually. > + */ > +.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req > +#ifdef CONFIG_RETPOLINE > + ALTERNATIVE "jmp .Lskip_rsb_\@", \ > + __stringify(__FILL_RETURN_BUFFER_PREP(\reg,\nr)), \ > + \ftr > + __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP,\@) > +#endif > +.endm This seems weird. I liked v1 a lot better. What's the problem with patching in the whole thing? Also, if you go back to v1, it should be an easy objtool fix, just add ANNOTATE_NOSPEC_ALTERNATIVE in front of it. -- Josh