summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMatthew Ellis <Matthew.Ellis@arm.com>2026-08-04 12:11:17 +0100
committerMatthew Ellis <Matthew.Ellis@arm.com>2026-08-17 17:31:33 +0100
commitdf90255531e29e9a4d0b2def77217edc4694ea2c (patch)
tree607b091341a0db8897e8a4f531728650dad9dace /lib
parentc4e0b993bf8dbda44b42ff6df063872de703340c (diff)
downloadarm-trusted-firmware-df90255531e29e9a4d0b2def77217edc4694ea2c.tar.gz
arm-trusted-firmware-df90255531e29e9a4d0b2def77217edc4694ea2c.zip
docs(xlat): add erratum 3683289 comments
C1 Ultra erratum 3683289 can be triggered when software managing translation tables misprograms the contiguous hint, or replaces an existing block mapping with a different mapping without following break-before-make and TLB invalidation requirements. Add comments to the xlat v2 code documenting the invariants that prevent those conditions in TF-A: - xlat v2 does not set the contiguous hint. - dynamic mappings only create entries where the descriptor is invalid. - dynamic mappings do not overwrite existing block/page descriptors. - unmap and attribute-change paths invalidate descriptors before TLB invalidation, with the attribute-change path using break-before-make. This is documentation only; no C1 Ultra-specific workaround is required. SDEN documentation: https://support.arm.com/documentation/111077/latest Change-Id: Idb4a6f864967b25b5187dd882fb47abfa2bc4605 Signed-off-by: Matthew Ellis <Matthew.Ellis@arm.com> LTS-candidate: yes
Diffstat (limited to 'lib')
-rw-r--r--lib/cpus/aarch64/c1_ultra.S4
-rw-r--r--lib/xlat_tables_v2/xlat_tables_core.c24
-rw-r--r--lib/xlat_tables_v2/xlat_tables_utils.c6
3 files changed, 30 insertions, 4 deletions
diff --git a/lib/cpus/aarch64/c1_ultra.S b/lib/cpus/aarch64/c1_ultra.S
index e593bc4dd..d112fb470 100644
--- a/lib/cpus/aarch64/c1_ultra.S
+++ b/lib/cpus/aarch64/c1_ultra.S
@@ -41,6 +41,10 @@ check_erratum_ls c1_ultra, ERRATUM(3502731), CPU_REV(0, 0)
add_erratum_entry c1_ultra, ERRATUM(3658374), ERRATA_C1ULTRA_3658374
check_erratum_ls c1_ultra, ERRATUM(3658374), CPU_REV(1, 0)
+/* Erratum avoided by the generic implementation in lib/xlat_tables_v2. */
+add_erratum_entry c1_ultra, ERRATUM(3683289), ERRATUM_ALWAYS_CHOSEN
+check_erratum_ls c1_ultra, ERRATUM(3683289), CPU_REV(1, 0)
+
workaround_reset_start c1_ultra, ERRATUM(3684152), ERRATA_C1ULTRA_3684152
sysreg_bitfield_insert C1_ULTRA_IMP_CPUACTLR_EL1, C1_ULTRA_IMP_CPUACTLR_EL1_LOAD_BIT, \
C1_ULTRA_IMP_CPUACTLR_EL1_LOAD_SHIFT, C1_ULTRA_IMP_CPUACTLR_EL1_LOAD_WIDTH
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index ae7ad891f..023b7c890 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2025, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2026, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -120,6 +120,10 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
/*
* There are different translation table descriptors for level 3 and the
* rest.
+ *
+ * Keep descriptors independent. This library does not set the
+ * contiguous hint, which avoids one of the conditions described by
+ * C1 Ultra erratum 3683289.
*/
desc |= (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC : BLOCK_DESC;
/*
@@ -387,6 +391,11 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
if (action == ACTION_WRITE_BLOCK_ENTRY) {
+ /*
+ * Remove the mapping before invalidating the TLB entry.
+ * Keeping this ordering avoids the stale-translation
+ * condition described by C1 Ultra erratum 3683289.
+ */
table_base[table_idx] = INVALID_DESC;
xlat_arch_tlbi_va(table_idx_va, ctx->xlat_regime);
@@ -406,6 +415,10 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
* If the subtable is now empty, remove its reference.
*/
if (xlat_table_is_empty(ctx, subtable)) {
+ /*
+ * Remove the table reference before invalidating
+ * the TLB entry, as above.
+ */
table_base[table_idx] = INVALID_DESC;
xlat_arch_tlbi_va(table_idx_va,
ctx->xlat_regime);
@@ -487,6 +500,11 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
* There's nothing mapped here, create a new
* entry.
*
+ * Dynamic mappings must not replace an existing
+ * block/page descriptor. Mapping only invalid
+ * entries avoids the block-size replacement
+ * condition described by C1 Ultra erratum 3683289.
+ *
* Check if the destination granularity allows
* us to use a block descriptor or we need a
* finer table for it.
@@ -505,7 +523,9 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
} else {
/*
* There's another region mapped here, don't
- * overwrite.
+ * overwrite. In particular, do not replace an
+ * existing block descriptor with a different
+ * block/page mapping without break-before-make.
*/
assert(desc_type == BLOCK_DESC);
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index fc186e5c4..582019071 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-2025, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2026, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -600,7 +600,9 @@ int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
/*
* The break-before-make sequence requires writing an invalid
* descriptor and making sure that the system sees the change
- * before writing the new descriptor.
+ * before writing the new descriptor. This is the ordering
+ * required to avoid the stale-translation condition described
+ * by C1 Ultra erratum 3683289.
*/
*entry = INVALID_DESC;
#if !HW_ASSISTED_COHERENCY