Skip to content

Commit 06c23f5

Browse files
author
Russell King
committed
ARM: spectre-v2: harden branch predictor on context switches
Harden the branch predictor against Spectre v2 attacks on context switches for ARMv7 and later CPUs. We do this by: Cortex A9, A12, A17, A73, A75: invalidating the BTB. Cortex A15, Brahma B15: invalidating the instruction cache. Cortex A57 and Cortex A72 are not addressed in this patch. Cortex R7 and Cortex R8 are also not addressed as we do not enforce memory protection on these cores. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Boot-tested-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Tony Lindgren <tony@atomide.com> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent c58d237 commit 06c23f5

File tree

3 files changed

+115
-35
lines changed

3 files changed

+115
-35
lines changed

arch/arm/mm/Kconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,25 @@ config CPU_BPREDICT_DISABLE
830830
config CPU_SPECTRE
831831
bool
832832

833+
config HARDEN_BRANCH_PREDICTOR
834+
bool "Harden the branch predictor against aliasing attacks" if EXPERT
835+
depends on CPU_SPECTRE
836+
default y
837+
help
838+
Speculation attacks against some high-performance processors rely
839+
on being able to manipulate the branch predictor for a victim
840+
context by executing aliasing branches in the attacker context.
841+
Such attacks can be partially mitigated against by clearing
842+
internal branch predictor state and limiting the prediction
843+
logic in some situations.
844+
845+
This config option will take CPU-specific actions to harden
846+
the branch predictor against aliasing attacks and may rely on
847+
specific instruction sequences or control bits being set by
848+
the system firmware.
849+
850+
If unsure, say Y.
851+
833852
config TLS_REG_EMUL
834853
bool
835854
select NEED_KUSER_HELPERS

arch/arm/mm/proc-v7-2level.S

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,6 @@
4141
* even on Cortex-A8 revisions not affected by 430973.
4242
* If IBE is not set, the flush BTAC/BTB won't do anything.
4343
*/
44-
ENTRY(cpu_ca8_switch_mm)
45-
#ifdef CONFIG_MMU
46-
mov r2, #0
47-
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
48-
#endif
4944
ENTRY(cpu_v7_switch_mm)
5045
#ifdef CONFIG_MMU
5146
mmid r1, r1 @ get mm->context.id
@@ -66,7 +61,6 @@ ENTRY(cpu_v7_switch_mm)
6661
#endif
6762
bx lr
6863
ENDPROC(cpu_v7_switch_mm)
69-
ENDPROC(cpu_ca8_switch_mm)
7064

7165
/*
7266
* cpu_v7_set_pte_ext(ptep, pte)

arch/arm/mm/proc-v7.S

Lines changed: 96 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ ENTRY(cpu_v7_dcache_clean_area)
9393
ret lr
9494
ENDPROC(cpu_v7_dcache_clean_area)
9595

96+
ENTRY(cpu_v7_iciallu_switch_mm)
97+
mov r3, #0
98+
mcr p15, 0, r3, c7, c5, 0 @ ICIALLU
99+
b cpu_v7_switch_mm
100+
ENDPROC(cpu_v7_iciallu_switch_mm)
101+
ENTRY(cpu_v7_bpiall_switch_mm)
102+
mov r3, #0
103+
mcr p15, 0, r3, c7, c5, 6 @ flush BTAC/BTB
104+
b cpu_v7_switch_mm
105+
ENDPROC(cpu_v7_bpiall_switch_mm)
106+
96107
string cpu_v7_name, "ARMv7 Processor"
97108
.align
98109

@@ -158,31 +169,6 @@ ENTRY(cpu_v7_do_resume)
158169
ENDPROC(cpu_v7_do_resume)
159170
#endif
160171

161-
/*
162-
* Cortex-A8
163-
*/
164-
globl_equ cpu_ca8_proc_init, cpu_v7_proc_init
165-
globl_equ cpu_ca8_proc_fin, cpu_v7_proc_fin
166-
globl_equ cpu_ca8_reset, cpu_v7_reset
167-
globl_equ cpu_ca8_do_idle, cpu_v7_do_idle
168-
globl_equ cpu_ca8_dcache_clean_area, cpu_v7_dcache_clean_area
169-
globl_equ cpu_ca8_set_pte_ext, cpu_v7_set_pte_ext
170-
globl_equ cpu_ca8_suspend_size, cpu_v7_suspend_size
171-
#ifdef CONFIG_ARM_CPU_SUSPEND
172-
globl_equ cpu_ca8_do_suspend, cpu_v7_do_suspend
173-
globl_equ cpu_ca8_do_resume, cpu_v7_do_resume
174-
#endif
175-
176-
/*
177-
* Cortex-A9 processor functions
178-
*/
179-
globl_equ cpu_ca9mp_proc_init, cpu_v7_proc_init
180-
globl_equ cpu_ca9mp_proc_fin, cpu_v7_proc_fin
181-
globl_equ cpu_ca9mp_reset, cpu_v7_reset
182-
globl_equ cpu_ca9mp_do_idle, cpu_v7_do_idle
183-
globl_equ cpu_ca9mp_dcache_clean_area, cpu_v7_dcache_clean_area
184-
globl_equ cpu_ca9mp_switch_mm, cpu_v7_switch_mm
185-
globl_equ cpu_ca9mp_set_pte_ext, cpu_v7_set_pte_ext
186172
.globl cpu_ca9mp_suspend_size
187173
.equ cpu_ca9mp_suspend_size, cpu_v7_suspend_size + 4 * 2
188174
#ifdef CONFIG_ARM_CPU_SUSPEND
@@ -548,10 +534,75 @@ __v7_setup_stack:
548534

