linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Linus Torvalds <torvalds@linuxfoundation.org>,
	x86@kernel.org, Peter Zijlstra <peterz@infradead.org>,
	Borislav Petkov <bp@alien8.de>,
	David Woodhouse <dwmw@amazon.co.uk>,
	Tim Chen <tim.c.chen@linux.intel.com>,
	Andrea Arcangeli <aarcange@redhat.com>,
	Andi Kleen <ak@linux.intel.com>,
	Greg KH <gregkh@linuxfoundation.org>,
	Dave Hansen <dave.hansen@intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	Arjan Van De Ven <arjan.van.de.ven@intel.com>
Subject: [patch RFC 3/5] x86/spectre: Prepare for IBRS selection
Date: Wed, 10 Jan 2018 02:06:55 +0100	[thread overview]
Message-ID: <20180110011350.662199342@linutronix.de> (raw)
In-Reply-To: 20180110010652.404145126@linutronix.de

[-- Attachment #1: x86-spectre--Prepare-for-IBRS-selection.patch --]
[-- Type: text/plain, Size: 7004 bytes --]

IBRS (Indirect Branch Restricted Speculation) is another mitigation method
for Spectre V2. So it needs to be integrated into the command line options.

That would be simple, but the new microcode which provides the
functionality is not widely deployed and gets potentially loaded late, so
the selection process might have to be repeated after micro code has loaded.

Split the command line parsing and the actual selection of the mitigation
method into two parts to prepare for IBRS support.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/include/asm/nospec-branch.h |   13 +++
 arch/x86/kernel/cpu/bugs.c           |  133 +++++++++++++++++++++++------------
 2 files changed, 101 insertions(+), 45 deletions(-)

--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -152,5 +152,18 @@
 # define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
 #endif
 
+/* The Spectre V2 mitigation variants */
+enum spectre_v2_mitigation {
+	SPECTRE_V2_NONE,
+	SPECTRE_V2_RETPOLINE_MINIMAL,
+	SPECTRE_V2_RETPOLINE_MINIMAL_AMD,
+	SPECTRE_V2_RETPOLINE_GENERIC,
+	SPECTRE_V2_RETPOLINE_AMD,
+	SPECTRE_V2_IBRS,
+};
+
+enum spectre_v2_mitigation spectre_v2_enabled;
+void spectre_v2_select_mitigation(void);
+
 #endif /* __ASSEMBLY__ */
 #endif /* __NOSPEC_BRANCH_H__ */
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -37,6 +37,7 @@ void __init check_bugs(void)
 
 	/* Select the proper spectre mitigation before patching alternatives */
 	spectre_v2_check_boottime_disable();
+	spectre_v2_select_mitigation();
 
 #ifdef CONFIG_X86_32
 	/*
@@ -70,12 +71,14 @@ void __init check_bugs(void)
 #endif
 }
 
-enum spectre_v2_mitigation {
-	SPECTRE_V2_NONE,
-	SPECTRE_V2_RETPOLINE_MINIMAL,
-	SPECTRE_V2_RETPOLINE_MINIMAL_AMD,
-	SPECTRE_V2_RETPOLINE_GENERIC,
-	SPECTRE_V2_RETPOLINE_AMD,
+/* The kernel command line selection */
+enum spectre_v2_mitigation_cmd {
+	SPECTRE_V2_CMD_NONE,
+	SPECTRE_V2_CMD_AUTO,
+	SPECTRE_V2_CMD_FORCE,
+	SPECTRE_V2_CMD_RETPOLINE,
+	SPECTRE_V2_CMD_RETPOLINE_GENERIC,
+	SPECTRE_V2_CMD_RETPOLINE_AMD,
 };
 
 static const char *spectre_v2_strings[] = {
@@ -89,7 +92,8 @@ static const char *spectre_v2_strings[]
 #undef pr_fmt
 #define pr_fmt(fmt)     "Spectre V2 mitigation: " fmt
 
-static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
+static enum spectre_v2_mitigation_cmd spectre_v2_cmdline = SPECTRE_V2_CMD_AUTO;
+enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
 
 static void __init spec2_print_if_insecure(const char *reason)
 {
@@ -124,66 +128,105 @@ static void __init spectre_v2_check_boot
 				  sizeof(arg));
 	if (ret > 0)  {
 		if (match_option(arg, ret, "off")) {
-			spec2_print_if_insecure("disabled on command line.");
 			goto disable;
 		} else if (match_option(arg, ret, "on")) {
 			spec2_print_if_secure("force enabled on command line.");
-			goto force;
+			spectre_v2_cmdline = SPECTRE_V2_CMD_FORCE;
+			return;
 		} else if (match_option(arg, ret, "retpoline")) {
 			spec2_print_if_insecure("retpoline selected on command line.");
-			goto retpoline;
+			spectre_v2_cmdline = SPECTRE_V2_CMD_RETPOLINE;
+			return;
 		} else if (match_option(arg, ret, "retpoline,amd")) {
+			if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+				pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n");
+				return;
+			}
 			spec2_print_if_insecure("AMD retpoline selected on command line.");
-			goto retpoline_amd;
+			spectre_v2_cmdline = SPECTRE_V2_CMD_RETPOLINE_AMD;
+			return;
 		} else if (match_option(arg, ret, "retpoline,generic")) {
 			spec2_print_if_insecure("generic retpoline selected on command line.");
-			goto retpoline_generic;
+			spectre_v2_cmdline = SPECTRE_V2_CMD_RETPOLINE_GENERIC;
+			return;
 		} else if (match_option(arg, ret, "auto")) {
-			goto autosel;
+			return;
 		}
 	}
 
-	if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) {
-		spec2_print_if_insecure("disabled on command line.");
-		goto disable;
-	}
+	if (!cmdline_find_option_bool(boot_command_line, "nospectre_v2"))
+		return;
+disable:
+	spec2_print_if_insecure("disabled on command line.");
+	spectre_v2_cmdline = SPECTRE_V2_CMD_NONE;
+}
 
