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); | ||