549535
@ define struct processor (see <asm/proc-fns.h> and proc-macros.S)
550536
define_processor_functions v7, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
537+
538+
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
539+
@ generic v7 bpiall on context switch
540+
globl_equ cpu_v7_bpiall_proc_init, cpu_v7_proc_init
541+
globl_equ cpu_v7_bpiall_proc_fin, cpu_v7_proc_fin
542+
globl_equ cpu_v7_bpiall_reset, cpu_v7_reset
543+
globl_equ cpu_v7_bpiall_do_idle, cpu_v7_do_idle
544+
globl_equ cpu_v7_bpiall_dcache_clean_area, cpu_v7_dcache_clean_area
545+
globl_equ cpu_v7_bpiall_set_pte_ext, cpu_v7_set_pte_ext
546+
globl_equ cpu_v7_bpiall_suspend_size, cpu_v7_suspend_size
547+
#ifdef CONFIG_ARM_CPU_SUSPEND
548+
globl_equ cpu_v7_bpiall_do_suspend, cpu_v7_do_suspend
549+
globl_equ cpu_v7_bpiall_do_resume, cpu_v7_do_resume
550+
#endif
551+
define_processor_functions v7_bpiall, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
552+
553+
#define HARDENED_BPIALL_PROCESSOR_FUNCTIONS v7_bpiall_processor_functions
554+
#else
555+
#define HARDENED_BPIALL_PROCESSOR_FUNCTIONS v7_processor_functions
556+
#endif
557+
551558
#ifndef CONFIG_ARM_LPAE
559+
@ Cortex-A8 - always needs bpiall switch_mm implementation
560+
globl_equ cpu_ca8_proc_init, cpu_v7_proc_init
561+
globl_equ cpu_ca8_proc_fin, cpu_v7_proc_fin
562+
globl_equ cpu_ca8_reset, cpu_v7_reset
563+
globl_equ cpu_ca8_do_idle, cpu_v7_do_idle
564+
globl_equ cpu_ca8_dcache_clean_area, cpu_v7_dcache_clean_area
565+
globl_equ cpu_ca8_set_pte_ext, cpu_v7_set_pte_ext
566+
globl_equ cpu_ca8_switch_mm, cpu_v7_bpiall_switch_mm
567+
globl_equ cpu_ca8_suspend_size, cpu_v7_suspend_size
568+
#ifdef CONFIG_ARM_CPU_SUSPEND
569+
globl_equ cpu_ca8_do_suspend, cpu_v7_do_suspend
570+
globl_equ cpu_ca8_do_resume, cpu_v7_do_resume
571+
#endif
552572
define_processor_functions ca8, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
573+
574+
@ Cortex-A9 - needs more registers preserved across suspend/resume
575+
@ and bpiall switch_mm for hardening
576+
globl_equ cpu_ca9mp_proc_init, cpu_v7_proc_init
577+
globl_equ cpu_ca9mp_proc_fin, cpu_v7_proc_fin
578+
globl_equ cpu_ca9mp_reset, cpu_v7_reset
579+
globl_equ cpu_ca9mp_do_idle, cpu_v7_do_idle
580+
globl_equ cpu_ca9mp_dcache_clean_area, cpu_v7_dcache_clean_area
581+
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
582+
globl_equ cpu_ca9mp_switch_mm, cpu_v7_bpiall_switch_mm
583+
#else
584+
globl_equ cpu_ca9mp_switch_mm, cpu_v7_switch_mm
585+
#endif
586+
globl_equ cpu_ca9mp_set_pte_ext, cpu_v7_set_pte_ext
553587
define_processor_functions ca9mp, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
554588
#endif
589+
590+
@ Cortex-A15 - needs iciallu switch_mm for hardening
591+
globl_equ cpu_ca15_proc_init, cpu_v7_proc_init
592+
globl_equ cpu_ca15_proc_fin, cpu_v7_proc_fin
593+
globl_equ cpu_ca15_reset, cpu_v7_reset
594+
globl_equ cpu_ca15_do_idle, cpu_v7_do_idle
595+
globl_equ cpu_ca15_dcache_clean_area, cpu_v7_dcache_clean_area
596+
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
597+
globl_equ cpu_ca15_switch_mm, cpu_v7_iciallu_switch_mm
598+
#else
599+
globl_equ cpu_ca15_switch_mm, cpu_v7_switch_mm
600+
#endif
601+
globl_equ cpu_ca15_set_pte_ext, cpu_v7_set_pte_ext
602+
globl_equ cpu_ca15_suspend_size, cpu_v7_suspend_size
603+
globl_equ cpu_ca15_do_suspend, cpu_v7_do_suspend
604+
globl_equ cpu_ca15_do_resume, cpu_v7_do_resume
605+
define_processor_functions ca15, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
555606
#ifdef CONFIG_CPU_PJ4B
556607
define_processor_functions pj4b, dabort=v7_early_abort, pabort=v7_pabort, suspend=1
557608
#endif
@@ -658,7 +709,7 @@ __v7_ca7mp_proc_info:
658709
__v7_ca12mp_proc_info:
659710
.long 0x410fc0d0
660711
.long 0xff0ffff0
661-
__v7_proc __v7_ca12mp_proc_info, __v7_ca12mp_setup
712+
__v7_proc __v7_ca12mp_proc_info, __v7_ca12mp_setup, proc_fns = HARDENED_BPIALL_PROCESSOR_FUNCTIONS
662713
.size __v7_ca12mp_proc_info, . - __v7_ca12mp_proc_info
663714

