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

Commit aa6acde6 authored by Will Deacon's avatar Will Deacon Committed by Catalin Marinas
Browse files

arm64: Implement branch predictor hardening for affected Cortex-A CPUs



Cortex-A57, A72, A73 and A75 are susceptible to branch predictor aliasing
and can theoretically be attacked by malicious code.

This patch implements a PSCI-based mitigation for these CPUs when available.
The call into firmware will invalidate the branch predictor state, preventing
any malicious entries from affecting other victim contexts.

Co-developed-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent a65d219f
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -53,3 +53,27 @@ ENTRY(__bp_harden_hyp_vecs_start)
	vectors __kvm_hyp_vector
	.endr
ENTRY(__bp_harden_hyp_vecs_end)
ENTRY(__psci_hyp_bp_inval_start)
	sub	sp, sp, #(8 * 18)
	stp	x16, x17, [sp, #(16 * 0)]
	stp	x14, x15, [sp, #(16 * 1)]
	stp	x12, x13, [sp, #(16 * 2)]
	stp	x10, x11, [sp, #(16 * 3)]
	stp	x8, x9, [sp, #(16 * 4)]
	stp	x6, x7, [sp, #(16 * 5)]
	stp	x4, x5, [sp, #(16 * 6)]
	stp	x2, x3, [sp, #(16 * 7)]
	stp	x0, x1, [sp, #(16 * 8)]
	mov	x0, #0x84000000
	smc	#0
	ldp	x16, x17, [sp, #(16 * 0)]
	ldp	x14, x15, [sp, #(16 * 1)]
	ldp	x12, x13, [sp, #(16 * 2)]
	ldp	x10, x11, [sp, #(16 * 3)]
	ldp	x8, x9, [sp, #(16 * 4)]
	ldp	x6, x7, [sp, #(16 * 5)]
	ldp	x4, x5, [sp, #(16 * 6)]
	ldp	x2, x3, [sp, #(16 * 7)]
	ldp	x0, x1, [sp, #(16 * 8)]
	add	sp, sp, #(8 * 18)
ENTRY(__psci_hyp_bp_inval_end)
+42 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ static int cpu_enable_trap_ctr_access(void *__unused)
DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);

#ifdef CONFIG_KVM
extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];

static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
				const char *hyp_vecs_end)
{
@@ -94,6 +96,9 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
	spin_unlock(&bp_lock);
}
#else
#define __psci_hyp_bp_inval_start	NULL
#define __psci_hyp_bp_inval_end		NULL

static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
				      const char *hyp_vecs_start,
				      const char *hyp_vecs_end)
@@ -118,6 +123,21 @@ static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,

	__install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
}

#include <linux/psci.h>

static int enable_psci_bp_hardening(void *data)
{
	const struct arm64_cpu_capabilities *entry = data;

	if (psci_ops.get_version)
		install_bp_hardening_cb(entry,
				       (bp_hardening_cb_t)psci_ops.get_version,
				       __psci_hyp_bp_inval_start,
				       __psci_hyp_bp_inval_end);

	return 0;
}
#endif	/* CONFIG_HARDEN_BRANCH_PREDICTOR */

#define MIDR_RANGE(model, min, max) \
@@ -260,6 +280,28 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
		.capability = ARM64_WORKAROUND_858921,
		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
	},
#endif
#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
	{
		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
		MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
		.enable = enable_psci_bp_hardening,
	},
	{
		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
		MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
		.enable = enable_psci_bp_hardening,
	},
	{
		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
		MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
		.enable = enable_psci_bp_hardening,
	},
	{
		.capability = ARM64_HARDEN_BRANCH_PREDICTOR,
		MIDR_ALL_VERSIONS(MIDR_CORTEX_A75),
		.enable = enable_psci_bp_hardening,
	},
#endif
	{
	}