Skip to content

Commit

Permalink
arm64: errata: add workaround for cortex-a53 erratum #845719
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Will Deacon committed Apr 1, 2015
1 parent cc3979b commit 905e8c5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 1 deletion.
21 changes: 21 additions & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,27 @@ config ARM64_ERRATUM_832075

If unsure, say Y.

config ARM64_ERRATUM_845719
bool "Cortex-A53: 845719: a load might read incorrect data"
depends on COMPAT
default y
help
This option adds an alternative code sequence to work around ARM
erratum 845719 on Cortex-A53 parts up to r0p4.

When running a compat (AArch32) userspace on an affected Cortex-A53
part, 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.

The workaround is to write the contextidr_el1 register on exception
return to a 32-bit task.
Please note that this does not necessarily enable the workaround,
as it depends on the alternative framework, which will only patch
the kernel if an affected CPU is detected.

If unsure, say Y.

endmenu


Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@

#define ARM64_WORKAROUND_CLEAN_CACHE 0
#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
#define ARM64_WORKAROUND_845719 2

#define ARM64_NCAPS 2
#define ARM64_NCAPS 3

#ifndef __ASSEMBLY__

Expand Down
8 changes: 8 additions & 0 deletions arch/arm64/kernel/cpu_errata.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.capability = ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE,
MIDR_RANGE(MIDR_CORTEX_A57, 0x00, 0x12),
},
#endif
#ifdef CONFIG_ARM64_ERRATUM_845719
{
/* Cortex-A53 r0p[01234] */
.desc = "ARM erratum 845719",
.capability = ARM64_WORKAROUND_845719,
MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x04),
},
#endif
{
}
Expand Down
20 changes: 20 additions & 0 deletions arch/arm64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
#include <linux/init.h>
#include <linux/linkage.h>

#include <asm/alternative-asm.h>
#include <asm/assembler.h>
#include <asm/asm-offsets.h>
#include <asm/cpufeature.h>
#include <asm/errno.h>
#include <asm/esr.h>
#include <asm/thread_info.h>
Expand Down Expand Up @@ -120,6 +122,24 @@
ct_user_enter
ldr x23, [sp, #S_SP] // load return stack pointer
msr sp_el0, x23

#ifdef CONFIG_ARM64_ERRATUM_845719
alternative_insn \
"nop", \
"tbz x22, #4, 1f", \
ARM64_WORKAROUND_845719
#ifdef CONFIG_PID_IN_CONTEXTIDR
alternative_insn \
"nop; nop", \
"mrs x29, contextidr_el1; msr contextidr_el1, x29; 1:", \
ARM64_WORKAROUND_845719
#else
alternative_insn \
"nop", \
"msr contextidr_el1, xzr; 1:", \
ARM64_WORKAROUND_845719
#endif
#endif
.endif
msr elr_el1, x21 // set up the return data
msr spsr_el1, x22
Expand Down

0 comments on commit 905e8c5

Please sign in to comment.