Commit 3388b38d authored by Antonio Nino Diaz's avatar Antonio Nino Diaz
Browse files

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: default avatarAntonio Nino Diaz <antonio.ninodiaz@arm.com>
parent df312c5a
...@@ -348,6 +348,8 @@ ...@@ -348,6 +348,8 @@
#define TCR_SH_OUTER_SHAREABLE (U(0x2) << 12) #define TCR_SH_OUTER_SHAREABLE (U(0x2) << 12)
#define TCR_SH_INNER_SHAREABLE (U(0x3) << 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_SHIFT U(0x0)
#define MODE_SP_MASK U(0x1) #define MODE_SP_MASK U(0x1)
#define MODE_SP_EL0 U(0x0) #define MODE_SP_EL0 U(0x0)
......
...@@ -182,7 +182,11 @@ void init_xlat_tables(void) ...@@ -182,7 +182,11 @@ void init_xlat_tables(void)
/* Define EL1 and EL3 variants of the function enabling the MMU */ /* Define EL1 and EL3 variants of the function enabling the MMU */
DEFINE_ENABLE_MMU_EL(1, 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) tlbivmalle1)
DEFINE_ENABLE_MMU_EL(3, DEFINE_ENABLE_MMU_EL(3,
TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT), TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT),
......
...@@ -256,7 +256,11 @@ void enable_mmu_arch(unsigned int flags, ...@@ -256,7 +256,11 @@ void enable_mmu_arch(unsigned int flags,
#if IMAGE_EL == 1 #if IMAGE_EL == 1
assert(IS_IN_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); enable_mmu_internal_el1(flags, mair, tcr, ttbr);
#elif IMAGE_EL == 3 #elif IMAGE_EL == 3
assert(IS_IN_EL(3)); assert(IS_IN_EL(3));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment