All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, stable@vger.kernel.org
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [PATCH 15/19] s390: add automatic detection of the spectre defense
Date: Fri, 27 Apr 2018 07:36:53 +0200	[thread overview]
Message-ID: <20180427053657.56944-16-schwidefsky@de.ibm.com> (raw)
In-Reply-To: <20180427053657.56944-1-schwidefsky@de.ibm.com>

[ Upstream commit 6e179d64126b909f0b288fa63cdbf07c531e9b1d ]

Automatically decide between nobp vs. expolines if the spectre_v2=auto
kernel parameter is specified or CONFIG_EXPOLINE_AUTO=y is set.

The decision made at boot time due to CONFIG_EXPOLINE_AUTO=y being set
can be overruled with the nobp, nospec and spectre_v2 kernel parameters.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
---
 arch/s390/Kconfig                     |  2 +-
 arch/s390/Makefile                    |  2 +-
 arch/s390/include/asm/nospec-branch.h |  6 ++--
 arch/s390/kernel/alternative.c        |  1 +
 arch/s390/kernel/module.c             | 11 +++---
 arch/s390/kernel/nospec-branch.c      | 68 +++++++++++++++++++++--------------
 6 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index c88bb4a50db7..fbb8fca6f9c2 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -741,7 +741,7 @@ choice
 config EXPOLINE_OFF
 	bool "spectre_v2=off"
 
-config EXPOLINE_MEDIUM
+config EXPOLINE_AUTO
 	bool "spectre_v2=auto"
 
 config EXPOLINE_FULL
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index d241a9fddf43..bef67c0f63e2 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -85,7 +85,7 @@ ifdef CONFIG_EXPOLINE
     CC_FLAGS_EXPOLINE += -mfunction-return=thunk
     CC_FLAGS_EXPOLINE += -mindirect-branch-table
     export CC_FLAGS_EXPOLINE
-    cflags-y += $(CC_FLAGS_EXPOLINE)
+    cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE
   endif
 endif
 
diff --git a/arch/s390/include/asm/nospec-branch.h b/arch/s390/include/asm/nospec-branch.h
index 7df48e5cf36f..35bf28fe4c64 100644
--- a/arch/s390/include/asm/nospec-branch.h
+++ b/arch/s390/include/asm/nospec-branch.h
@@ -6,12 +6,10 @@
 
 #include <linux/types.h>
 
-extern int nospec_call_disable;
-extern int nospec_return_disable;
+extern int nospec_disable;
 
 void nospec_init_branches(void);
-void nospec_call_revert(s32 *start, s32 *end);
-void nospec_return_revert(s32 *start, s32 *end);
+void nospec_revert(s32 *start, s32 *end);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/s390/kernel/alternative.c b/arch/s390/kernel/alternative.c
index f5060af61176..b57b293998dc 100644
--- a/arch/s390/kernel/alternative.c
+++ b/arch/s390/kernel/alternative.c
@@ -1,6 +1,7 @@
 #include <linux/module.h>
 #include <asm/alternative.h>
 #include <asm/facility.h>
+#include <asm/nospec-branch.h>
 
 #define MAX_PATCH_LEN (255 - 1)
 
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index f461b09b3e85..f3f7321bef1a 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -171,7 +171,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 	me->core_layout.size += me->arch.got_size;
 	me->arch.plt_offset = me->core_layout.size;
 	if (me->arch.plt_size) {
-		if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_call_disable)
+		if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable)
 			me->arch.plt_size += PLT_ENTRY_SIZE;
 		me->core_layout.size += me->arch.plt_size;
 	}
@@ -330,8 +330,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
 				info->plt_offset;
 			ip[0] = 0x0d10e310;	/* basr 1,0  */
 			ip[1] = 0x100a0004;	/* lg	1,10(1) */
