linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@suse.de>
To: David Woodhouse <dwmw2@infradead.org>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>,
	"tglx@linutronix.de" <tglx@linutronix.de>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"tim.c.chen@linux.intel.com" <tim.c.chen@linux.intel.com>,
	"peterz@infradead.org" <peterz@infradead.org>,
	"torvalds@linux-foundation.org" <torvalds@linux-foundation.org>,
	"ak@linux.intel.com" <ak@linux.intel.com>,
	"riel@redhat.com" <riel@redhat.com>,
	"keescook@google.com" <keescook@google.com>,
	"gnomes@lxorguk.ukuu.org.uk" <gnomes@lxorguk.ukuu.org.uk>,
	"pjt@google.com" <pjt@google.com>,
	"dave.hansen@intel.com" <dave.hansen@intel.com>,
	"luto@amacapital.net" <luto@amacapital.net>,
	"jikos@kernel.org" <jikos@kernel.org>,
	"gregkh@linux-foundation.org" <gregkh@linux-foundation.org>
Subject: Re: [PATCH v3 01/13] x86/retpoline: Add initial retpoline support
Date: Sun, 7 Jan 2018 15:03:51 +0100	[thread overview]
Message-ID: <20180107140351.iukmbuf2xkqtvyoz@pd.tnic> (raw)
In-Reply-To: <1515327689.29312.319.camel@infradead.org>

On Sun, Jan 07, 2018 at 12:21:29PM +0000, David Woodhouse wrote:
> http://git.infradead.org/users/dwmw2/linux-retpoline.git
> 
> In particular, this call site in entry_64.S:
> http://git.infradead.org/users/dwmw2/linux-retpoline.git/blob/0f5c54a36e:/arch/x86/entry/entry_64.S#l270
> 
> It's still just unconditionally calling the out-of-line thunk and not
> using ALTERNATIVE in the CONFIG_RETPOLINE case. I can't just use the
> NOSPEC_CALL macro from
> http://git.infradead.org/users/dwmw2/linux-retpoline.git/blob/0f5c54a36e:/arch/x86/include/asm/nospec-branch.h#l46
> because of that requirement that the return address (on the stack) for
> the CALL instruction must be precisely at the end, in all cases.

Thanks, this makes it all clear.

> Each of the three alternatives *does* end with the CALL, it's just that
> for the two which are shorter than the full retpoline one, they'll get
> padded with NOPs at the end, so the return address on the stack *won't*
> be what's expected.

Right.

> Explicitly padding the alternatives with leading NOPs so that they are
> all precisely the same length would work, and if the alternatives
> mechanism were to pad the shorter ones with leading NOPs instead of
> trailing NOPs that would *also* work (but be fairly difficult
> especially to do that for oldinstr).

Right, so doing this reliably would need adding flags to struct
alt_instr - and this need has arisen before and we've managed not to do
it :). And I'm not really persuaded we need it now either because this
would be a one-off case where we need the padding in the front.

> I'm not sure I *see* a simple answer, and it isn't really that bad to
> just do what GCC is doing and unconditionally call the out-of-line
> thunk. So feel free to just throw your hands up in horror and say "no,
> we can't cope with that" :)

Right, or we can do something like this - diff ontop of yours below. We used to
do this before the automatic padding - explicit NOP padding by hand :-)

First split the ALTERNATIVE_2 into two alternative calls, as Brian suggested:

        ALTERNATIVE "", "lfence", X86_FEATURE_RETPOLINE_AMD

and then the second:

        ALTERNATIVE __stringify(ASM_NOP8; ASM_NOP8; ASM_NOP3; call *\reg), \
                     __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE

with frontal NOP padding.

When compiled, it looks like this:

ffffffff818002e2:       90                      nop
ffffffff818002e3:       90                      nop
ffffffff818002e4:       90                      nop

these first three bytes become LFENCE on AMD. On Intel, it gets optimized:

