diff options
| author | Will Deacon <will.deacon@arm.com> | 2018-01-03 11:17:58 +0000 |
|---|---|---|
| committer | Srinivas Ramana <sramana@codeaurora.org> | 2018-02-07 17:33:15 +0530 |
| commit | 4e56397ea6a4597cf7692b65a18179d1a9bbae2a (patch) | |
| tree | 3d3415f8276523f1bc23a71663f10d019e52b7c5 /arch/arm64/include | |
| parent | 24c543be8577aa9d425e0867be32355dfcb5b831 (diff) | |
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: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will 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: Srinivas Ramana <sramana@codeaurora.org>
Diffstat (limited to 'arch/arm64/include')
| -rw-r--r-- | arch/arm64/include/asm/cpufeature.h | 5 | ||||
| -rw-r--r-- | arch/arm64/include/asm/mmu.h | 41 | ||||
| -rw-r--r-- | arch/arm64/include/asm/sysreg.h | 1 |
3 files changed, 45 insertions, 2 deletions
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index efa76d20a591..6e993094996e 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -36,8 +36,9 @@ #define ARM64_WORKAROUND_CAVIUM_27456 11 #define ARM64_HAS_VIRT_HOST_EXTN 12 -#define ARM64_UNMAP_KERNEL_AT_EL0 23 -#define ARM64_NCAPS 24 +#define ARM64_HARDEN_BRANCH_PREDICTOR 13 +#define ARM64_UNMAP_KERNEL_AT_EL0 14 +#define ARM64_NCAPS 15 #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index e68aa42b0cea..67e8c0c5e3cc 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -20,6 +20,10 @@ #define TTBR_ASID_MASK (UL(0xffff) << 48) #ifndef __ASSEMBLY__ +#include <linux/smp.h> + +#include <asm/cpufeature.h> +#include <asm/percpu.h> typedef struct { atomic64_t id; @@ -39,6 +43,43 @@ static inline bool arm64_kernel_unmapped_at_el0(void) cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0); } +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); diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 0961a24e8d48..90025558d5e1 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -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 |