-autosel:
-	if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
-		goto disable;
+void spectre_v2_select_mitigation(void)
+{
+	enum spectre_v2_mitigation mode = SPECTRE_V2_NONE;
 
-force:
-#ifdef CONFIG_RETPOLINE
-retpoline:
+	/*
+	 * If the CPU is not affected and the command line mode is NONE or AUTO
+	 * then nothing to do.
+	 */
+	if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2) &&
+	    (spectre_v2_cmdline == SPECTRE_V2_CMD_NONE ||
+	     spectre_v2_cmdline == SPECTRE_V2_CMD_AUTO))
+		return;
+
+	switch (spectre_v2_cmdline) {
+	case SPECTRE_V2_CMD_NONE:
+		return;
+
+	case SPECTRE_V2_CMD_FORCE:
+		/* FALLTRHU */
+	case SPECTRE_V2_CMD_AUTO:
+		goto retpoline_auto;
+
+	case SPECTRE_V2_CMD_RETPOLINE_AMD:
+		if (IS_ENABLED(CONFIG_RETPOLINE))
+			goto retpoline_amd;
+		break;
+	case SPECTRE_V2_CMD_RETPOLINE_GENERIC:
+		if (IS_ENABLED(CONFIG_RETPOLINE))
+			goto retpoline_generic;
+		break;
+	case SPECTRE_V2_CMD_RETPOLINE:
+		if (IS_ENABLED(CONFIG_RETPOLINE))
+			goto retpoline_auto;
+		break;
+	}
+	pr_err("kernel not compiled with retpoline; no mitigation available!");
+	return;
+
+retpoline_auto:
+	/*
+	 * Note: This only takes effect during boot before alternatives
+	 * have been patched. Later invocations after late micro code
+	 * update wont change the boot selection even if IBRS has not been
+	 * made available by the microcode loading.
+	 */
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
 	retpoline_amd:
-		if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD ||
-		    !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
-			pr_info("AMD retpoline not supported, fall back to generic\n");
+		if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
+			pr_info("LFENCE not serializing, using to generic mode\n");
 			goto retpoline_generic;
 		}
-
-		spectre_v2_enabled = retp_compiler() ?
-			SPECTRE_V2_RETPOLINE_AMD : SPECTRE_V2_RETPOLINE_MINIMAL_AMD;
+		mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD :
+					 SPECTRE_V2_RETPOLINE_MINIMAL_AMD;
 		setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
 		setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
-		return;
+	} else {
+	retpoline_generic:
+		mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_GENERIC :
+					 SPECTRE_V2_RETPOLINE_MINIMAL;
+		setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
 	}