-			if (IS_ENABLED(CONFIG_EXPOLINE) &&
-			    !nospec_call_disable) {
+			if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
 				unsigned int *ij;
 				ij = me->core_layout.base +
 					me->arch.plt_offset +
@@ -452,7 +451,7 @@ int module_finalize(const Elf_Ehdr *hdr,
 	void *aseg;
 
 	if (IS_ENABLED(CONFIG_EXPOLINE) &&
-	    !nospec_call_disable && me->arch.plt_size) {
+	    !nospec_disable && me->arch.plt_size) {
 		unsigned int *ij;
 
 		ij = me->core_layout.base + me->arch.plt_offset +
@@ -479,11 +478,11 @@ int module_finalize(const Elf_Ehdr *hdr,
 
 		if (IS_ENABLED(CONFIG_EXPOLINE) &&
 		    (!strcmp(".nospec_call_table", secname)))
-			nospec_call_revert(aseg, aseg + s->sh_size);
+			nospec_revert(aseg, aseg + s->sh_size);
 
 		if (IS_ENABLED(CONFIG_EXPOLINE) &&
 		    (!strcmp(".nospec_return_table", secname)))
-			nospec_return_revert(aseg, aseg + s->sh_size);
+			nospec_revert(aseg, aseg + s->sh_size);
 	}
 
 	jump_label_apply_nops(me);
diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c
index 3ce59d044a4d..daa36a38a8b7 100644
--- a/arch/s390/kernel/nospec-branch.c
+++ b/arch/s390/kernel/nospec-branch.c
@@ -11,10 +11,17 @@ static int __init nobp_setup_early(char *str)
 	rc = kstrtobool(str, &enabled);
 	if (rc)
 		return rc;
-	if (enabled && test_facility(82))
+	if (enabled && test_facility(82)) {
+		/*
+		 * The user explicitely requested nobp=1, enable it and
+		 * disable the expoline support.
+		 */
 		__set_facility(82, S390_lowcore.alt_stfle_fac_list);
-	else
+		if (IS_ENABLED(CONFIG_EXPOLINE))
+			nospec_disable = 1;
+	} else {
 		__clear_facility(82, S390_lowcore.alt_stfle_fac_list);
+	}
 	return 0;
 }
 early_param("nobp", nobp_setup_early);
@@ -28,31 +35,46 @@ early_param("nospec", nospec_setup_early);
 
 #ifdef CONFIG_EXPOLINE
 
-int nospec_call_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
-int nospec_return_disable = !IS_ENABLED(CONFIG_EXPOLINE_FULL);
+int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF);
 
 static int __init nospectre_v2_setup_early(char *str)
 {
-	nospec_call_disable = 1;
-	nospec_return_disable = 1;
+	nospec_disable = 1;
 	return 0;
 }
 early_param("nospectre_v2", nospectre_v2_setup_early);
 
+static int __init spectre_v2_auto_early(void)
+{
+	if (IS_ENABLED(CC_USING_EXPOLINE)) {
+		/*
+		 * The kernel has been compiled with expolines.
+		 * Keep expolines enabled and disable nobp.
+		 */
+		nospec_disable = 0;
+		__clear_facility(82, S390_lowcore.alt_stfle_fac_list);
+	}
+	/*
+	 * If the kernel has not been compiled with expolines the
+	 * nobp setting decides what is done, this depends on the
+	 * CONFIG_KERNEL_NP option and the nobp/nospec parameters.
+	 */
+	return 0;
+}
+#ifdef CONFIG_EXPOLINE_AUTO
+early_initcall(spectre_v2_auto_early);
+#endif
+
 static int __init spectre_v2_setup_early(char *str)
 {
 	if (str && !strncmp(str, "on", 2)) {
-		nospec_call_disable = 0;
-		nospec_return_disable = 0;
-	}
-	if (str && !strncmp(str, "off", 3)) {
-		nospec_call_disable = 1;
-		nospec_return_disable = 1;
-	}
-	if (str && !strncmp(str, "auto", 4)) {
-		nospec_call_disable = 0;
-		nospec_return_disable = 1;
+		nospec_disable = 0;
+		__clear_facility(82, S390_lowcore.alt_stfle_fac_list);
 	}
+	if (str && !strncmp(str, "off", 3))
+		nospec_disable = 1;
+	if (str && !strncmp(str, "auto", 4))
+		spectre_v2_auto_early();
 	return 0;
 }
 early_param("spectre_v2", spectre_v2_setup_early);
@@ -105,15 +127,9 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end)
 	}
 }
 
-void __init_or_module nospec_call_revert(s32 *start, s32 *end)
-{
-	if (nospec_call_disable)
-		__nospec_revert(start, end);
-}
-
-void __init_or_module nospec_return_revert(s32 *start, s32 *end)
+void __init_or_module nospec_revert(s32 *start, s32 *end)
 {
-	if (nospec_return_disable)
+	if (nospec_disable)
 		__nospec_revert(start, end);
 }
 
@@ -121,8 +137,8 @@ extern s32 __nospec_call_start[], __nospec_call_end[];
 extern s32 __nospec_return_start[], __nospec_return_end[];
 void __init nospec_init_branches(void)
 {
-	nospec_call_revert(__nospec_call_start, __nospec_call_end);
-	nospec_return_revert(__nospec_return_start, __nospec_return_end);
+	nospec_revert(__nospec_call_start, __nospec_call_end);
+	nospec_revert(__nospec_return_start, __nospec_return_end);
 }
 
 #endif /* CONFIG_EXPOLINE */
-- 
2.13.5

  parent reply	other threads:[~2018-04-27  5:37 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-27  5:36 [PATCH 00/19] s390 spectre mititgation for 4.9 Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 01/19] s390: introduce CPU alternatives Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 02/19] s390: enable CPU alternatives unconditionally Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 03/19] KVM: s390: wire up bpb feature Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 04/19] s390: scrub registers on kernel entry and KVM exit Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 05/19] s390: add optimized array_index_mask_nospec Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 06/19] s390/alternative: use a copy of the facility bit mask Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 07/19] s390: add options to change branch prediction behaviour for the kernel Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 08/19] s390: run user space and KVM guests with modified branch prediction Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 09/19] s390: introduce execute-trampolines for branches Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 10/19] KVM: s390: force bp isolation for VSIE Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 11/19] s390: Replace IS_ENABLED(EXPOLINE_*) with IS_ENABLED(CONFIG_EXPOLINE_*) Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 12/19] s390: do not bypass BPENTER for interrupt system calls Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 13/19] s390/entry.S: fix spurious zeroing of r0 Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 14/19] s390: move nobp parameter functions to nospec-branch.c Martin Schwidefsky
2018-04-27  5:36 ` Martin Schwidefsky [this message]
2018-04-27  5:36 ` [PATCH 16/19] s390: report spectre mitigation via syslog Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 17/19] s390: add sysfs attributes for spectre Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 18/19] s390: correct nospec auto detection init order Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 19/19] s390: correct module section names for expoline code revert Martin Schwidefsky
2018-04-27 10:11 ` [PATCH 00/19] s390 spectre mititgation for 4.9 Greg Kroah-Hartman
  -- strict thread matches above, loose matches on Subject: below --
2018-04-27  5:36 [PATCH 00/19] s390 spectre mititgation for 4.14 Martin Schwidefsky
2018-04-27  5:36 ` [PATCH 15/19] s390: add automatic detection of the spectre defense Martin Schwidefsky

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=20180427053657.56944-16-schwidefsky@de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=stable@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.