summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish V Badarkhe <Manish.Badarkhe@arm.com>2020-07-14 14:43:12 +0100
committerManish V Badarkhe <Manish.Badarkhe@arm.com>2020-08-18 10:49:27 +0100
commit86ba585300aa784160bbcb8441ace3df8e06e1bd (patch)
tree466f8ec4804da549ce0baf9916165e3c9a654edb
parent3b8456bd1c9fd2303483f0675786e3fbda81a0af (diff)
downloadarm-trusted-firmware-86ba585300aa784160bbcb8441ace3df8e06e1bd.tar.gz
Add wrapper for AT instruction
In case of AT speculative workaround applied, page table walk is disabled for lower ELs (EL1 and EL0) in EL3. Hence added a wrapper function which temporarily enables page table walk to execute AT instruction for lower ELs and then disables page table walk. Execute AT instructions directly for lower ELs (EL1 and EL0) assuming page table walk is enabled always when AT speculative workaround is not applied. Change-Id: I4ad4c0bcbb761448af257e9f72ae979473c0dde8 Signed-off-by: Manish V Badarkhe <Manish.Badarkhe@arm.com>
-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 */