Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 604760bf authored by James Morse's avatar James Morse Committed by Gerrit - the friendly Code Review server
Browse files

arm64: Mitigate spectre style branch history side channels



commit 558c303c9734af5a813739cd284879227f7297d2 upstream.

Speculation attacks against some high-performance processors can
make use of branch history to influence future speculation.
When taking an exception from user-space, a sequence of branches
or a firmware call overwrites or invalidates the branch history.

The sequence of branches is added to the vectors, and should appear
before the first indirect branch. For systems using KPTI the sequence
is added to the kpti trampoline where it has a free register as the exit
from the trampoline is via a  'ret'. For systems not using KPTI, the same
register tricks are used to free up a register in the vectors.
For the firmware call, arch-workaround-3 clobbers 4 registers, so
there is no choice but to save them to the EL1 stack. This only happens
for entry from EL0 so if we take an exception due to the stack access,
it will not become re-entrant.

For KVM, the existing branch-predictor-hardening vectors are used.
When a spectre version of these vectors is in use, the firmware call
is sufficient to mitigate against Spectre-BHB. For the non-spectre
versions the sequence of branches is added to the indirect vector.

Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Cc: <stable@kernel.org> # <v5.17.x 72bb9dcb6c33c arm64: Add Cortex-X2 CPU part definition
Cc: <stable@kernel.org> # <v5.16.x 2d0d656700d67 arm64: Add Neoverse-N2, Cortex-A710 CPU part definition
Cc: <stable@kernel.org> # <v5.10.x 8a6b88e66233f arm64: Add part number for Arm Cortex-A77
[ modified for stable, moved code to cpu_errata.c removed bitmap of
  mitigations, use kvm template infrastructure ]
Signed-off-by: default avatarJames Morse <james.morse@arm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Git-commit: c20d5517
Git-repo: https://android.googlesource.com/kernel/common/


Change-Id: Ib5f1191b3e81b68edbcd2a0ba4f45e0c1041ad05
Signed-off-by: default avatarKishor Krishna Bhat <quic_kishkris@quicinc.com>
parent b0264309
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1152,6 +1152,15 @@ config COMPAT_VDSO
	  You must have a 32-bit build of glibc 2.22 or later for programs
	  to seamlessly take advantage of this.

config MITIGATE_SPECTRE_BRANCH_HISTORY
	bool "Mitigate Spectre style attacks against branch history" if EXPERT
	default y
	help
	  Speculation attacks against some high-performance processors can
	  make use of branch history to influence future speculation.
	  When taking an exception from user-space, a sequence of branches
	  or a firmware call overwrites the branch history.

menuconfig ARMV8_DEPRECATED
	bool "Emulate deprecated/obsolete ARMv8 instructions"
	depends on COMPAT
+3 −1
Original line number Diff line number Diff line
@@ -734,7 +734,9 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU

	.macro __mitigate_spectre_bhb_loop	tmp
#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY
	mov	\tmp, #32
alternative_cb  spectre_bhb_patch_loop_iter
	mov	\tmp, #32		// Patched to correct the immediate
alternative_cb_end
.Lspectre_bhb_loop\@:
	b	. + 4
	subs	\tmp, \tmp, #1
+18 −0
Original line number Diff line number Diff line
@@ -482,6 +482,21 @@ static inline bool cpu_supports_mixed_endian_el0(void)
	return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
}

static inline bool supports_csv2p3(int scope)
{
	u64 pfr0;
	u8 csv2_val;

	if (scope == SCOPE_LOCAL_CPU)
		pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
	else
		pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);

	csv2_val = cpuid_feature_extract_unsigned_field(pfr0,
							ID_AA64PFR0_CSV2_SHIFT);
	return csv2_val == 3;
}

static inline bool system_supports_32bit_el0(void)
{
	return cpus_have_const_cap(ARM64_HAS_32BIT_EL0);
@@ -540,6 +555,9 @@ enum mitigation_state {
};

enum mitigation_state arm64_get_spectre_bhb_state(void);
bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
u8 spectre_bhb_loop_affected(int scope);
void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);

#endif /* __ASSEMBLY__ */

+8 −0
Original line number Diff line number Diff line
@@ -85,9 +85,13 @@
#define ARM_CPU_PART_KRYO2XX_GOLD	0x800
#define ARM_CPU_PART_KRYO2XX_SILVER	0x801
#define ARM_CPU_PART_CORTEX_A77		0xD0D
#define ARM_CPU_PART_NEOVERSE_V1	0xD40
#define ARM_CPU_PART_CORTEX_A78		0xD41
#define ARM_CPU_PART_CORTEX_X1		0xD44
#define ARM_CPU_PART_CORTEX_A710	0xD47
#define ARM_CPU_PART_CORTEX_X2		0xD48
#define ARM_CPU_PART_NEOVERSE_N2	0xD49
#define ARM_CPU_PART_CORTEX_A78C	0xD4B
#define ARM_CPU_PART_NEOVERSE_N1	0xD0C

#define APM_CPU_PART_POTENZA		0x000
@@ -119,9 +123,13 @@
#define MIDR_KRYO4G	MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO4G)
#define MIDR_KRYO5S	MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, ARM_CPU_PART_KRYO5S)
#define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
#define MIDR_NEOVERSE_V1	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1)
#define MIDR_CORTEX_A78	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78)
#define MIDR_CORTEX_X1	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1)
#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
#define MIDR_CORTEX_A78C	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
#define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
#define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
+1 −0
Original line number Diff line number Diff line
@@ -593,6 +593,7 @@
#endif

/* id_aa64mmfr1 */
#define ID_AA64MMFR1_ECBHB_SHIFT	60
#define ID_AA64MMFR1_PAN_SHIFT		20
#define ID_AA64MMFR1_LOR_SHIFT		16
#define ID_AA64MMFR1_HPD_SHIFT		12
Loading