diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h index 98b37340376bcc3f6724ea0b6dd79f24f84601c3..4ca02f1927f70d327ddb6aed33d90e87095dbd2e 100644 --- a/arch/arm/include/asm/system_misc.h +++ b/arch/arm/include/asm/system_misc.h @@ -36,6 +36,7 @@ static inline void harden_branch_predictor(void) #define UDBG_BUS (1 << 4) extern unsigned int user_debug; +extern int nospectre_v2; #endif /* !__ASSEMBLY__ */ diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c index 8bc7a2d6d6c7f96cda00741fe76faa148cee7b51..996888c8505b061e2011fc08b3d89400efcd8b02 100644 --- a/arch/arm/mm/proc-v7-bugs.c +++ b/arch/arm/mm/proc-v7-bugs.c @@ -35,6 +35,19 @@ static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) } #endif +/* + * 32-bit ARM spectre hardening, enabled by default, can be disabled via boot + * cmdline param 'nospectre_v2' to avoid performance regression. + */ +int nospectre_v2 __read_mostly; + +static int __init nospectre_v2_setup(char *str) +{ + nospectre_v2 = 1; + return 0; +} +early_param("nospectre_v2", nospectre_v2_setup); + #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn); @@ -68,6 +81,11 @@ static unsigned int spectre_v2_install_workaround(unsigned int method) const char *spectre_v2_method = NULL; int cpu = smp_processor_id(); + if (nospectre_v2) { + pr_info_once("Spectre v2: hardening is disabled\n"); + return; + } + if (per_cpu(harden_branch_predictor_fn, cpu)) return SPECTRE_MITIGATED; diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 193c7aeb670391ff27b764d9667baa1ffa1e4992..d1bbbb5dae7d37a072331eaafb52fa547cd403fb 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -113,14 +113,23 @@ ENTRY(cpu_v7_hvc_switch_mm) b cpu_v7_switch_mm ENDPROC(cpu_v7_hvc_switch_mm) #endif + ENTRY(cpu_v7_iciallu_switch_mm) + ldr_l r3, nospectre_v2 + cmp r3, #1 + beq 1f mov r3, #0 mcr p15, 0, r3, c7, c5, 0 @ ICIALLU +1: b cpu_v7_switch_mm ENDPROC(cpu_v7_iciallu_switch_mm) ENTRY(cpu_v7_bpiall_switch_mm) + ldr_l r3, nospectre_v2 + cmp r3, #1 + beq 1f mov r3, #0 mcr p15, 0, r3, c7, c5, 6 @ flush BTAC/BTB +1: b cpu_v7_switch_mm ENDPROC(cpu_v7_bpiall_switch_mm)