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

Commit 57fcac00 authored by Will Deacon's avatar Will Deacon Committed by Gerrit - the friendly Code Review server
Browse files

arm64: Add skeleton to harden the branch predictor against aliasing attacks



Aliasing attacks against CPU branch predictors can allow the attacks to
redirect speculative control flow on some CPUs and potentially divulge
information from one context to another.

This patch adds initial skeleton code behind a new Kconfig option to
enable implementation-specific mitigations against these attacks for
CPUs that are affected.

Change-Id: I07fba1943dd63df8951bf68fac947666100e5559
Co-developed-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Git-commit: 0f15adbb2861ce6f75ccfc5a92b19eae0ef327d0
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[sramana@codeaurora.org: Fix merge conflicts and make it
compilable on msm-4.4]
Signed-off-by: default avatarSrinivas Ramana <sramana@codeaurora.org>
parent 28994bb5
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -775,6 +775,23 @@ config FORCE_MAX_ZONEORDER
	  However for 4K, we choose a higher default value, 11 as opposed to 10, giving us
	  4M allocations matching the default size used by generic code.

config HARDEN_BRANCH_PREDICTOR
	bool "Harden the branch predictor against aliasing attacks" if EXPERT
	default y
	help
	  Speculation attacks against some high-performance processors rely on
	  being able to manipulate the branch predictor for a victim context by
	  executing aliasing branches in the attacker context.  Such attacks
	  can be partially mitigated against by clearing internal branch
	  predictor state and limiting the prediction logic in some situations.

	  This config option will take CPU-specific actions to harden the
	  branch predictor against aliasing attacks and may rely on specific
	  instruction sequences or control bits being set by the system
	  firmware.

	  If unsure, say Y.

menuconfig ARMV8_DEPRECATED
	bool "Emulate deprecated/obsolete ARMv8 instructions"
	depends on COMPAT
+2 −1
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@

#define ARM64_WORKAROUND_CAVIUM_27456		11
#define ARM64_HAS_VIRT_HOST_EXTN		12
#define ARM64_NCAPS				13
#define ARM64_HARDEN_BRANCH_PREDICTOR		13
#define ARM64_NCAPS				14

#ifndef __ASSEMBLY__

+42 −0
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@
#ifndef __ASM_MMU_H
#define __ASM_MMU_H

#include <linux/smp.h>

#include <asm/cpufeature.h>
#include <asm/percpu.h>

typedef struct {
	atomic64_t	id;
	void		*vdso;
@@ -28,6 +33,43 @@ typedef struct {
 */
#define ASID(mm)	((mm)->context.id.counter & 0xffff)

typedef void (*bp_hardening_cb_t)(void);

struct bp_hardening_data {
	int			hyp_vectors_slot;
	bp_hardening_cb_t	fn;
};

#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
extern char __bp_harden_hyp_vecs_start[], __bp_harden_hyp_vecs_end[];

DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);

static inline struct bp_hardening_data *arm64_get_bp_hardening_data(void)
{
	return this_cpu_ptr(&bp_hardening_data);
}

static inline void arm64_apply_bp_hardening(void)
{
	struct bp_hardening_data *d;

	if (!cpus_have_cap(ARM64_HARDEN_BRANCH_PREDICTOR))
		return;

	d = arm64_get_bp_hardening_data();
	if (d->fn)
		d->fn();
}
#else
static inline struct bp_hardening_data *arm64_get_bp_hardening_data(void)
{
	return NULL;
}

static inline void arm64_apply_bp_hardening(void)	{ }
#endif	/* CONFIG_HARDEN_BRANCH_PREDICTOR */

extern void paging_init(void);
extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
extern void init_mem_pgprot(void);
+1 −0
Original line number Diff line number Diff line
@@ -112,6 +112,7 @@
#define ID_AA64ISAR0_AES_SHIFT		4

/* id_aa64pfr0 */
#define ID_AA64PFR0_CSV2_SHIFT		56
#define ID_AA64PFR0_GIC_SHIFT		24
#define ID_AA64PFR0_ASIMD_SHIFT		20
#define ID_AA64PFR0_FP_SHIFT		16
+4 −0
Original line number Diff line number Diff line
@@ -49,6 +49,10 @@ arm64-obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o
arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o

ifeq ($(CONFIG_KVM),y)
arm64-obj-$(CONFIG_HARDEN_BRANCH_PREDICTOR)	+= bpi.o
endif

obj-y					+= $(arm64-obj-y) vdso/ probes/
obj-m					+= $(arm64-obj-m)
head-y					:= head.o
Loading