[    0.042954] ffffffff818002e2: [0:3) optimized NOPs: 0f 1f 00

Then:

ffffffff818002e5:       66 66 66 90             data16 data16 xchg %ax,%ax
ffffffff818002e9:       66 66 66 90             data16 data16 xchg %ax,%ax
ffffffff818002ed:       66 66 66 90             data16 data16 xchg %ax,%ax
ffffffff818002f1:       66 66 66 90             data16 data16 xchg %ax,%ax
ffffffff818002f5:       66 66 90                data16 xchg %ax,%ax
ffffffff818002f8:       ff d3                   callq  *%rbx

This thing remains like this on AMD and on Intel gets turned into:

[    0.044004] apply_alternatives: feat: 7*32+12, old: (ffffffff818002e5, len: 21), repl: (ffffffff82219edc, len: 21), pad: 0
[    0.045967] ffffffff818002e5: old_insn: 66 66 66 90 66 66 66 90 66 66 66 90 66 66 66 90 66 66 90 ff d3
[    0.048006] ffffffff82219edc: rpl_insn: eb 0e e8 04 00 00 00 f3 90 eb fc 48 89 1c 24 c3 e8 ed ff ff ff
[    0.050581] ffffffff818002e5: final_insn: eb 0e e8 04 00 00 00 f3 90 eb fc 48 89 1c 24 c3 e8 ed ff ff ff
[    0.052003] ffffffff8180123b: [0:3) optimized NOPs: 0f 1f 00


ffffffff818002e5:       eb 0e                   jmp ffffffff818002f5
ffffffff818002e7:       e8 04 00 00 00          callq ffffffff818002f0
ffffffff818002ec:       f3 90                   pause
ffffffff818002ee:       eb fc                   jmp ffffffff818002ec
ffffffff818002f0:       48 89 1c 24             mov %rbx,(%rsp)
ffffffff818002f4:       c3                      ret
ffffffff818002f5:       e8 ed ff ff ff          callq ffffffff818002e7

so that in both cases, the CALL remains last.

My fear is if some funky compiler changes the sizes of the insns in
RETPOLINE_CALL/JMP and then the padding becomes wrong. But looking at the
labels, they're all close so you have a 2-byte jmp already and the

call    1112f

should be ok. The MOV is reg,(reg) which should not change size of 4...

But I'm remaining cautious here.

And we'd need to do the respective thing for NOSPEC_JMP.

Btw, I've moved the setting of X86_FEATURE_RETPOLINE and
X86_FEATURE_RETPOLINE_AMD to the respective intel.c and amd.c files. I
think this is what we want.

And if we're doing two different RETPOLINE flavors, then we should call
X86_FEATURE_RETPOLINE
X86_FEATURE_RETPOLINE_INTEL.

Does that whole thing make some sense...?

---
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index c4d08fa29d6c..70825ce909ba 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -6,6 +6,7 @@
 #include <asm/alternative.h>
 #include <asm/alternative-asm.h>
 #include <asm/cpufeatures.h>
+#include <asm/nops.h>
 
 #ifdef __ASSEMBLY__
 
@@ -43,11 +44,15 @@
 #endif
 .endm
 
+/*
+ * RETPOLINE_CALL is 21 bytes so pad the front with 19 bytes + 2 bytes for the
+ * CALL insn so that all CALL instructions remain last.
+ */
 .macro NOSPEC_CALL reg:req
 #ifdef CONFIG_RETPOLINE
-	ALTERNATIVE_2 __stringify(call *\reg),				\
-		__stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\
-		__stringify(lfence; call *\reg), X86_FEATURE_RETPOLINE_AMD
+	ALTERNATIVE "", "lfence", X86_FEATURE_RETPOLINE_AMD
+	ALTERNATIVE __stringify(ASM_NOP8; ASM_NOP8; ASM_NOP3; call *\reg), \
+		     __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE
 #else
 	call	*\reg
 #endif
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index b221fe507640..938111e77dd0 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -554,6 +554,8 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
 		rdmsrl(MSR_FAM10H_NODE_ID, value);
 		nodes_per_socket = ((value >> 3) & 7) + 1;
 	}
+
+	setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
 }
 
 static void early_init_amd(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index cfa5042232a2..372ba3fb400f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -904,9 +904,6 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c)
 
 	setup_force_cpu_bug(X86_BUG_SPECTRE_V1);
 	setup_force_cpu_bug(X86_BUG_SPECTRE_V2);
-#ifdef CONFIG_RETPOLINE
-	setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
-#endif
 
 	fpu__init_system(c);
 
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 35e123e5f413..a9e00edaba46 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -524,6 +524,13 @@ static void init_intel_misc_features(struct cpuinfo_x86 *c)
 	wrmsrl(MSR_MISC_FEATURES_ENABLES, msr);
 }
 
+static void bsp_init_intel(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_RETPOLINE
+	setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
+#endif
+}
+
 static void init_intel(struct cpuinfo_x86 *c)
 {
 	unsigned int l2 = 0;
@@ -893,6 +900,7 @@ static const struct cpu_dev intel_cpu_dev = {
 	.c_detect_tlb	= intel_detect_tlb,
 	.c_early_init   = early_init_intel,
 	.c_init		= init_intel,
+	.c_bsp_init	= bsp_init_intel,
 	.c_bsp_resume	= intel_bsp_resume,
 	.c_x86_vendor	= X86_VENDOR_INTEL,
 };

-- 
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 

  reply	other threads:[~2018-01-07 14:04 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-04  9:10 [RFC] Retpoline: Binary mitigation for branch-target-injection (aka "Spectre") Paul Turner
2018-01-04  9:12 ` Paul Turner
2018-01-04  9:24 ` Paul Turner
2018-01-04  9:48   ` Greg Kroah-Hartman
2018-01-04  9:56     ` Woodhouse, David
2018-01-04  9:30 ` Woodhouse, David
2018-01-04 14:36   ` [PATCH v3 01/13] x86/retpoline: Add initial retpoline support David Woodhouse
2018-01-04 18:03     ` Linus Torvalds
2018-01-04 19:32       ` Woodhouse, David
2018-01-04 18:17     ` Alexei Starovoitov
2018-01-04 18:25       ` Linus Torvalds
2018-01-04 18:36         ` Alexei Starovoitov
2018-01-04 19:27           ` David Woodhouse
2018-01-05 10:28             ` Paul Turner
2018-01-05 10:55               ` David Woodhouse
2018-01-05 11:19                 ` Paul Turner
2018-01-05 11:25                 ` Paul Turner
2018-01-05 11:26               ` Paolo Bonzini
2018-01-05 12:20                 ` Paul Turner
2018-01-05 10:40         ` Paul Turner
2018-01-04 18:40       ` Andi Kleen
2018-01-05 10:32         ` Paul Turner
2018-01-05 12:54     ` Thomas Gleixner
2018-01-05 13:01       ` Juergen Gross
2018-01-05 13:03         ` Thomas Gleixner
2018-01-05 13:56       ` Woodhouse, David
2018-01-05 16:41         ` Woodhouse, David
2018-01-05 16:45           ` Borislav Petkov
2018-01-05 17:08             ` Josh Poimboeuf
2018-01-06  0:30               ` Borislav Petkov
2018-01-06  8:23                 ` David Woodhouse
2018-01-06 17:02                   ` Borislav Petkov
2018-01-07  9:40                     ` David Woodhouse
2018-01-07 11:46                       ` Borislav Petkov
2018-01-07 12:21                         ` David Woodhouse
2018-01-07 14:03                           ` Borislav Petkov [this message]
2018-01-08 21:50                             ` David Woodhouse
2018-01-08  5:06                 ` Josh Poimboeuf
2018-01-08  7:55                   ` Woodhouse, David
2018-01-05 17:12             ` Woodhouse, David
2018-01-05 17:28               ` Linus Torvalds
2018-01-05 17:48                 ` David Woodhouse
2018-01-05 18:05                 ` Andi Kleen
2018-01-05 20:32                 ` Woodhouse, David
2018-01-05 21:11                   ` Brian Gerst
2018-01-05 22:16                     ` Woodhouse, David
2018-01-05 22:43                       ` Borislav Petkov
2018-01-05 22:00                 ` Woodhouse, David
2018-01-05 22:06                   ` Borislav Petkov
2018-01-05 23:50                   ` Linus Torvalds
2018-01-06 10:53                     ` Woodhouse, David
2018-01-04 14:36   ` [PATCH v3 02/13] x86/retpoline/crypto: Convert crypto assembler indirect jumps David Woodhouse
2018-01-04 14:37   ` [PATCH v3 03/13] x86/retpoline/entry: Convert entry " David Woodhouse
2018-01-04 14:46     ` Dave Hansen
2018-01-04 14:49       ` Woodhouse, David
2018-01-04 14:37   ` [PATCH v3 04/13] x86/retpoline/ftrace: Convert ftrace " David Woodhouse
2018-01-04 14:37   ` [PATCH v3 05/13] x86/retpoline/hyperv: Convert " David Woodhouse
2018-01-04 14:37   ` [PATCH v3 06/13] x86/retpoline/xen: Convert Xen hypercall " David Woodhouse
2018-01-04 15:10     ` Juergen Gross
2018-01-04 15:18       ` David Woodhouse
2018-01-04 15:54     ` Juergen Gross
2018-01-04 14:37   ` [PATCH v3 07/13] x86/retpoline/checksum32: Convert assembler " David Woodhouse
2018-01-04 14:37   ` [PATCH v3 08/13] x86/alternatives: Add missing \n at end of ALTERNATIVE inline asm David Woodhouse
2018-01-05 13:04     ` [tip:x86/pti] x86/alternatives: Add missing '\n' " tip-bot for David Woodhouse
2018-01-04 14:37   ` [PATCH v3 09/13] x86/retpoline/irq32: Convert assembler indirect jumps David Woodhouse
2018-01-04 14:37   ` [PATCH v3 10/13] x86/retpoline/pvops: " David Woodhouse
2018-01-04 15:02     ` Juergen Gross
2018-01-04 15:12       ` Woodhouse, David
2018-01-04 15:18       ` Andrew Cooper
2018-01-04 16:04         ` Juergen Gross
2018-01-04 16:37       ` Andi Kleen
2018-01-04 14:37   ` [PATCH v3 11/13] retpoline/taint: Taint kernel for missing retpoline in compiler David Woodhouse
2018-01-04 22:06     ` Justin Forbes
2018-01-04 14:37   ` [PATCH v3 12/13] retpoline/objtool: Disable some objtool warnings David Woodhouse
2018-01-04 14:37   ` [PATCH v3 13/13] retpoline: Attempt to quiten objtool warning for unreachable code David Woodhouse
2018-01-04 16:18   ` [RFC] Retpoline: Binary mitigation for branch-target-injection (aka "Spectre") Andy Lutomirski
2018-01-04 16:24     ` David Woodhouse
2018-01-05 10:49     ` Paul Turner
2018-01-05 11:43       ` Woodhouse, David

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=20180107140351.iukmbuf2xkqtvyoz@pd.tnic \
    --to=bp@suse.de \
    --cc=ak@linux.intel.com \
    --cc=dave.hansen@intel.com \
    --cc=dwmw2@infradead.org \
    --cc=gnomes@lxorguk.ukuu.org.uk \
    --cc=gregkh@linux-foundation.org \
    --cc=jikos@kernel.org \
    --cc=jpoimboe@redhat.com \
    --cc=keescook@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=peterz@infradead.org \
    --cc=pjt@google.com \
    --cc=riel@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linux-foundation.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).