|
Matthias Brugger |
214f30 |
From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
|
|
Matthias Brugger |
214f30 |
Date: Thu, 10 Feb 2022 16:05:45 +0000
|
|
Matthias Brugger |
214f30 |
Subject: ARM: Spectre-BHB workaround
|
|
Matthias Brugger |
214f30 |
Git-commit: b9baf5c8c5c356757f4f9d8180b5e9d234065bc3
|
|
Matthias Brugger |
214f30 |
Patch-mainline: v5.17 or v5.17-rc8 (next release)
|
|
Matthias Brugger |
214f30 |
References: bsc#1085308 CVE-2022-23960
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
Workaround the Spectre BHB issues for Cortex-A15, Cortex-A57,
|
|
Matthias Brugger |
214f30 |
Cortex-A72, Cortex-A73 and Cortex-A75. We also include Brahma B15 as
|
|
Matthias Brugger |
214f30 |
well to be safe, which is affected by Spectre V2 in the same ways as
|
|
Matthias Brugger |
214f30 |
Cortex-A15.
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
|
|
Matthias Brugger |
214f30 |
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
|
Matthias Brugger |
214f30 |
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
|
|
Matthias Brugger |
214f30 |
---
|
|
Matthias Brugger |
214f30 |
arch/arm/include/asm/assembler.h | 10 ++++
|
|
Matthias Brugger |
214f30 |
arch/arm/include/asm/spectre.h | 4 ++
|
|
Matthias Brugger |
214f30 |
arch/arm/include/asm/vmlinux.lds.h | 18 +++++--
|
|
Matthias Brugger |
214f30 |
arch/arm/kernel/entry-armv.S | 79 +++++++++++++++++++++++++++---
|
|
Matthias Brugger |
214f30 |
arch/arm/kernel/entry-common.S | 24 +++++++++
|
|
Matthias Brugger |
214f30 |
arch/arm/kernel/spectre.c | 4 ++
|
|
Matthias Brugger |
214f30 |
arch/arm/kernel/traps.c | 38 ++++++++++++++
|
|
Matthias Brugger |
214f30 |
arch/arm/mm/Kconfig | 10 ++++
|
|
Matthias Brugger |
214f30 |
arch/arm/mm/proc-v7-bugs.c | 76 ++++++++++++++++++++++++++++
|
|
Matthias Brugger |
214f30 |
9 files changed, 254 insertions(+), 9 deletions(-)
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
|
|
Matthias Brugger |
214f30 |
index 7d23d4bb2168..49ea603fc8e3 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/include/asm/assembler.h
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/include/asm/assembler.h
|
|
Matthias Brugger |
214f30 |
@@ -107,6 +107,16 @@
|
|
Matthias Brugger |
214f30 |
.endm
|
|
Matthias Brugger |
214f30 |
#endif
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+#if __LINUX_ARM_ARCH__ < 7
|
|
Matthias Brugger |
214f30 |
+ .macro dsb, args
|
|
Matthias Brugger |
214f30 |
+ mcr p15, 0, r0, c7, c10, 4
|
|
Matthias Brugger |
214f30 |
+ .endm
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ .macro isb, args
|
|
Matthias Brugger |
214f30 |
+ mcr p15, 0, r0, c7, r5, 4
|
|
Matthias Brugger |
214f30 |
+ .endm
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
.macro asm_trace_hardirqs_off, save=1
|
|
Matthias Brugger |
214f30 |
#if defined(CONFIG_TRACE_IRQFLAGS)
|
|
Matthias Brugger |
214f30 |
.if \save
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/include/asm/spectre.h b/arch/arm/include/asm/spectre.h
|
|
Matthias Brugger |
214f30 |
index 8a9019e08dba..d1fa5607d3aa 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/include/asm/spectre.h
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/include/asm/spectre.h
|
|
Matthias Brugger |
214f30 |
@@ -14,6 +14,7 @@ enum {
|
|
Matthias Brugger |
214f30 |
__SPECTRE_V2_METHOD_ICIALLU,
|
|
Matthias Brugger |
214f30 |
__SPECTRE_V2_METHOD_SMC,
|
|
Matthias Brugger |
214f30 |
__SPECTRE_V2_METHOD_HVC,
|
|
Matthias Brugger |
214f30 |
+ __SPECTRE_V2_METHOD_LOOP8,
|
|
Matthias Brugger |
214f30 |
};
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
enum {
|
|
Matthias Brugger |
214f30 |
@@ -21,8 +22,11 @@ enum {
|
|
Matthias Brugger |
214f30 |
SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU),
|
|
Matthias Brugger |
214f30 |
SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC),
|
|
Matthias Brugger |
214f30 |
SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC),
|
|
Matthias Brugger |
214f30 |
+ SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
|
|
Matthias Brugger |
214f30 |
};
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
void spectre_v2_update_state(unsigned int state, unsigned int methods);
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+int spectre_bhb_update_vectors(unsigned int method);
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
#endif
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/include/asm/vmlinux.lds.h b/arch/arm/include/asm/vmlinux.lds.h
|
|
Matthias Brugger |
214f30 |
index e02710d17cf9..0ef21bfae9f6 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/include/asm/vmlinux.lds.h
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/include/asm/vmlinux.lds.h
|
|
Matthias Brugger |
214f30 |
@@ -116,11 +116,23 @@
|
|
Matthias Brugger |
214f30 |
*/
|
|
Matthias Brugger |
214f30 |
#define ARM_VECTORS \
|
|
Matthias Brugger |
214f30 |
__vectors_lma = .; \
|
|
Matthias Brugger |
214f30 |
- .vectors 0xffff0000 : AT(__vectors_start) { \
|
|
Matthias Brugger |
214f30 |
- *(.vectors) \
|
|
Matthias Brugger |
214f30 |
+ OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \
|
|
Matthias Brugger |
214f30 |
+ .vectors { \
|
|
Matthias Brugger |
214f30 |
+ *(.vectors) \
|
|
Matthias Brugger |
214f30 |
+ } \
|
|
Matthias Brugger |
214f30 |
+ .vectors.bhb.loop8 { \
|
|
Matthias Brugger |
214f30 |
+ *(.vectors.bhb.loop8) \
|
|
Matthias Brugger |
214f30 |
+ } \
|
|
Matthias Brugger |
214f30 |
+ .vectors.bhb.bpiall { \
|
|
Matthias Brugger |
214f30 |
+ *(.vectors.bhb.bpiall) \
|
|
Matthias Brugger |
214f30 |
+ } \
|
|
Matthias Brugger |
214f30 |
} \
|
|
Matthias Brugger |
214f30 |
ARM_LMA(__vectors, .vectors); \
|
|
Matthias Brugger |
214f30 |
- . = __vectors_lma + SIZEOF(.vectors); \
|
|
Matthias Brugger |
214f30 |
+ ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8); \
|
|
Matthias Brugger |
214f30 |
+ ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall); \
|
|
Matthias Brugger |
214f30 |
+ . = __vectors_lma + SIZEOF(.vectors) + \
|
|
Matthias Brugger |
214f30 |
+ SIZEOF(.vectors.bhb.loop8) + \
|
|
Matthias Brugger |
214f30 |
+ SIZEOF(.vectors.bhb.bpiall); \
|
|
Matthias Brugger |
214f30 |
\
|
|
Matthias Brugger |
214f30 |
__stubs_lma = .; \
|
|
Matthias Brugger |
214f30 |
.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
|
|
Matthias Brugger |
214f30 |
index 5cd057859fe9..676703cbfe4b 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/kernel/entry-armv.S
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/kernel/entry-armv.S
|
|
Matthias Brugger |
214f30 |
@@ -1002,12 +1002,11 @@ vector_\name:
|
|
Matthias Brugger |
214f30 |
sub lr, lr, #\correction
|
|
Matthias Brugger |
214f30 |
.endif
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
- @
|
|
Matthias Brugger |
214f30 |
- @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
|
|
Matthias Brugger |
214f30 |
- @ (parent CPSR)
|
|
Matthias Brugger |
214f30 |
- @
|
|
Matthias Brugger |
214f30 |
+ @ Save r0, lr_<exception> (parent PC)
|
|
Matthias Brugger |
214f30 |
stmia sp, {r0, lr} @ save r0, lr
|
|
Matthias Brugger |
214f30 |
- mrs lr, spsr
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ @ Save spsr_<exception> (parent CPSR)
|
|
Matthias Brugger |
214f30 |
+2: mrs lr, spsr
|
|
Matthias Brugger |
214f30 |
str lr, [sp, #8] @ save spsr
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
@
|
|
Matthias Brugger |
214f30 |
@@ -1028,6 +1027,44 @@ vector_\name:
|
|
Matthias Brugger |
214f30 |
movs pc, lr @ branch to handler in SVC mode
|
|
Matthias Brugger |
214f30 |
ENDPROC(vector_\name)
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+ .subsection 1
|
|
Matthias Brugger |
214f30 |
+ .align 5
|
|
Matthias Brugger |
214f30 |
+vector_bhb_loop8_\name:
|
|
Matthias Brugger |
214f30 |
+ .if \correction
|
|
Matthias Brugger |
214f30 |
+ sub lr, lr, #\correction
|
|
Matthias Brugger |
214f30 |
+ .endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ @ Save r0, lr_<exception> (parent PC)
|
|
Matthias Brugger |
214f30 |
+ stmia sp, {r0, lr}
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ @ bhb workaround
|
|
Matthias Brugger |
214f30 |
+ mov r0, #8
|
|
Matthias Brugger |
214f30 |
+1: b . + 4
|
|
Matthias Brugger |
214f30 |
+ subs r0, r0, #1
|
|
Matthias Brugger |
214f30 |
+ bne 1b
|
|
Matthias Brugger |
214f30 |
+ dsb
|
|
Matthias Brugger |
214f30 |
+ isb
|
|
Matthias Brugger |
214f30 |
+ b 2b
|
|
Matthias Brugger |
214f30 |
+ENDPROC(vector_bhb_loop8_\name)
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+vector_bhb_bpiall_\name:
|
|
Matthias Brugger |
214f30 |
+ .if \correction
|
|
Matthias Brugger |
214f30 |
+ sub lr, lr, #\correction
|
|
Matthias Brugger |
214f30 |
+ .endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ @ Save r0, lr_<exception> (parent PC)
|
|
Matthias Brugger |
214f30 |
+ stmia sp, {r0, lr}
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ @ bhb workaround
|
|
Matthias Brugger |
214f30 |
+ mcr p15, 0, r0, c7, c5, 6 @ BPIALL
|
|
Matthias Brugger |
214f30 |
+ @ isb not needed due to "movs pc, lr" in the vector stub
|
|
Matthias Brugger |
214f30 |
+ @ which gives a "context synchronisation".
|
|
Matthias Brugger |
214f30 |
+ b 2b
|
|
Matthias Brugger |
214f30 |
+ENDPROC(vector_bhb_bpiall_\name)
|
|
Matthias Brugger |
214f30 |
+ .previous
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
.align 2
|
|
Matthias Brugger |
214f30 |
@ handler addresses follow this label
|
|
Matthias Brugger |
214f30 |
1:
|
|
Matthias Brugger |
214f30 |
@@ -1036,6 +1073,10 @@ ENDPROC(vector_\name)
|
|
Matthias Brugger |
214f30 |
.section .stubs, "ax", %progbits
|
|
Matthias Brugger |
214f30 |
@ This must be the first word
|
|
Matthias Brugger |
214f30 |
.word vector_swi
|
|
Matthias Brugger |
214f30 |
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+ .word vector_bhb_loop8_swi
|
|
Matthias Brugger |
214f30 |
+ .word vector_bhb_bpiall_swi
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
vector_rst:
|
|
Matthias Brugger |
214f30 |
ARM( swi SYS_ERROR0 )
|
|
Matthias Brugger |
214f30 |
@@ -1150,8 +1191,10 @@ vector_addrexcptn:
|
|
Matthias Brugger |
214f30 |
* FIQ "NMI" handler
|
|
Matthias Brugger |
214f30 |
*-----------------------------------------------------------------------------
|
|
Matthias Brugger |
214f30 |
* Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86
|
|
Matthias Brugger |
214f30 |
- * systems.
|
|
Matthias Brugger |
214f30 |
+ * systems. This must be the last vector stub, so lets place it in its own
|
|
Matthias Brugger |
214f30 |
+ * subsection.
|
|
Matthias Brugger |
214f30 |
*/
|
|
Matthias Brugger |
214f30 |
+ .subsection 2
|
|
Matthias Brugger |
214f30 |
vector_stub fiq, FIQ_MODE, 4
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
.long __fiq_usr @ 0 (USR_26 / USR_32)
|
|
Matthias Brugger |
214f30 |
@@ -1184,6 +1227,30 @@ vector_addrexcptn:
|
|
Matthias Brugger |
214f30 |
W(b) vector_irq
|
|
Matthias Brugger |
214f30 |
W(b) vector_fiq
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+ .section .vectors.bhb.loop8, "ax", %progbits
|
|
Matthias Brugger |
214f30 |
+.L__vectors_bhb_loop8_start:
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_rst
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_loop8_und
|
|
Matthias Brugger |
214f30 |
+ W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_loop8_pabt
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_loop8_dabt
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_addrexcptn
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_loop8_irq
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_loop8_fiq
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ .section .vectors.bhb.bpiall, "ax", %progbits
|
|
Matthias Brugger |
214f30 |
+.L__vectors_bhb_bpiall_start:
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_rst
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_bpiall_und
|
|
Matthias Brugger |
214f30 |
+ W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_bpiall_pabt
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_bpiall_dabt
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_addrexcptn
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_bpiall_irq
|
|
Matthias Brugger |
214f30 |
+ W(b) vector_bhb_bpiall_fiq
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
.data
|
|
Matthias Brugger |
214f30 |
.align 2
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
|
|
Matthias Brugger |
214f30 |
index ac86c34682bb..dbc1913ee30b 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/kernel/entry-common.S
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/kernel/entry-common.S
|
|
Matthias Brugger |
214f30 |
@@ -153,6 +153,29 @@ ENDPROC(ret_from_fork)
|
|
Matthias Brugger |
214f30 |
*-----------------------------------------------------------------------------
|
|
Matthias Brugger |
214f30 |
*/
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+ .align 5
|
|
Matthias Brugger |
214f30 |
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+ENTRY(vector_bhb_loop8_swi)
|
|
Matthias Brugger |
214f30 |
+ sub sp, sp, #PT_REGS_SIZE
|
|
Matthias Brugger |
214f30 |
+ stmia sp, {r0 - r12}
|
|
Matthias Brugger |
214f30 |
+ mov r8, #8
|
|
Matthias Brugger |
214f30 |
+1: b 2f
|
|
Matthias Brugger |
214f30 |
+2: subs r8, r8, #1
|
|
Matthias Brugger |
214f30 |
+ bne 1b
|
|
Matthias Brugger |
214f30 |
+ dsb
|
|
Matthias Brugger |
214f30 |
+ isb
|
|
Matthias Brugger |
214f30 |
+ b 3f
|
|
Matthias Brugger |
214f30 |
+ENDPROC(vector_bhb_loop8_swi)
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ .align 5
|
|
Matthias Brugger |
214f30 |
+ENTRY(vector_bhb_bpiall_swi)
|
|
Matthias Brugger |
214f30 |
+ sub sp, sp, #PT_REGS_SIZE
|
|
Matthias Brugger |
214f30 |
+ stmia sp, {r0 - r12}
|
|
Matthias Brugger |
214f30 |
+ mcr p15, 0, r8, c7, c5, 6 @ BPIALL
|
|
Matthias Brugger |
214f30 |
+ isb
|
|
Matthias Brugger |
214f30 |
+ b 3f
|
|
Matthias Brugger |
214f30 |
+ENDPROC(vector_bhb_bpiall_swi)
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
.align 5
|
|
Matthias Brugger |
214f30 |
ENTRY(vector_swi)
|
|
Matthias Brugger |
214f30 |
#ifdef CONFIG_CPU_V7M
|
|
Matthias Brugger |
214f30 |
@@ -160,6 +183,7 @@ ENTRY(vector_swi)
|
|
Matthias Brugger |
214f30 |
#else
|
|
Matthias Brugger |
214f30 |
sub sp, sp, #PT_REGS_SIZE
|
|
Matthias Brugger |
214f30 |
stmia sp, {r0 - r12} @ Calling r0 - r12
|
|
Matthias Brugger |
214f30 |
+3:
|
|
Matthias Brugger |
214f30 |
ARM( add r8, sp, #S_PC )
|
|
Matthias Brugger |
214f30 |
ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
|
|
Matthias Brugger |
214f30 |
THUMB( mov r8, sp )
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/kernel/spectre.c b/arch/arm/kernel/spectre.c
|
|
Matthias Brugger |
214f30 |
index 6f6dd1cfd099..ade967f18d06 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/kernel/spectre.c
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/kernel/spectre.c
|
|
Matthias Brugger |
214f30 |
@@ -45,6 +45,10 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
|
|
Matthias Brugger |
214f30 |
method = "Firmware call";
|
|
Matthias Brugger |
214f30 |
break;
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+ case SPECTRE_V2_METHOD_LOOP8:
|
|
Matthias Brugger |
214f30 |
+ method = "History overwrite";
|
|
Matthias Brugger |
214f30 |
+ break;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
default:
|
|
Matthias Brugger |
214f30 |
method = "Multiple mitigations";
|
|
Matthias Brugger |
214f30 |
break;
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
|
|
Matthias Brugger |
214f30 |
index abc82dfeab51..90c887aa67a4 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/kernel/traps.c
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/kernel/traps.c
|
|
Matthias Brugger |
214f30 |
@@ -30,6 +30,7 @@
|
|
Matthias Brugger |
214f30 |
#include <linux/atomic.h>
|
|
Matthias Brugger |
214f30 |
#include <asm/cacheflush.h>
|
|
Matthias Brugger |
214f30 |
#include <asm/exception.h>
|
|
Matthias Brugger |
214f30 |
+#include <asm/spectre.h>
|
|
Matthias Brugger |
214f30 |
#include <asm/unistd.h>
|
|
Matthias Brugger |
214f30 |
#include <asm/traps.h>
|
|
Matthias Brugger |
214f30 |
#include <asm/ptrace.h>
|
|
Matthias Brugger |
214f30 |
@@ -801,6 +802,43 @@ static void flush_vectors(void *vma, size_t offset, size_t size)
|
|
Matthias Brugger |
214f30 |
flush_icache_range(start, end);
|
|
Matthias Brugger |
214f30 |
}
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+int spectre_bhb_update_vectors(unsigned int method)
|
|
Matthias Brugger |
214f30 |
+{
|
|
Matthias Brugger |
214f30 |
+ extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[];
|
|
Matthias Brugger |
214f30 |
+ extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[];
|
|
Matthias Brugger |
214f30 |
+ void *vec_start, *vec_end;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ if (system_state >= SYSTEM_RUNNING) {
|
|
Matthias Brugger |
214f30 |
+ pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n",
|
|
Matthias Brugger |
214f30 |
+ smp_processor_id());
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_VULNERABLE;
|
|
Matthias Brugger |
214f30 |
+ }
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ switch (method) {
|
|
Matthias Brugger |
214f30 |
+ case SPECTRE_V2_METHOD_LOOP8:
|
|
Matthias Brugger |
214f30 |
+ vec_start = __vectors_bhb_loop8_start;
|
|
Matthias Brugger |
214f30 |
+ vec_end = __vectors_bhb_loop8_end;
|
|
Matthias Brugger |
214f30 |
+ break;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ case SPECTRE_V2_METHOD_BPIALL:
|
|
Matthias Brugger |
214f30 |
+ vec_start = __vectors_bhb_bpiall_start;
|
|
Matthias Brugger |
214f30 |
+ vec_end = __vectors_bhb_bpiall_end;
|
|
Matthias Brugger |
214f30 |
+ break;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ default:
|
|
Matthias Brugger |
214f30 |
+ pr_err("CPU%u: unknown Spectre BHB state %d\n",
|
|
Matthias Brugger |
214f30 |
+ smp_processor_id(), method);
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_VULNERABLE;
|
|
Matthias Brugger |
214f30 |
+ }
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ copy_from_lma(vectors_page, vec_start, vec_end);
|
|
Matthias Brugger |
214f30 |
+ flush_vectors(vectors_page, 0, vec_end - vec_start);
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_MITIGATED;
|
|
Matthias Brugger |
214f30 |
+}
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
void __init early_trap_init(void *vectors_base)
|
|
Matthias Brugger |
214f30 |
{
|
|
Matthias Brugger |
214f30 |
extern char __stubs_start[], __stubs_end[];
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
|
|
Matthias Brugger |
214f30 |
index 850329ea9bf8..9724c16e9076 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/mm/Kconfig
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/mm/Kconfig
|
|
Matthias Brugger |
214f30 |
@@ -851,6 +851,16 @@ config HARDEN_BRANCH_PREDICTOR
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
If unsure, say Y.
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+config HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+ bool "Harden Spectre style attacks against branch history" if EXPERT
|
|
Matthias Brugger |
214f30 |
+ depends on CPU_SPECTRE
|
|
Matthias Brugger |
214f30 |
+ default y
|
|
Matthias Brugger |
214f30 |
+ help
|
|
Matthias Brugger |
214f30 |
+ Speculation attacks against some high-performance processors can
|
|
Matthias Brugger |
214f30 |
+ make use of branch history to influence future speculation. When
|
|
Matthias Brugger |
214f30 |
+ taking an exception, a sequence of branches overwrites the branch
|
|
Matthias Brugger |
214f30 |
+ history, or branch history is invalidated.
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
config TLS_REG_EMUL
|
|
Matthias Brugger |
214f30 |
bool
|
|
Matthias Brugger |
214f30 |
select NEED_KUSER_HELPERS
|
|
Matthias Brugger |
214f30 |
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
|
|
Matthias Brugger |
214f30 |
index e438e59bb63e..c226feab2457 100644
|
|
Matthias Brugger |
214f30 |
--- a/arch/arm/mm/proc-v7-bugs.c
|
|
Matthias Brugger |
214f30 |
+++ b/arch/arm/mm/proc-v7-bugs.c
|
|
Matthias Brugger |
214f30 |
@@ -177,6 +177,81 @@ static void cpu_v7_spectre_v2_init(void)
|
|
Matthias Brugger |
214f30 |
spectre_v2_update_state(state, method);
|
|
Matthias Brugger |
214f30 |
}
|
|
Matthias Brugger |
214f30 |
|
|
Matthias Brugger |
214f30 |
+#ifdef CONFIG_HARDEN_BRANCH_HISTORY
|
|
Matthias Brugger |
214f30 |
+static int spectre_bhb_method;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+static const char *spectre_bhb_method_name(int method)
|
|
Matthias Brugger |
214f30 |
+{
|
|
Matthias Brugger |
214f30 |
+ switch (method) {
|
|
Matthias Brugger |
214f30 |
+ case SPECTRE_V2_METHOD_LOOP8:
|
|
Matthias Brugger |
214f30 |
+ return "loop";
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ case SPECTRE_V2_METHOD_BPIALL:
|
|
Matthias Brugger |
214f30 |
+ return "BPIALL";
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ default:
|
|
Matthias Brugger |
214f30 |
+ return "unknown";
|
|
Matthias Brugger |
214f30 |
+ }
|
|
Matthias Brugger |
214f30 |
+}
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+static int spectre_bhb_install_workaround(int method)
|
|
Matthias Brugger |
214f30 |
+{
|
|
Matthias Brugger |
214f30 |
+ if (spectre_bhb_method != method) {
|
|
Matthias Brugger |
214f30 |
+ if (spectre_bhb_method) {
|
|
Matthias Brugger |
214f30 |
+ pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n",
|
|
Matthias Brugger |
214f30 |
+ smp_processor_id());
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_VULNERABLE;
|
|
Matthias Brugger |
214f30 |
+ }
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE)
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_VULNERABLE;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ spectre_bhb_method = method;
|
|
Matthias Brugger |
214f30 |
+ }
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ pr_info("CPU%u: Spectre BHB: using %s workaround\n",
|
|
Matthias Brugger |
214f30 |
+ smp_processor_id(), spectre_bhb_method_name(method));
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_MITIGATED;
|
|
Matthias Brugger |
214f30 |
+}
|
|
Matthias Brugger |
214f30 |
+#else
|
|
Matthias Brugger |
214f30 |
+static int spectre_bhb_install_workaround(int method)
|
|
Matthias Brugger |
214f30 |
+{
|
|
Matthias Brugger |
214f30 |
+ return SPECTRE_VULNERABLE;
|
|
Matthias Brugger |
214f30 |
+}
|
|
Matthias Brugger |
214f30 |
+#endif
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+static void cpu_v7_spectre_bhb_init(void)
|
|
Matthias Brugger |
214f30 |
+{
|
|
Matthias Brugger |
214f30 |
+ unsigned int state, method = 0;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ switch (read_cpuid_part()) {
|
|
Matthias Brugger |
214f30 |
+ case ARM_CPU_PART_CORTEX_A15:
|
|
Matthias Brugger |
214f30 |
+ case ARM_CPU_PART_BRAHMA_B15:
|
|
Matthias Brugger |
214f30 |
+ case ARM_CPU_PART_CORTEX_A57:
|
|
Matthias Brugger |
214f30 |
+ case ARM_CPU_PART_CORTEX_A72:
|
|
Matthias Brugger |
214f30 |
+ state = SPECTRE_MITIGATED;
|
|
Matthias Brugger |
214f30 |
+ method = SPECTRE_V2_METHOD_LOOP8;
|
|
Matthias Brugger |
214f30 |
+ break;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ case ARM_CPU_PART_CORTEX_A73:
|
|
Matthias Brugger |
214f30 |
+ case ARM_CPU_PART_CORTEX_A75:
|
|
Matthias Brugger |
214f30 |
+ state = SPECTRE_MITIGATED;
|
|
Matthias Brugger |
214f30 |
+ method = SPECTRE_V2_METHOD_BPIALL;
|
|
Matthias Brugger |
214f30 |
+ break;
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ default:
|
|
Matthias Brugger |
214f30 |
+ state = SPECTRE_UNAFFECTED;
|
|
Matthias Brugger |
214f30 |
+ break;
|
|
Matthias Brugger |
214f30 |
+ }
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ if (state == SPECTRE_MITIGATED)
|
|
Matthias Brugger |
214f30 |
+ state = spectre_bhb_install_workaround(method);
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
+ spectre_v2_update_state(state, method);
|
|
Matthias Brugger |
214f30 |
+}
|
|
Matthias Brugger |
214f30 |
+
|
|
Matthias Brugger |
214f30 |
static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned,
|
|
Matthias Brugger |
214f30 |
u32 mask, const char *msg)
|
|
Matthias Brugger |
214f30 |
{
|
|
Matthias Brugger |
214f30 |
@@ -217,4 +292,5 @@ void cpu_v7_ca15_ibe(void)
|
|
Matthias Brugger |
214f30 |
void cpu_v7_bugs_init(void)
|
|
Matthias Brugger |
214f30 |
{
|
|
Matthias Brugger |
214f30 |
cpu_v7_spectre_v2_init();
|
|
Matthias Brugger |
214f30 |
+ cpu_v7_spectre_bhb_init();
|
|
Matthias Brugger |
214f30 |
}
|
|
Matthias Brugger |
214f30 |
--
|
|
Matthias Brugger |
214f30 |
2.34.1
|
|
Matthias Brugger |
214f30 |
|