From: Rouven Czerwinski <r.czerwinski@xxxxxxxxxxxxxx> Like done for ARM64, use the reserved memory regions marked in the SDRAM bank to map these regions uncached and eXecute Never to avoid speculative access into these regions from causing hard-to-debug data aborts. Unlike with mmu_64, for CONFIG_MMU_EARLY systems, the MMU isn't turned off before changing the page table. So what we do instead is allocating a 16K shadow buffer and modifying that and afterwards overwriting the active TTB with it. We could instead use set_ttbr() to move the page table, but in interest of minimizing chance of breaking older ARM platforms, we keep the online changing of the entries for now. Signed-off-by: Rouven Czerwinski <r.czerwinski@xxxxxxxxxxxxxx> [afa: use SDRAM regions instead of FDT reserve entries] Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- arch/arm/cpu/mmu.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 6388e1bf14f6..f9c629c0f19d 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -413,6 +413,7 @@ static void vectors_init(void) void __mmu_init(bool mmu_on) { struct memory_bank *bank; + void *oldttb = NULL; arm_set_cache_functions(); @@ -430,15 +431,17 @@ void __mmu_init(bool mmu_on) pte_flags_uncached = PTE_FLAGS_UNCACHED_V4; } + ttb = xmemalign(ARM_TTB_SIZE, ARM_TTB_SIZE); + + /* + * Early MMU code may have already enabled the MMU. We assume a + * flat 1:1 section mapping in this case. + */ if (mmu_on) { - /* - * Early MMU code has already enabled the MMU. We assume a - * flat 1:1 section mapping in this case. - */ - /* Clear unpredictable bits [13:0] */ - ttb = (uint32_t *)(get_ttbr() & ~0x3fff); + oldttb = (uint32_t *)(get_ttbr() & ~0x3fff); + memcpy(ttb, oldttb, ARM_TTB_SIZE); - if (!request_sdram_region("ttb", (unsigned long)ttb, SZ_16K)) + if (!request_sdram_region("ttb", (unsigned long)oldttb, SZ_16K)) /* * This can mean that: * - the early MMU code has put the ttb into a place @@ -447,10 +450,8 @@ void __mmu_init(bool mmu_on) * the ttb will get corrupted. */ pr_crit("Critical Error: Can't request SDRAM region for ttb at %p\n", - ttb); + oldttb); } else { - ttb = xmemalign(ARM_TTB_SIZE, ARM_TTB_SIZE); - set_ttbr(ttb); /* For the XN bit to take effect, we can't be using DOMAIN_MANAGER. */ @@ -468,11 +469,28 @@ void __mmu_init(bool mmu_on) vectors_init(); for_each_memory_bank(bank) { + struct resource *rsv; + create_sections(ttb, bank->start, bank->start + bank->size - 1, PMD_SECT_DEF_CACHED); - __mmu_cache_flush(); + + for_each_reserved_region(bank, rsv) { + create_sections(ttb, resource_first_page(rsv), + resource_count_pages(rsv), + attrs_uncached_mem()); + } } + /* + * We could set_ttbr(ttb) here instead and save on the copy, but + * for now we play it safe, so we don't mess with the older ARMs. + */ + if (oldttb) { + memcpy(oldttb, ttb, ARM_TTB_SIZE); + free(ttb); + } + + __mmu_cache_flush(); __mmu_cache_on(); } -- 2.30.2