aboutsummaryrefslogtreecommitdiffstats
path: root/lib/xlat_tables_v2
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2021-02-16 21:01:22 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-16 21:01:22 +0000
commitefb2826bb8160e2d8e0fcec85133a7468484f9fd (patch)
tree37a21c69306801ee7cdda5167a30896c8740155b /lib/xlat_tables_v2
parentb00a71fc312c9781fa6f404dccfb55b062b2ccac (diff)
parentfaa476c0caaa598afa5a6109d17102db5fe35ec6 (diff)
downloadplatform_external_arm-trusted-firmware-master.tar.gz
platform_external_arm-trusted-firmware-master.tar.bz2
platform_external_arm-trusted-firmware-master.zip
Original change: https://android-review.googlesource.com/c/platform/external/arm-trusted-firmware/+/1589611 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I3a25534ceed4f8e188510641080d8b8ed49b8f62
Diffstat (limited to 'lib/xlat_tables_v2')
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch.c4
-rw-r--r--lib/xlat_tables_v2/ro_xlat_tables.mk37
-rw-r--r--lib/xlat_tables_v2/xlat_tables.mk6
-rw-r--r--lib/xlat_tables_v2/xlat_tables_context.c91
-rw-r--r--lib/xlat_tables_v2/xlat_tables_core.c11
-rw-r--r--lib/xlat_tables_v2/xlat_tables_private.h5
-rw-r--r--lib/xlat_tables_v2/xlat_tables_utils.c8
7 files changed, 148 insertions, 14 deletions
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 8eeeea1dd..3832b0703 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -135,7 +135,7 @@ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
bool is_dcache_enabled(void)
{
- unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
+ unsigned int el = get_current_el_maybe_constant();
if (el == 1U) {
return (read_sctlr_el1() & SCTLR_C_BIT) != 0U;
diff --git a/lib/xlat_tables_v2/ro_xlat_tables.mk b/lib/xlat_tables_v2/ro_xlat_tables.mk
new file mode 100644
index 000000000..7991e1afd
--- /dev/null
+++ b/lib/xlat_tables_v2/ro_xlat_tables.mk
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2020, ARM Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${USE_DEBUGFS}, 1)
+ $(error "Debugfs requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+endif
+
+ifeq (${ARCH},aarch32)
+ ifeq (${RESET_TO_SP_MIN},1)
+ $(error "RESET_TO_SP_MIN requires functionality from the dynamic \
+ translation library and is incompatible with \
+ ALLOW_RO_XLAT_TABLES.")
+ endif
+else # if AArch64
+ ifeq (${PLAT},tegra)
+ $(error "Tegra requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+ endif
+ ifeq (${RESET_TO_BL31},1)
+ $(error "RESET_TO_BL31 requires functionality from the dynamic \
+ translation library and is incompatible with \
+ ALLOW_RO_XLAT_TABLES.")
+ endif
+ ifeq (${SPD},trusty)
+ $(error "Trusty requires functionality from the dynamic translation \
+ library and is incompatible with ALLOW_RO_XLAT_TABLES.")
+ endif
+ ifeq (${SPM_MM},1)
+ $(error "SPM_MM requires functionality to change memory region \
+ attributes, which is not possible once the translation tables \
+ have been made read-only.")
+ endif
+endif
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index c946315bf..bcc3e68d8 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -13,3 +13,7 @@ XLAT_TABLES_LIB_SRCS := $(addprefix lib/xlat_tables_v2/, \
XLAT_TABLES_LIB_V2 := 1
$(eval $(call add_define,XLAT_TABLES_LIB_V2))
+
+ifeq (${ALLOW_RO_XLAT_TABLES}, 1)
+ include lib/xlat_tables_v2/ro_xlat_tables.mk
+endif
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index f4b64b33f..95dae88eb 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -1,9 +1,10 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch_helpers.h>
#include <assert.h>
#include <platform_def.h>
@@ -25,7 +26,7 @@ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
* currently executing.
*/
REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,
- PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
+ PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);
void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size,
unsigned int attr)
@@ -119,6 +120,75 @@ int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr)
return xlat_change_mem_attributes_ctx(&tf_xlat_ctx, base_va, size, attr);
}
+#if PLAT_RO_XLAT_TABLES
+/* Change the memory attributes of the descriptors which resolve the address
+ * range that belongs to the translation tables themselves, which are by default
+ * mapped as part of read-write data in the BL image's memory.
+ *
+ * Since the translation tables map themselves via these level 3 (page)
+ * descriptors, any change applied to them with the MMU on would introduce a
+ * chicken and egg problem because of the break-before-make sequence.
+ * Eventually, it would reach the descriptor that resolves the very table it
+ * belongs to and the invalidation (break step) would cause the subsequent write
+ * (make step) to it to generate an MMU fault. Therefore, the MMU is disabled
+ * before making the change.
+ *
+ * No assumption is made about what data this function needs, therefore all the
+ * caches are flushed in order to ensure coherency. A future optimization would
+ * be to only flush the required data to main memory.
+ */
+int xlat_make_tables_readonly(void)
+{
+ assert(tf_xlat_ctx.initialized == true);
+#ifdef __aarch64__
+ if (tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME) {
+ disable_mmu_el1();
+ } else if (tf_xlat_ctx.xlat_regime == EL3_REGIME) {
+ disable_mmu_el3();
+ } else {
+ assert(tf_xlat_ctx.xlat_regime == EL2_REGIME);
+ return -1;
+ }
+
+ /* Flush all caches. */
+ dcsw_op_all(DCCISW);
+#else /* !__aarch64__ */
+ assert(tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME);
+ /* On AArch32, we flush the caches before disabling the MMU. The reason
+ * for this is that the dcsw_op_all AArch32 function pushes some
+ * registers onto the stack under the assumption that it is writing to
+ * cache, which is not true with the MMU off. This would result in the
+ * stack becoming corrupted and a wrong/junk value for the LR being
+ * restored at the end of the routine.
+ */
+ dcsw_op_all(DC_OP_CISW);
+ disable_mmu_secure();
+#endif
+
+ int rc = xlat_change_mem_attributes_ctx(&tf_xlat_ctx,
+ (uintptr_t)tf_xlat_ctx.tables,
+ tf_xlat_ctx.tables_num * XLAT_TABLE_SIZE,
+ MT_RO_DATA | MT_SECURE);
+
+#ifdef __aarch64__
+ if (tf_xlat_ctx.xlat_regime == EL1_EL0_REGIME) {
+ enable_mmu_el1(0U);
+ } else {
+ assert(tf_xlat_ctx.xlat_regime == EL3_REGIME);
+ enable_mmu_el3(0U);
+ }
+#else /* !__aarch64__ */
+ enable_mmu_svc_mon(0U);
+#endif
+
+ if (rc == 0) {
+ tf_xlat_ctx.readonly_tables = true;
+ }
+
+ return rc;
+}
+#endif /* PLAT_RO_XLAT_TABLES */
+
/*
* If dynamic allocation of new regions is disabled then by the time we call the
* function enabling the MMU, we'll have registered all the memory regions to
@@ -162,6 +232,23 @@ void enable_mmu_el3(unsigned int flags)
enable_mmu_direct_el3(flags);
}
+void enable_mmu(unsigned int flags)
+{
+ switch (get_current_el_maybe_constant()) {
+ case 1:
+ enable_mmu_el1(flags);
+ break;
+ case 2:
+ enable_mmu_el2(flags);
+ break;
+ case 3:
+ enable_mmu_el3(flags);
+ break;
+ default:
+ panic();
+ }
+}
+
#else /* !__aarch64__ */
void enable_mmu_svc_mon(unsigned int flags)
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index b2259e5f3..bb6d18459 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -109,6 +109,7 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
{
uint64_t desc;
uint32_t mem_type;
+ uint32_t shareability_type;
/* Make sure that the granularity is fine enough to map this address. */
assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0U);
@@ -194,8 +195,16 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
desc |= xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
}
+ shareability_type = MT_SHAREABILITY(attr);
if (mem_type == MT_MEMORY) {
- desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH);
+ desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX);
+ if (shareability_type == MT_SHAREABILITY_NSH) {
+ desc |= LOWER_ATTRS(NSH);
+ } else if (shareability_type == MT_SHAREABILITY_OSH) {
+ desc |= LOWER_ATTRS(OSH);
+ } else {
+ desc |= LOWER_ATTRS(ISH);
+ }
/* Check if Branch Target Identification is enabled */
#if ENABLE_BTI
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 70ef39523..863470cf3 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -99,9 +99,6 @@ unsigned long long xlat_arch_get_max_supported_pa(void);
*/
bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
-/* Returns true if the data cache is enabled at the current EL. */
-bool is_dcache_enabled(void);
-
/*
* Returns minimum virtual address space size supported by the architecture
*/
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index 30babc63f..9fae7e917 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -472,7 +472,7 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
/*
* Sanity checks.
*/
- for (size_t i = 0U; i < pages_count; ++i) {
+ for (unsigned int i = 0U; i < pages_count; ++i) {
const uint64_t *entry;
uint64_t desc, attr_index;
unsigned int level;
@@ -497,8 +497,8 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
(level != XLAT_TABLE_LEVEL_MAX)) {
WARN("Address 0x%lx is not mapped at the right granularity.\n",
base_va);
- WARN("Granularity is 0x%llx, should be 0x%x.\n",
- (unsigned long long)XLAT_BLOCK_SIZE(level), PAGE_SIZE);
+ WARN("Granularity is 0x%lx, should be 0x%lx.\n",
+ XLAT_BLOCK_SIZE(level), PAGE_SIZE);
return -EINVAL;
}