[coreboot-gerrit] New patch to review for coreboot: arch/arm64: mmu: Spot check TTB memory attributes

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Thu Feb 4 11:16:07 CET 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13595

-gerrit

commit fb5f1284831ccba9ebcd37231a9c95705cc5b58c
Author: Julius Werner <jwerner at chromium.org>
Date:   Tue Jan 26 19:17:53 2016 -0800

    arch/arm64: mmu: Spot check TTB memory attributes
    
    On ARM64, the memory type for accessing page table descriptors during
    address translation is governed by the Translation Control Register
    (TCR). When the MMU code accesses the same descriptors to change page
    mappings, it uses the standard memory type rules (defined by the page
    table descriptor for the page that contains that table, or 'device' if
    the MMU is off).
    
    Accessing the same memory with different memory types can lead to all
    kinds of fun and hard to debug effects. In particular, if the TCR says
    "cacheable" and the page tables say "uncacheable", page table walks will
    pull stale entries into the cache and later mmu_config_range() calls
    will write directly to memory, bypassing those cache lines. This means
    the translations will not get updated even after a TLB flush, and later
    cache flushes/evictions may write the stale entries back to memory.
    
    Since page table configuration is currently always done from SoC code,
    we can't generally ensure that the TTB is always mapped as cacheable.
    We can however save developers of future SoCs a lot of headaches and
    time by spot checking the attributes when the MMU gets enabled, as this
    patch does.
    
    BRANCH=None
    BUG=None
    TEST=Booted Oak. Manually tested get_pte() with a few addresses.
    
    Change-Id: I3afd29dece848c4b5f759ce2f00ca2b7433374da
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: f3947f4bb0abf4466006d5e3a962bbcb8919b12d
    Original-Change-Id: I1008883e5ed4cc37d30cae5777a60287d3d01af0
    Original-Signed-off-by: Julius Werner <jwerner at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/323862
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/arch/arm64/armv8/mmu.c              | 26 ++++++++++++++++++++++++++
 src/arch/arm64/include/armv8/arch/mmu.h |  1 +
 2 files changed, 27 insertions(+)

diff --git a/src/arch/arm64/armv8/mmu.c b/src/arch/arm64/armv8/mmu.c
index 5d957d4..9280fc2 100644
--- a/src/arch/arm64/armv8/mmu.c
+++ b/src/arch/arm64/armv8/mmu.c
@@ -199,6 +199,26 @@ static void sanity_check(uint64_t addr, uint64_t size)
 	       size >= GRANULE_SIZE);
 }
 
+/* Func : get_pte
+ * Desc : Returns the page table entry governing a specific address. */
+static uint64_t get_pte(void *addr)
+{
+	int shift = BITS_PER_VA > L1_ADDR_SHIFT ? L1_ADDR_SHIFT : L2_ADDR_SHIFT;
+	uint64_t *pte = (uint64_t *)_ttb;
+
+	while (1) {
+		int index = ((uintptr_t)addr >> shift) &
+			    ((1UL << BITS_RESOLVED_PER_LVL) - 1);
+
+		if ((pte[index] & DESC_MASK) != TABLE_DESC ||
+		    shift <= GRANULE_SIZE_SHIFT)
+			return pte[index];
+
+		pte = (uint64_t *)(pte[index] & XLAT_ADDR_MASK);
+		shift -= BITS_RESOLVED_PER_LVL;
+	}
+}
+
 /* Func : mmu_config_range
  * Desc : This function repeatedly calls init_xlat_table with the base
  * address. Based on size returned from init_xlat_table, base_addr is updated
@@ -256,6 +276,12 @@ void mmu_init(void)
 
 void mmu_enable(void)
 {
+	if (((get_pte(_ttb) >> BLOCK_INDEX_SHIFT) & BLOCK_INDEX_MASK)
+	    != BLOCK_INDEX_MEM_NORMAL ||
+	    ((get_pte(_ettb - 1) >> BLOCK_INDEX_SHIFT) & BLOCK_INDEX_MASK)
+	    != BLOCK_INDEX_MEM_NORMAL)
+		die("TTB memory type must match TCR (normal, cacheable)!");
+
 	uint32_t sctlr = raw_read_sctlr_el3();
 	sctlr |= SCTLR_C | SCTLR_M | SCTLR_I;
 	raw_write_sctlr_el3(sctlr);
diff --git a/src/arch/arm64/include/armv8/arch/mmu.h b/src/arch/arm64/include/armv8/arch/mmu.h
index 7c3b6a7..a812073 100644
--- a/src/arch/arm64/include/armv8/arch/mmu.h
+++ b/src/arch/arm64/include/armv8/arch/mmu.h
@@ -102,6 +102,7 @@
 #define BLOCK_INDEX_MEM_NORMAL_NC  3
 #define BLOCK_INDEX_MEM_NORMAL     4
 
+#define BLOCK_INDEX_MASK           0x7
 #define BLOCK_INDEX_SHIFT          2
 
 /* MAIR attributes */



More information about the coreboot-gerrit mailing list