summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/backtrace/backtrace.c2
-rw-r--r--include/arch/aarch64/arch_helpers.h20
-rw-r--r--plat/arm/common/arm_common.c2
-rw-r--r--services/spd/tlkd/tlkd_common.c8
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 */