| From foo@baz Wed Nov 21 19:20:53 CET 2018 |
| From: David Long <dave.long@linaro.org> |
| Date: Wed, 7 Nov 2018 11:43:45 -0500 |
| Subject: ARM: spectre-v2: add Cortex A8 and A15 validation of the IBE bit |
| To: stable@vger.kernel.org, Russell King - ARM Linux <linux@armlinux.org.uk>, Florian Fainelli <f.fainelli@gmail.com>, Tony Lindgren <tony@atomide.com>, Marc Zyngier <marc.zyngier@arm.com>, Mark Rutland <mark.rutland@arm.com> |
| Cc: Greg KH <gregkh@linuxfoundation.org>, Mark Brown <broonie@kernel.org> |
| Message-ID: <20181107164402.9380-8-dave.long@linaro.org> |
| |
| From: Russell King <rmk+kernel@armlinux.org.uk> |
| |
| Commit e388b80288aade31135aca23d32eee93dd106795 upstream. |
| |
| When the branch predictor hardening is enabled, firmware must have set |
| the IBE bit in the auxiliary control register. If this bit has not |
| been set, the Spectre workarounds will not be functional. |
| |
| Add validation that this bit is set, and print a warning at alert level |
| if this is not the case. |
| |
| Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> |
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> |
| Boot-tested-by: Tony Lindgren <tony@atomide.com> |
| Reviewed-by: Tony Lindgren <tony@atomide.com> |
| Signed-off-by: David A. Long <dave.long@linaro.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm/mm/Makefile | 2 +- |
| arch/arm/mm/proc-v7-bugs.c | 36 ++++++++++++++++++++++++++++++++++++ |
| arch/arm/mm/proc-v7.S | 4 ++-- |
| 3 files changed, 39 insertions(+), 3 deletions(-) |
| create mode 100644 arch/arm/mm/proc-v7-bugs.c |
| |
| --- a/arch/arm/mm/Makefile |
| +++ b/arch/arm/mm/Makefile |
| @@ -94,7 +94,7 @@ obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk. |
| obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o |
| obj-$(CONFIG_CPU_V6) += proc-v6.o |
| obj-$(CONFIG_CPU_V6K) += proc-v6.o |
| -obj-$(CONFIG_CPU_V7) += proc-v7.o |
| +obj-$(CONFIG_CPU_V7) += proc-v7.o proc-v7-bugs.o |
| obj-$(CONFIG_CPU_V7M) += proc-v7m.o |
| |
| AFLAGS_proc-v6.o :=-Wa,-march=armv6 |
| --- /dev/null |
| +++ b/arch/arm/mm/proc-v7-bugs.c |
| @@ -0,0 +1,36 @@ |
| +// SPDX-License-Identifier: GPL-2.0 |
| +#include <linux/kernel.h> |
| +#include <linux/smp.h> |
| + |
| +static __maybe_unused void cpu_v7_check_auxcr_set(bool *warned, |
| + u32 mask, const char *msg) |
| +{ |
| + u32 aux_cr; |
| + |
| + asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (aux_cr)); |
| + |
| + if ((aux_cr & mask) != mask) { |
| + if (!*warned) |
| + pr_err("CPU%u: %s", smp_processor_id(), msg); |
| + *warned = true; |
| + } |
| +} |
| + |
| +static DEFINE_PER_CPU(bool, spectre_warned); |
| + |
| +static void check_spectre_auxcr(bool *warned, u32 bit) |
| +{ |
| + if (IS_ENABLED(CONFIG_HARDEN_BRANCH_PREDICTOR) && |
| + cpu_v7_check_auxcr_set(warned, bit, |
| + "Spectre v2: firmware did not set auxiliary control register IBE bit, system vulnerable\n"); |
| +} |
| + |
| +void cpu_v7_ca8_ibe(void) |
| +{ |
| + check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6)); |
| +} |
| + |
| +void cpu_v7_ca15_ibe(void) |
| +{ |
| + check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)); |
| +} |
| --- a/arch/arm/mm/proc-v7.S |
| +++ b/arch/arm/mm/proc-v7.S |
| @@ -564,7 +564,7 @@ __v7_setup_stack: |
| globl_equ cpu_ca8_do_suspend, cpu_v7_do_suspend |
| globl_equ cpu_ca8_do_resume, cpu_v7_do_resume |
| #endif |
| - define_processor_functions ca8, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 |
| + define_processor_functions ca8, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_ca8_ibe |
| |
| @ Cortex-A9 - needs more registers preserved across suspend/resume |
| @ and bpiall switch_mm for hardening |
| @@ -597,7 +597,7 @@ __v7_setup_stack: |
| globl_equ cpu_ca15_suspend_size, cpu_v7_suspend_size |
| globl_equ cpu_ca15_do_suspend, cpu_v7_do_suspend |
| globl_equ cpu_ca15_do_resume, cpu_v7_do_resume |
| - define_processor_functions ca15, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 |
| + define_processor_functions ca15, dabort=v7_early_abort, pabort=v7_pabort, suspend=1, bugs=cpu_v7_ca15_ibe |
| #ifdef CONFIG_CPU_PJ4B |
| define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1 |
| #endif |