diff options
author | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2017-09-15 10:30:34 +0100 |
---|---|---|
committer | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2017-09-21 11:57:11 +0100 |
commit | 3388b38dc3426d28aeeb2462ee5125ec983e9f3a (patch) | |
tree | 603a0517d88b9299c4be5d2bf4d6a5b3f23474d4 | |
parent | df312c5a2b152953f755df9d979cff20afb7ef4b (diff) |
Set TCR_EL1.EPD1 bit to 1
In the S-EL1&0 translation regime we aren't using the higher VA range,
whose translation table base address is held in TTBR1_EL1. The bit
TCR_EL1.EPD1 can be used to disable translations using TTBR1_EL1, but
the code wasn't setting it to 1. Additionally, other fields in TCR1_EL1
associated with the higher VA range (TBI1, TG1, SH1, ORGN1, IRGN1 and
A1) weren't set correctly as they were left as 0. In particular, 0 is a
reserved value for TG1. Also, TBBR1_EL1 was not explicitly set and its
reset value is UNKNOWN.
Therefore memory accesses to the higher VA range would result in
unpredictable behaviour as a translation table walk would be attempted
using an UNKNOWN value in TTBR1_EL1.
On the FVP and Juno platforms accessing the higher VA range resulted in
a translation fault, but this may not always be the case on all
platforms.
This patch sets the bit TCR_EL1.EPD1 to 1 so that any kind of
unpredictable behaviour is prevented.
This bug only affects the AArch64 version of the code, the AArch32
version sets this bit to 1 as expected.
Change-Id: I481c000deda5bc33a475631301767b9e0474a303
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
-rw-r--r-- | include/lib/aarch64/arch.h | 2 | ||||
-rw-r--r-- | lib/xlat_tables/aarch64/xlat_tables.c | 6 | ||||
-rw-r--r-- | lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 6 |
3 files changed, 12 insertions, 2 deletions
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h index e38a5307..188b0b75 100644 --- a/include/lib/aarch64/arch.h +++ b/include/lib/aarch64/arch.h @@ -348,6 +348,8 @@ #define TCR_SH_OUTER_SHAREABLE (U(0x2) << 12) #define TCR_SH_INNER_SHAREABLE (U(0x3) << 12) +#define TCR_EPD1_BIT (U(1) << 23) + #define MODE_SP_SHIFT U(0x0) #define MODE_SP_MASK U(0x1) #define MODE_SP_EL0 U(0x0) diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c index 2ddf8cba..28ae1f73 100644 --- a/lib/xlat_tables/aarch64/xlat_tables.c +++ b/lib/xlat_tables/aarch64/xlat_tables.c @@ -182,7 +182,11 @@ void init_xlat_tables(void) /* Define EL1 and EL3 variants of the function enabling the MMU */ DEFINE_ENABLE_MMU_EL(1, - (tcr_ps_bits << TCR_EL1_IPS_SHIFT), + /* + * TCR_EL1.EPD1: Disable translation table walk for addresses + * that are translated using TTBR1_EL1. + */ + TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT), tlbivmalle1) DEFINE_ENABLE_MMU_EL(3, TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT), diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index 097e815c..760db928 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -256,7 +256,11 @@ void enable_mmu_arch(unsigned int flags, #if IMAGE_EL == 1 assert(IS_IN_EL(1)); - tcr |= tcr_ps_bits << TCR_EL1_IPS_SHIFT; + /* + * TCR_EL1.EPD1: Disable translation table walk for addresses that are + * translated using TTBR1_EL1. + */ + tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT); enable_mmu_internal_el1(flags, mair, tcr, ttbr); #elif IMAGE_EL == 3 assert(IS_IN_EL(3)); |