diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2019-04-17 15:38:16 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2019-04-17 15:55:31 -0400 |
commit | e9fee6fe08eef51cd9a7455d18b9011f1e463f22 (patch) | |
tree | 12df824e278d3bf25644cbb1f680e69044b02d07 | |
parent | e2c3c94788b08891dcf3dbe608f9880523ecd71b (diff) | |
parent | 0336e04a6520bdaefdb0769d2a70084fa52e81ed (diff) |
Merge branch 'core/speculation' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git
Pull in the command line updates from the tip tree so the MDS parts can be
added.
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 32 | ||||
-rw-r--r-- | arch/powerpc/kernel/security.c | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/nospec-branch.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/bugs.c | 11 | ||||
-rw-r--r-- | arch/x86/mm/pti.c | 4 | ||||
-rw-r--r-- | include/linux/cpu.h | 24 | ||||
-rw-r--r-- | kernel/cpu.c | 15 |
8 files changed, 89 insertions, 8 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 8f04985d3122..9aa3543a8723 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
@@ -2539,6 +2539,38 @@ | |||
2539 | in the "bleeding edge" mini2440 support kernel at | 2539 | in the "bleeding edge" mini2440 support kernel at |
2540 | http://repo.or.cz/w/linux-2.6/mini2440.git | 2540 | http://repo.or.cz/w/linux-2.6/mini2440.git |
2541 | 2541 | ||
2542 | mitigations= | ||
2543 | [X86,PPC,S390] Control optional mitigations for CPU | ||
2544 | vulnerabilities. This is a set of curated, | ||
2545 | arch-independent options, each of which is an | ||
2546 | aggregation of existing arch-specific options. | ||
2547 | |||
2548 | off | ||
2549 | Disable all optional CPU mitigations. This | ||
2550 | improves system performance, but it may also | ||
2551 | expose users to several CPU vulnerabilities. | ||
2552 | Equivalent to: nopti [X86,PPC] | ||
2553 | nospectre_v1 [PPC] | ||
2554 | nobp=0 [S390] | ||
2555 | nospectre_v2 [X86,PPC,S390] | ||
2556 | spectre_v2_user=off [X86] | ||
2557 | spec_store_bypass_disable=off [X86,PPC] | ||
2558 | l1tf=off [X86] | ||
2559 | |||
2560 | auto (default) | ||
2561 | Mitigate all CPU vulnerabilities, but leave SMT | ||
2562 | enabled, even if it's vulnerable. This is for | ||
2563 | users who don't want to be surprised by SMT | ||
2564 | getting disabled across kernel upgrades, or who | ||
2565 | have other ways of avoiding SMT-based attacks. | ||
2566 | Equivalent to: (default behavior) | ||
2567 | |||
2568 | auto,nosmt | ||
2569 | Mitigate all CPU vulnerabilities, disabling SMT | ||
2570 | if needed. This is for users who always want to | ||
2571 | be fully mitigated, even if it means losing SMT. | ||
2572 | Equivalent to: l1tf=flush,nosmt [X86] | ||
2573 | |||
2542 | mminit_loglevel= | 2574 | mminit_loglevel= |
2543 | [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this | 2575 | [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this |
2544 | parameter allows control of the logging verbosity for | 2576 | parameter allows control of the logging verbosity for |
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c index 9b8631533e02..cdf3e73000e9 100644 --- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c | |||
@@ -57,7 +57,7 @@ void setup_barrier_nospec(void) | |||
57 | enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && | 57 | enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && |
58 | security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR); | 58 | security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR); |
59 | 59 | ||
60 | if (!no_nospec) | 60 | if (!no_nospec && !cpu_mitigations_off()) |
61 | enable_barrier_nospec(enable); | 61 | enable_barrier_nospec(enable); |
62 | } | 62 | } |
63 | 63 | ||
@@ -116,7 +116,7 @@ static int __init handle_nospectre_v2(char *p) | |||
116 | early_param("nospectre_v2", handle_nospectre_v2); | 116 | early_param("nospectre_v2", handle_nospectre_v2); |
117 | void setup_spectre_v2(void) | 117 | void setup_spectre_v2(void) |
118 | { | 118 | { |
119 | if (no_spectrev2) | 119 | if (no_spectrev2 || cpu_mitigations_off()) |
120 | do_btb_flush_fixups(); | 120 | do_btb_flush_fixups(); |
121 | else | 121 | else |
122 | btb_flush_enabled = true; | 122 | btb_flush_enabled = true; |
@@ -307,7 +307,7 @@ void setup_stf_barrier(void) | |||
307 | 307 | ||
308 | stf_enabled_flush_types = type; | 308 | stf_enabled_flush_types = type; |
309 | 309 | ||
310 | if (!no_stf_barrier) | 310 | if (!no_stf_barrier && !cpu_mitigations_off()) |
311 | stf_barrier_enable(enable); | 311 | stf_barrier_enable(enable); |
312 | } | 312 | } |
313 | 313 | ||
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 236c1151a3a7..c7ec27ba8926 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -958,7 +958,7 @@ void setup_rfi_flush(enum l1d_flush_type types, bool enable) | |||
958 | 958 | ||
959 | enabled_flush_types = types; | 959 | enabled_flush_types = types; |
960 | 960 | ||
961 | if (!no_rfi_flush) | 961 | if (!no_rfi_flush && !cpu_mitigations_off()) |
962 | rfi_flush_enable(enable); | 962 | rfi_flush_enable(enable); |
963 | } | 963 | } |
964 | 964 | ||
diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c index bdddaae96559..649135cbedd5 100644 --- a/arch/s390/kernel/nospec-branch.c +++ b/arch/s390/kernel/nospec-branch.c | |||
@@ -1,6 +1,7 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/module.h> | 2 | #include <linux/module.h> |
3 | #include <linux/device.h> | 3 | #include <linux/device.h> |
4 | #include <linux/cpu.h> | ||
4 | #include <asm/nospec-branch.h> | 5 | #include <asm/nospec-branch.h> |
5 | 6 | ||
6 | static int __init nobp_setup_early(char *str) | 7 | static int __init nobp_setup_early(char *str) |
@@ -58,7 +59,7 @@ early_param("nospectre_v2", nospectre_v2_setup_early); | |||
58 | 59 | ||
59 | void __init nospec_auto_detect(void) | 60 | void __init nospec_auto_detect(void) |
60 | { | 61 | { |
61 | if (test_facility(156)) { | 62 | if (test_facility(156) || cpu_mitigations_off()) { |
62 | /* | 63 | /* |
63 | * The machine supports etokens. | 64 | * The machine supports etokens. |
64 | * Disable expolines and disable nobp. | 65 | * Disable expolines and disable nobp. |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 6b8a55c7cebc..3c5c3c3ba734 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
@@ -506,7 +506,8 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) | |||
506 | char arg[20]; | 506 | char arg[20]; |
507 | int ret, i; | 507 | int ret, i; |
508 | 508 | ||
509 | if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) | 509 | if (cmdline_find_option_bool(boot_command_line, "nospectre_v2") || |
510 | cpu_mitigations_off()) | ||
510 | return SPECTRE_V2_CMD_NONE; | 511 | return SPECTRE_V2_CMD_NONE; |
511 | 512 | ||
512 | ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg)); | 513 | ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg)); |
@@ -771,7 +772,8 @@ static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void) | |||
771 | char arg[20]; | 772 | char arg[20]; |
772 | int ret, i; | 773 | int ret, i; |
773 | 774 | ||
774 | if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable")) { | 775 | if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable") || |
776 | cpu_mitigations_off()) { | ||
775 | return SPEC_STORE_BYPASS_CMD_NONE; | 777 | return SPEC_STORE_BYPASS_CMD_NONE; |
776 | } else { | 778 | } else { |
777 | ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable", | 779 | ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable", |
@@ -1095,6 +1097,11 @@ static void __init l1tf_select_mitigation(void) | |||
1095 | if (!boot_cpu_has_bug(X86_BUG_L1TF)) | 1097 | if (!boot_cpu_has_bug(X86_BUG_L1TF)) |
1096 | return; | 1098 | return; |
1097 | 1099 | ||
1100 | if (cpu_mitigations_off()) | ||
1101 | l1tf_mitigation = L1TF_MITIGATION_OFF; | ||
1102 | else if (cpu_mitigations_auto_nosmt()) | ||
1103 | l1tf_mitigation = L1TF_MITIGATION_FLUSH_NOSMT; | ||
1104 | |||
1098 | override_cache_bits(&boot_cpu_data); | 1105 | override_cache_bits(&boot_cpu_data); |
1099 | 1106 | ||
1100 | switch (l1tf_mitigation) { | 1107 | switch (l1tf_mitigation) { |
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c index 4fee5c3003ed..5890f09bfc19 100644 --- a/arch/x86/mm/pti.c +++ b/arch/x86/mm/pti.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/mm.h> | 36 | #include <linux/mm.h> |
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | #include <linux/cpu.h> | ||
38 | 39 | ||
39 | #include <asm/cpufeature.h> | 40 | #include <asm/cpufeature.h> |
40 | #include <asm/hypervisor.h> | 41 | #include <asm/hypervisor.h> |
@@ -115,7 +116,8 @@ void __init pti_check_boottime_disable(void) | |||
115 | } | 116 | } |
116 | } | 117 | } |
117 | 118 | ||
118 | if (cmdline_find_option_bool(boot_command_line, "nopti")) { | 119 | if (cmdline_find_option_bool(boot_command_line, "nopti") || |
120 | cpu_mitigations_off()) { | ||
119 | pti_mode = PTI_FORCE_OFF; | 121 | pti_mode = PTI_FORCE_OFF; |
120 | pti_print_if_insecure("disabled on command line."); | 122 | pti_print_if_insecure("disabled on command line."); |
121 | return; | 123 | return; |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 3c87ad888ed3..57ae83c4d5f4 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -189,4 +189,28 @@ static inline void cpu_smt_disable(bool force) { } | |||
189 | static inline void cpu_smt_check_topology(void) { } | 189 | static inline void cpu_smt_check_topology(void) { } |
190 | #endif | 190 | #endif |
191 | 191 | ||
192 | /* | ||
193 | * These are used for a global "mitigations=" cmdline option for toggling | ||
194 | * optional CPU mitigations. | ||
195 | */ | ||
196 | enum cpu_mitigations { | ||
197 | CPU_MITIGATIONS_OFF, | ||
198 | CPU_MITIGATIONS_AUTO, | ||
199 | CPU_MITIGATIONS_AUTO_NOSMT, | ||
200 | }; | ||
201 | |||
202 | extern enum cpu_mitigations cpu_mitigations; | ||
203 | |||
204 | /* mitigations=off */ | ||
205 | static inline bool cpu_mitigations_off(void) | ||
206 | { | ||
207 | return cpu_mitigations == CPU_MITIGATIONS_OFF; | ||
208 | } | ||
209 | |||
210 | /* mitigations=auto,nosmt */ | ||
211 | static inline bool cpu_mitigations_auto_nosmt(void) | ||
212 | { | ||
213 | return cpu_mitigations == CPU_MITIGATIONS_AUTO_NOSMT; | ||
214 | } | ||
215 | |||
192 | #endif /* _LINUX_CPU_H_ */ | 216 | #endif /* _LINUX_CPU_H_ */ |
diff --git a/kernel/cpu.c b/kernel/cpu.c index d1c6d152da89..e70a90634b41 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -2279,3 +2279,18 @@ void __init boot_cpu_hotplug_init(void) | |||
2279 | #endif | 2279 | #endif |
2280 | this_cpu_write(cpuhp_state.state, CPUHP_ONLINE); | 2280 | this_cpu_write(cpuhp_state.state, CPUHP_ONLINE); |
2281 | } | 2281 | } |
2282 | |||
2283 | enum cpu_mitigations cpu_mitigations __ro_after_init = CPU_MITIGATIONS_AUTO; | ||
2284 | |||
2285 | static int __init mitigations_parse_cmdline(char *arg) | ||
2286 | { | ||
2287 | if (!strcmp(arg, "off")) | ||
2288 | cpu_mitigations = CPU_MITIGATIONS_OFF; | ||
2289 | else if (!strcmp(arg, "auto")) | ||
2290 | cpu_mitigations = CPU_MITIGATIONS_AUTO; | ||
2291 | else if (!strcmp(arg, "auto,nosmt")) | ||
2292 | cpu_mitigations = CPU_MITIGATIONS_AUTO_NOSMT; | ||
2293 | |||
2294 | return 0; | ||
2295 | } | ||
2296 | early_param("mitigations", mitigations_parse_cmdline); | ||