-retpoline_generic:
-	spectre_v2_enabled = retp_compiler() ?
-		SPECTRE_V2_RETPOLINE_GENERIC : SPECTRE_V2_RETPOLINE_MINIMAL;
-	setup_force_cpu_cap(X86_FEATURE_RETPOLINE);
-	return;
-#else
-retpoline:
-retpoline_amd:
-retpoline_generic:
-	pr_err("kernel not compiled with retpoline; no mitigation available!");
-#endif
-disable:
-	setup_clear_cpu_cap(X86_FEATURE_RETPOLINE);
-	setup_clear_cpu_cap(X86_FEATURE_RETPOLINE_AMD);
-	return;
+
+	if (spectre_v2_enabled == mode)
+		return;
+	spectre_v2_enabled = mode;
+	pr_info("%s\n", spectre_v2_strings[mode]);
 }
 
 #undef pr_fmt

  parent reply	other threads:[~2018-01-10  1:21 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-10  1:06 [patch RFC 0/5] x86/spectre_v2: Initial integration of IBRS into the spectre_v2 mechanics Thomas Gleixner
2018-01-10  1:06 ` [patch RFC 1/5] x86/CPU: Sync CPU feature flags late Thomas Gleixner
2018-01-10  1:37   ` Dave Hansen
2018-01-10  1:39     ` Van De Ven, Arjan
2018-01-10  1:47       ` Thomas Gleixner
2018-01-10  2:57         ` Andy Lutomirski
2018-01-10 11:02           ` Thomas Gleixner
2018-01-10  1:44     ` Thomas Gleixner
2018-01-10  6:20     ` Ingo Molnar
2018-01-10 11:33       ` Borislav Petkov
2018-01-10 12:38         ` Thomas Gleixner
2018-01-10  1:06 ` [patch RFC 2/5] x86/spectre: Simplify spectre code a bit Thomas Gleixner
2018-01-10  6:22   ` Ingo Molnar
2018-01-10  1:06 ` Thomas Gleixner [this message]
2018-01-10  1:51   ` [patch RFC 3/5] x86/spectre: Prepare for IBRS selection Dave Hansen
2018-01-10  1:06 ` [patch RFC 4/5] x86/cpufeatures: Detect Speculation control feature Thomas Gleixner
2018-01-10  6:32   ` Ingo Molnar
2018-01-10 11:06     ` Thomas Gleixner
2018-01-10  1:06 ` [patch RFC 5/5] x86/speculation: Add basic speculation control code Thomas Gleixner
2018-01-10  2:02   ` Dave Hansen
2018-01-10  4:11     ` Justin Forbes
2018-01-10  9:22     ` Peter Zijlstra
2018-01-10  9:27       ` David Woodhouse
2018-01-10 10:03         ` Peter Zijlstra
2018-01-10 11:22           ` David Woodhouse
2018-01-10 11:41             ` Thomas Gleixner
2018-01-10 11:45             ` Peter Zijlstra
2018-01-10 11:54         ` Andrea Arcangeli
2018-01-10 11:58           ` David Woodhouse
2018-01-10 12:01             ` Andrea Arcangeli
2018-01-10 12:07               ` Andrea Arcangeli
2018-01-10 12:12                 ` David Woodhouse
2018-01-10 12:20                   ` Andrea Arcangeli
2018-01-10 12:27                     ` Andrea Arcangeli
2018-01-10 13:42                     ` Van De Ven, Arjan
2018-01-10 12:09               ` David Woodhouse
2018-01-10 12:17                 ` Andrea Arcangeli
2018-01-10 12:29                   ` David Woodhouse
2018-01-10 12:41                     ` Andrea Arcangeli
2018-01-10 12:47                       ` Jiri Kosina
2018-01-10 12:51                         ` David Woodhouse
2018-01-10 13:02                           ` Andrea Arcangeli
2018-01-10 13:05                             ` Andrea Arcangeli
2018-01-10 13:10                               ` Andrea Arcangeli
2018-01-10 13:12                                 ` Andrea Arcangeli
2018-01-10 12:57                         ` Andrea Arcangeli
2018-01-10 13:07                           ` David Woodhouse
2018-01-10 13:45                             ` Van De Ven, Arjan
2018-01-10 13:52                               ` Andrea Arcangeli
2018-01-10 13:53                                 ` Van De Ven, Arjan
2018-01-10 21:35                                   ` Tim Chen
2018-01-10 22:13                                     ` Andrea Arcangeli
2018-01-10 13:46                             ` Thomas Gleixner
2018-01-10 13:51                               ` Van De Ven, Arjan
2018-01-10 13:53                                 ` Thomas Gleixner
2018-01-10 13:58                               ` David Woodhouse
2018-01-10 14:10                               ` Andrea Arcangeli
2018-01-10 14:14                                 ` Van De Ven, Arjan
2018-01-10 14:59                                 ` Dave Hansen
2018-01-10 15:13                                   ` Andrea Arcangeli
2018-01-10 15:24                                     ` David Woodhouse
2018-01-10 15:47                                       ` Andrea Arcangeli
2018-01-10 15:56                                         ` David Woodhouse
2018-01-10 13:10                           ` Jiri Kosina

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=20180110011350.662199342@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=aarcange@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=arjan.van.de.ven@intel.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@intel.com \
    --cc=dwmw@amazon.co.uk \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linuxfoundation.org \
    --cc=x86@kernel.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).