Commit 0a499fc5 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'core-speculation-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull speculation mitigation update from Ingo Molnar:
 "This adds the "mitigations=" bootline option, which offers a
  cross-arch set of options that will work on x86, PowerPC and s390 that
  will map to the arch specific option internally"

* 'core-speculation-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  s390/speculation: Support 'mitigations=' cmdline option
  powerpc/speculation: Support 'mitigations=' cmdline option
  x86/speculation: Support 'mitigations=' cmdline option
  cpu/speculation: Add 'mitigations=' cmdline option
parents e50c5d2e 0336e04a
...@@ -2544,6 +2544,38 @@ ...@@ -2544,6 +2544,38 @@
in the "bleeding edge" mini2440 support kernel at in the "bleeding edge" mini2440 support kernel at
http://repo.or.cz/w/linux-2.6/mini2440.git http://repo.or.cz/w/linux-2.6/mini2440.git
mitigations=
[X86,PPC,S390] Control optional mitigations for CPU
vulnerabilities. This is a set of curated,
arch-independent options, each of which is an
aggregation of existing arch-specific options.
off
Disable all optional CPU mitigations. This
improves system performance, but it may also
expose users to several CPU vulnerabilities.
Equivalent to: nopti [X86,PPC]
nospectre_v1 [PPC]
nobp=0 [S390]
nospectre_v2 [X86,PPC,S390]
spectre_v2_user=off [X86]
spec_store_bypass_disable=off [X86,PPC]
l1tf=off [X86]
auto (default)
Mitigate all CPU vulnerabilities, but leave SMT
enabled, even if it's vulnerable. This is for
users who don't want to be surprised by SMT
getting disabled across kernel upgrades, or who
have other ways of avoiding SMT-based attacks.
Equivalent to: (default behavior)
auto,nosmt
Mitigate all CPU vulnerabilities, disabling SMT
if needed. This is for users who always want to
be fully mitigated, even if it means losing SMT.
Equivalent to: l1tf=flush,nosmt [X86]
mminit_loglevel= mminit_loglevel=
[KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this
parameter allows control of the logging verbosity for parameter allows control of the logging verbosity for
......
...@@ -57,7 +57,7 @@ void setup_barrier_nospec(void) ...@@ -57,7 +57,7 @@ void setup_barrier_nospec(void)
enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR); security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR);
if (!no_nospec) if (!no_nospec && !cpu_mitigations_off())
enable_barrier_nospec(enable); enable_barrier_nospec(enable);
} }
...@@ -116,7 +116,7 @@ static int __init handle_nospectre_v2(char *p) ...@@ -116,7 +116,7 @@ static int __init handle_nospectre_v2(char *p)
early_param("nospectre_v2", handle_nospectre_v2); early_param("nospectre_v2", handle_nospectre_v2);
void setup_spectre_v2(void) void setup_spectre_v2(void)
{ {
if (no_spectrev2) if (no_spectrev2 || cpu_mitigations_off())
do_btb_flush_fixups(); do_btb_flush_fixups();
else else
btb_flush_enabled = true; btb_flush_enabled = true;
...@@ -300,7 +300,7 @@ void setup_stf_barrier(void) ...@@ -300,7 +300,7 @@ void setup_stf_barrier(void)
stf_enabled_flush_types = type; stf_enabled_flush_types = type;
if (!no_stf_barrier) if (!no_stf_barrier && !cpu_mitigations_off())
stf_barrier_enable(enable); stf_barrier_enable(enable);
} }
......
...@@ -932,7 +932,7 @@ void setup_rfi_flush(enum l1d_flush_type types, bool enable) ...@@ -932,7 +932,7 @@ void setup_rfi_flush(enum l1d_flush_type types, bool enable)
enabled_flush_types = types; enabled_flush_types = types;
if (!no_rfi_flush) if (!no_rfi_flush && !cpu_mitigations_off())
rfi_flush_enable(enable); rfi_flush_enable(enable);
} }
......
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0
#include <linux/module.h> #include <linux/module.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/cpu.h>
#include <asm/nospec-branch.h> #include <asm/nospec-branch.h>
static int __init nobp_setup_early(char *str) static int __init nobp_setup_early(char *str)
...@@ -58,7 +59,7 @@ early_param("nospectre_v2", nospectre_v2_setup_early); ...@@ -58,7 +59,7 @@ early_param("nospectre_v2", nospectre_v2_setup_early);
void __init nospec_auto_detect(void) void __init nospec_auto_detect(void)
{ {
if (test_facility(156)) { if (test_facility(156) || cpu_mitigations_off()) {
/* /*
* The machine supports etokens. * The machine supports etokens.
* Disable expolines and disable nobp. * Disable expolines and disable nobp.
......
...@@ -440,7 +440,8 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) ...@@ -440,7 +440,8 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
char arg[20]; char arg[20];
int ret, i; int ret, i;
if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) if (cmdline_find_option_bool(boot_command_line, "nospectre_v2") ||
cpu_mitigations_off())
return SPECTRE_V2_CMD_NONE; return SPECTRE_V2_CMD_NONE;
ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg)); ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg));
...@@ -672,7 +673,8 @@ static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void) ...@@ -672,7 +673,8 @@ static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
char arg[20]; char arg[20];
int ret, i; int ret, i;
if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable")) { if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable") ||
cpu_mitigations_off()) {
return SPEC_STORE_BYPASS_CMD_NONE; return SPEC_STORE_BYPASS_CMD_NONE;
} else { } else {
ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable", ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable",
...@@ -1008,6 +1010,11 @@ static void __init l1tf_select_mitigation(void) ...@@ -1008,6 +1010,11 @@ static void __init l1tf_select_mitigation(void)
if (!boot_cpu_has_bug(X86_BUG_L1TF)) if (!boot_cpu_has_bug(X86_BUG_L1TF))
return; return;
if (cpu_mitigations_off())
l1tf_mitigation = L1TF_MITIGATION_OFF;
else if (cpu_mitigations_auto_nosmt())
l1tf_mitigation = L1TF_MITIGATION_FLUSH_NOSMT;
override_cache_bits(&boot_cpu_data); override_cache_bits(&boot_cpu_data);
switch (l1tf_mitigation) { switch (l1tf_mitigation) {
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/cpu.h>
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <asm/hypervisor.h> #include <asm/hypervisor.h>
...@@ -115,7 +116,8 @@ void __init pti_check_boottime_disable(void) ...@@ -115,7 +116,8 @@ void __init pti_check_boottime_disable(void)
} }
} }
if (cmdline_find_option_bool(boot_command_line, "nopti")) { if (cmdline_find_option_bool(boot_command_line, "nopti") ||
cpu_mitigations_off()) {
pti_mode = PTI_FORCE_OFF; pti_mode = PTI_FORCE_OFF;
pti_print_if_insecure("disabled on command line."); pti_print_if_insecure("disabled on command line.");
return; return;
......
...@@ -187,4 +187,28 @@ static inline void cpu_smt_disable(bool force) { } ...@@ -187,4 +187,28 @@ static inline void cpu_smt_disable(bool force) { }
static inline void cpu_smt_check_topology(void) { } static inline void cpu_smt_check_topology(void) { }
#endif #endif
/*
* These are used for a global "mitigations=" cmdline option for toggling
* optional CPU mitigations.
*/
enum cpu_mitigations {
CPU_MITIGATIONS_OFF,
CPU_MITIGATIONS_AUTO,
CPU_MITIGATIONS_AUTO_NOSMT,
};
extern enum cpu_mitigations cpu_mitigations;
/* mitigations=off */
static inline bool cpu_mitigations_off(void)
{
return cpu_mitigations == CPU_MITIGATIONS_OFF;
}
/* mitigations=auto,nosmt */
static inline bool cpu_mitigations_auto_nosmt(void)
{
return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT;
}
#endif /* _LINUX_CPU_H_ */ #endif /* _LINUX_CPU_H_ */
...@@ -2304,3 +2304,18 @@ void __init boot_cpu_hotplug_init(void) ...@@ -2304,3 +2304,18 @@ void __init boot_cpu_hotplug_init(void)
#endif #endif
this_cpu_write(cpuhp_state.state, CPUHP_ONLINE); this_cpu_write(cpuhp_state.state, CPUHP_ONLINE);
} }
enum cpu_mitigations cpu_mitigations __ro_after_init = CPU_MITIGATIONS_AUTO;
static int __init mitigations_parse_cmdline(char *arg)
{
if (!strcmp(arg, "off"))
cpu_mitigations = CPU_MITIGATIONS_OFF;
else if (!strcmp(arg, "auto"))
cpu_mitigations = CPU_MITIGATIONS_AUTO;
else if (!strcmp(arg, "auto,nosmt"))
cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT;
return 0;
}
early_param("mitigations", mitigations_parse_cmdline);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment