diff options
-rw-r--r-- | common/backtrace/backtrace.c | 2 | ||||
-rw-r--r-- | include/arch/aarch64/arch_helpers.h | 20 | ||||
-rw-r--r-- | plat/arm/common/arm_common.c | 2 | ||||
-rw-r--r-- | services/spd/tlkd/tlkd_common.c | 8 |
4 files changed, 26 insertions, 6 deletions
diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c index ef575006f..a07c066ce 100644 --- a/common/backtrace/backtrace.c +++ b/common/backtrace/backtrace.c @@ -70,7 +70,7 @@ static bool is_address_readable(uintptr_t addr) } else if (el == 2U) { ats1e2r(addr); } else { - ats1e1r(addr); + AT(ats1e1r, addr); } isb(); diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h index 4bff0f6f0..1f2f4a923 100644 --- a/include/arch/aarch64/arch_helpers.h +++ b/include/arch/aarch64/arch_helpers.h @@ -590,4 +590,24 @@ static inline uint64_t el_implemented(unsigned int el) #define read_clusterpwrdn() read_clusterpwrdn_el1() #define write_clusterpwrdn(_v) write_clusterpwrdn_el1(_v) +#if ERRATA_SPECULATIVE_AT +/* + * Assuming SCTLR.M bit is already enabled + * 1. Enable page table walk by clearing TCR_EL1.EPDx bits + * 2. Execute AT instruction for lower EL1/0 + * 3. Disable page table walk by setting TCR_EL1.EPDx bits + */ +#define AT(_at_inst, _va) \ +{ \ + assert((read_sctlr_el1() & SCTLR_M_BIT) != 0ULL); \ + write_tcr_el1(read_tcr_el1() & ~(TCR_EPD0_BIT | TCR_EPD1_BIT)); \ + isb(); \ + _at_inst(_va); \ + write_tcr_el1(read_tcr_el1() | (TCR_EPD0_BIT | TCR_EPD1_BIT)); \ + isb(); \ +} +#else +#define AT(_at_inst, _va) _at_inst(_va); +#endif + #endif /* ARCH_HELPERS_H */ diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index e2b99a3d6..e55ea90f8 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -216,7 +216,7 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) * Translate entry point to Physical Address using the EL1&0 * translation regime, including stage 2. */ - ats12e1r(ep); + AT(ats12e1r, ep); } isb(); par = read_par_el1(); diff --git a/services/spd/tlkd/tlkd_common.c b/services/spd/tlkd/tlkd_common.c index dbe6c2e34..820bd8a72 100644 --- a/services/spd/tlkd/tlkd_common.c +++ b/services/spd/tlkd/tlkd_common.c @@ -38,16 +38,16 @@ uint64_t tlkd_va_translate(uintptr_t va, int type) int at = type & AT_MASK; switch (at) { case 0: - ats12e1r(va); + AT(ats12e1r, va); break; case 1: - ats12e1w(va); + AT(ats12e1w, va); break; case 2: - ats12e0r(va); + AT(ats12e0r, va); break; case 3: - ats12e0w(va); + AT(ats12e0w, va); break; default: assert(0); /* Unreachable */ |