Commit fc55c23a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-bhb' of git://git.armlinux.org.uk/~rmk/linux-arm

Pull ARM spectre fixes from Russell King:
 "ARM Spectre BHB mitigations.

  These patches add Spectre BHB migitations for the following Arm CPUs
  to the 32-bit ARM kernels:
   - Cortex A15
   - Cortex A57
   - Cortex A72
   - Cortex A73
   - Cortex A75
   - Brahma B15
  for CVE-2022-23960"

* tag 'for-linus-bhb' of git://git.armlinux.org.uk/~rmk/linux-arm:
  ARM: include unprivileged BPF status in Spectre V2 reporting
  ARM: Spectre-BHB workaround
  ARM: use LOADADDR() to get load address of sections
  ARM: early traps initialisation
  ARM: report Spectre v2 status through sysfs
parents 4a01e748 25875aa7
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -107,6 +107,16 @@
	.endm
#endif

#if __LINUX_ARM_ARCH__ < 7
	.macro	dsb, args
	mcr	p15, 0, r0, c7, c10, 4
	.endm

	.macro	isb, args
	mcr	p15, 0, r0, c7, r5, 4
	.endm
#endif

	.macro asm_trace_hardirqs_off, save=1
#if defined(CONFIG_TRACE_IRQFLAGS)
	.if \save
+32 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __ASM_SPECTRE_H
#define __ASM_SPECTRE_H

enum {
	SPECTRE_UNAFFECTED,
	SPECTRE_MITIGATED,
	SPECTRE_VULNERABLE,
};

enum {
	__SPECTRE_V2_METHOD_BPIALL,
	__SPECTRE_V2_METHOD_ICIALLU,
	__SPECTRE_V2_METHOD_SMC,
	__SPECTRE_V2_METHOD_HVC,
	__SPECTRE_V2_METHOD_LOOP8,
};

enum {
	SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL),
	SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU),
	SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC),
	SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC),
	SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8),
};

void spectre_v2_update_state(unsigned int state, unsigned int methods);

int spectre_bhb_update_vectors(unsigned int method);

#endif
+26 −9
Original line number Diff line number Diff line
@@ -26,6 +26,11 @@
#define ARM_MMU_DISCARD(x)	x
#endif

/* Set start/end symbol names to the LMA for the section */
#define ARM_LMA(sym, section)						\
	sym##_start = LOADADDR(section);				\
	sym##_end = LOADADDR(section) + SIZEOF(section)

#define PROC_INFO							\
		. = ALIGN(4);						\
		__proc_info_begin = .;					\
@@ -110,19 +115,31 @@
 * only thing that matters is their relative offsets
 */
#define ARM_VECTORS							\
	__vectors_start = .;						\
	.vectors 0xffff0000 : AT(__vectors_start) {			\
	__vectors_lma = .;						\
	OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) {		\
		.vectors {						\
			*(.vectors)					\
		}							\
	. = __vectors_start + SIZEOF(.vectors);				\
	__vectors_end = .;						\
		.vectors.bhb.loop8 {					\
			*(.vectors.bhb.loop8)				\
		}							\
		.vectors.bhb.bpiall {					\
			*(.vectors.bhb.bpiall)				\
		}							\
	}								\
	ARM_LMA(__vectors, .vectors);					\
	ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8);		\
	ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall);		\
	. = __vectors_lma + SIZEOF(.vectors) +				\
		SIZEOF(.vectors.bhb.loop8) +				\
		SIZEOF(.vectors.bhb.bpiall);				\
									\
	__stubs_start = .;						\
	.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {		\
	__stubs_lma = .;						\
	.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) {		\
		*(.stubs)						\
	}								\
	. = __stubs_start + SIZEOF(.stubs);				\
	__stubs_end = .;						\
	ARM_LMA(__stubs, .stubs);					\
	. = __stubs_lma + SIZEOF(.stubs);				\
									\
	PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors));

+2 −0
Original line number Diff line number Diff line
@@ -106,4 +106,6 @@ endif

obj-$(CONFIG_HAVE_ARM_SMCCC)	+= smccc-call.o

obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o

extra-y := $(head-y) vmlinux.lds
+73 −6
Original line number Diff line number Diff line
@@ -1002,12 +1002,11 @@ vector_\name:
	sub	lr, lr, #\correction
	.endif

	@
	@ Save r0, lr_<exception> (parent PC) and spsr_<exception>
	@ (parent CPSR)
	@
	@ Save r0, lr_<exception> (parent PC)
	stmia	sp, {r0, lr}		@ save r0, lr
	mrs	lr, spsr

	@ Save spsr_<exception> (parent CPSR)
2:	mrs	lr, spsr
	str	lr, [sp, #8]		@ save spsr

	@
@@ -1028,6 +1027,44 @@ vector_\name:
	movs	pc, lr			@ branch to handler in SVC mode
ENDPROC(vector_\name)

#ifdef CONFIG_HARDEN_BRANCH_HISTORY
	.subsection 1
	.align 5
vector_bhb_loop8_\name:
	.if \correction
	sub	lr, lr, #\correction
	.endif

	@ Save r0, lr_<exception> (parent PC)
	stmia	sp, {r0, lr}

	@ bhb workaround
	mov	r0, #8
1:	b	. + 4
	subs	r0, r0, #1
	bne	1b
	dsb
	isb
	b	2b
ENDPROC(vector_bhb_loop8_\name)

vector_bhb_bpiall_\name:
	.if \correction
	sub	lr, lr, #\correction
	.endif

	@ Save r0, lr_<exception> (parent PC)
	stmia	sp, {r0, lr}

	@ bhb workaround
	mcr	p15, 0, r0, c7, c5, 6	@ BPIALL
	@ isb not needed due to "movs pc, lr" in the vector stub
	@ which gives a "context synchronisation".
	b	2b
ENDPROC(vector_bhb_bpiall_\name)
	.previous
#endif

	.align	2
	@ handler addresses follow this label
1:
@@ -1036,6 +1073,10 @@ ENDPROC(vector_\name)
	.section .stubs, "ax", %progbits
	@ This must be the first word
	.word	vector_swi
#ifdef CONFIG_HARDEN_BRANCH_HISTORY
	.word	vector_bhb_loop8_swi
	.word	vector_bhb_bpiall_swi
#endif

vector_rst:
 ARM(	swi	SYS_ERROR0	)
@@ -1150,8 +1191,10 @@ vector_addrexcptn:
 * FIQ "NMI" handler
 *-----------------------------------------------------------------------------
 * Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86
 * systems.
 * systems. This must be the last vector stub, so lets place it in its own
 * subsection.
 */
	.subsection 2
	vector_stub	fiq, FIQ_MODE, 4

	.long	__fiq_usr			@  0  (USR_26 / USR_32)
@@ -1184,6 +1227,30 @@ vector_addrexcptn:
	W(b)	vector_irq
	W(b)	vector_fiq

#ifdef CONFIG_HARDEN_BRANCH_HISTORY
	.section .vectors.bhb.loop8, "ax", %progbits
.L__vectors_bhb_loop8_start:
	W(b)	vector_rst
	W(b)	vector_bhb_loop8_und
	W(ldr)	pc, .L__vectors_bhb_loop8_start + 0x1004
	W(b)	vector_bhb_loop8_pabt
	W(b)	vector_bhb_loop8_dabt
	W(b)	vector_addrexcptn
	W(b)	vector_bhb_loop8_irq
	W(b)	vector_bhb_loop8_fiq

	.section .vectors.bhb.bpiall, "ax", %progbits
.L__vectors_bhb_bpiall_start:
	W(b)	vector_rst
	W(b)	vector_bhb_bpiall_und
	W(ldr)	pc, .L__vectors_bhb_bpiall_start + 0x1008
	W(b)	vector_bhb_bpiall_pabt
	W(b)	vector_bhb_bpiall_dabt
	W(b)	vector_addrexcptn
	W(b)	vector_bhb_bpiall_irq
	W(b)	vector_bhb_bpiall_fiq
#endif

	.data
	.align	2

Loading