aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2015-03-23 15:07:02 -0400
committerWill Deacon <will.deacon@arm.com>2015-04-01 05:24:31 -0400
commit905e8c5dcaa147163672b06fe9dcb5abaacbc711 (patch)
tree4284f6e2ecac493b6e4938e4b60e57fb521c3790 /arch/arm64
parentcc3979b54d5f1d5b5059b404892888c304d28080 (diff)
arm64: errata: add workaround for cortex-a53 erratum #845719
When running a compat (AArch32) userspace on Cortex-A53, a load at EL0 from a virtual address that matches the bottom 32 bits of the virtual address used by a recent load at (AArch64) EL1 might return incorrect data. This patch works around the issue by writing to the contextidr_el1 register on the exception return path when returning to a 32-bit task. This workaround is patched in at runtime based on the MIDR value of the processor. Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Tested-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/Kconfig21
-rw-r--r--arch/arm64/include/asm/cpufeature.h3
-rw-r--r--arch/arm64/kernel/cpu_errata.c8
-rw-r--r--arch/arm64/kernel/entry.S20
4 files changed, 51 insertions, 1 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 02f67a9d7426..23d51be7d60a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -361,6 +361,27 @@ config ARM64_ERRATUM_832075
361 361
362 If unsure, say Y. 362 If unsure, say Y.
363 363
364config ARM64_ERRATUM_845719
365 bool "Cortex-A53: 845719: a load might read incorrect data"
366 depends on COMPAT
367 default y
368 help
369 This option adds an alternative code sequence to work around ARM
370 erratum 845719 on Cortex-A53 parts up to r0p4.
371
372 When running a compat (AArch32) userspace on an affected Cortex-A53
373 part, a load at EL0 from a virtual address that matches the bottom 32
374 bits of the virtual address used by a recent load at (AArch64) EL1
375 might return incorrect data.
376
377 The workaround is to write the contextidr_el1 register on exception
378 return to a 32-bit task.
379 Please note that this does not necessarily enable the workaround,
380 as it depends on the alternative framework, which will only patch
381 the kernel if an affected CPU is detected.
382
383 If unsure, say Y.
384
364endmenu 385endmenu
365 386
366 387
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 6ae35d160464..82cb9f98ba1a 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -23,8 +23,9 @@
23 23
24#define ARM64_WORKAROUND_CLEAN_CACHE 0 24#define ARM64_WORKAROUND_CLEAN_CACHE 0
25#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1 25#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
26#define ARM64_WORKAROUND_845719 2
26 27
27#define ARM64_NCAPS 2 28#define ARM64_NCAPS 3
28 29
29#ifndef __ASSEMBLY__ 30#ifndef __ASSEMBLY__
30 31
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a66f4fa4d541..4672860def1f 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -73,6 +73,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
73 MIDR_RANGE(MIDR_CORTEX_A57, 0x00, 0x12), 73 MIDR_RANGE(MIDR_CORTEX_A57, 0x00, 0x12),
74 }, 74 },
75#endif 75#endif
76#ifdef CONFIG_ARM64_ERRATUM_845719
77 {
78 /* Cortex-A53 r0p[01234] */
79 .desc = "ARM erratum 845719",
80 .capability = ARM64_WORKAROUND_845719,
81 MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
82 },
83#endif
76 { 84 {
77 } 85 }
78}; 86};
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index cf21bb3bf752..959fe8733560 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -21,8 +21,10 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/linkage.h> 22#include <linux/linkage.h>
23 23
24#include <asm/alternative-asm.h>
24#include <asm/assembler.h> 25#include <asm/assembler.h>
25#include <asm/asm-offsets.h> 26#include <asm/asm-offsets.h>
27#include <asm/cpufeature.h>
26#include <asm/errno.h> 28#include <asm/errno.h>
27#include <asm/esr.h> 29#include <asm/esr.h>
28#include <asm/thread_info.h> 30#include <asm/thread_info.h>
@@ -120,6 +122,24 @@
120 ct_user_enter 122 ct_user_enter
121 ldr x23, [sp, #S_SP] // load return stack pointer 123 ldr x23, [sp, #S_SP] // load return stack pointer
122 msr sp_el0, x23 124 msr sp_el0, x23
125
126#ifdef CONFIG_ARM64_ERRATUM_845719
127 alternative_insn \
128 "nop", \
129 "tbz x22, #4, 1f", \
130 ARM64_WORKAROUND_845719
131#ifdef CONFIG_PID_IN_CONTEXTIDR
132 alternative_insn \
133 "nop; nop", \
134 "mrs x29, contextidr_el1; msr contextidr_el1, x29; 1:", \
135 ARM64_WORKAROUND_845719
136#else
137 alternative_insn \
138 "nop", \
139 "msr contextidr_el1, xzr; 1:", \
140 ARM64_WORKAROUND_845719
141#endif
142#endif
123 .endif 143 .endif
124 msr elr_el1, x21 // set up the return data 144 msr elr_el1, x21 // set up the return data
125 msr spsr_el1, x22 145 msr spsr_el1, x22