664715
/*
@@ -668,7 +719,7 @@ __v7_ca12mp_proc_info:
668719
__v7_ca15mp_proc_info:
669720
.long 0x410fc0f0
670721
.long 0xff0ffff0
671-
__v7_proc __v7_ca15mp_proc_info, __v7_ca15mp_setup
722+
__v7_proc __v7_ca15mp_proc_info, __v7_ca15mp_setup, proc_fns = ca15_processor_functions
672723
.size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info
673724

674725
/*
@@ -678,7 +729,7 @@ __v7_ca15mp_proc_info:
678729
__v7_b15mp_proc_info:
679730
.long 0x420f00f0
680731
.long 0xff0ffff0
681-
__v7_proc __v7_b15mp_proc_info, __v7_b15mp_setup, cache_fns = b15_cache_fns
732+
__v7_proc __v7_b15mp_proc_info, __v7_b15mp_setup, proc_fns = ca15_processor_functions, cache_fns = b15_cache_fns
682733
.size __v7_b15mp_proc_info, . - __v7_b15mp_proc_info
683734

684735
/*
@@ -688,9 +739,25 @@ __v7_b15mp_proc_info:
688739
__v7_ca17mp_proc_info:
689740
.long 0x410fc0e0
690741
.long 0xff0ffff0
691-
__v7_proc __v7_ca17mp_proc_info, __v7_ca17mp_setup
742+
__v7_proc __v7_ca17mp_proc_info, __v7_ca17mp_setup, proc_fns = HARDENED_BPIALL_PROCESSOR_FUNCTIONS
692743
.size __v7_ca17mp_proc_info, . - __v7_ca17mp_proc_info
693744

745+
/* ARM Ltd. Cortex A73 processor */
746+
.type __v7_ca73_proc_info, #object
747+
__v7_ca73_proc_info:
748+
.long 0x410fd090
749+
.long 0xff0ffff0
750+
__v7_proc __v7_ca73_proc_info, __v7_setup, proc_fns = HARDENED_BPIALL_PROCESSOR_FUNCTIONS
751+
.size __v7_ca73_proc_info, . - __v7_ca73_proc_info
752+
753+
/* ARM Ltd. Cortex A75 processor */
754+
.type __v7_ca75_proc_info, #object
755+
__v7_ca75_proc_info:
756+
.long 0x410fd0a0
757+
.long 0xff0ffff0
758+
__v7_proc __v7_ca75_proc_info, __v7_setup, proc_fns = HARDENED_BPIALL_PROCESSOR_FUNCTIONS
759+
.size __v7_ca75_proc_info, . - __v7_ca75_proc_info
760+
694761
/*
695762
* Qualcomm Inc. Krait processors.
696763
*/

0 commit comments

Comments
 (0)