[PATCH v2 06/10] ARM: mmu64: map reserved regions uncached

Ahmad Fatoum a.fatoum at pengutronix.de
Wed Aug 17 04:42:40 PDT 2022


Now that we have reserved memory regions specially marked in the SDRAM
bank requests, we can use this information to map these regions
uncached and eXecute Never to avoid speculative access into these
regions from causing hard-to-debug data aborts.

The sequence used here is safe because __mmu_init turns off the MMU if
enabled, so even if we overwrite early MMU uncached entries they are
without effect until the MMU is turned on again, by which time the
for_each_reserved_region should have disabled caching for them again
(e.g. because they were listed in DT as /reserve-memory).

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm/cpu/mmu-common.h | 15 +++++++++++++++
 arch/arm/cpu/mmu_64.c     | 10 +++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch/arm/cpu/mmu-common.h b/arch/arm/cpu/mmu-common.h
index ed7d5bc3168f..c9ea2c122857 100644
--- a/arch/arm/cpu/mmu-common.h
+++ b/arch/arm/cpu/mmu-common.h
@@ -3,6 +3,11 @@
 #ifndef __ARM_MMU_COMMON_H
 #define __ARM_MMU_COMMON_H
 
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/sizes.h>
+
 void dma_inv_range(void *ptr, size_t size);
 void dma_flush_range(void *ptr, size_t size);
 void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags);
@@ -19,4 +24,14 @@ static inline void arm_mmu_not_initialized_error(void)
 	panic("MMU not initialized\n");
 }
 
+static inline size_t resource_first_page(const struct resource *res)
+{
+	return ALIGN_DOWN(res->start, SZ_4K);
+}
+
+static inline size_t resource_count_pages(const struct resource *res)
+{
+	return ALIGN(resource_size(res), SZ_4K);
+}
+
 #endif
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index 06049e000375..f43ac9a12186 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -201,9 +201,17 @@ void __mmu_init(bool mmu_on)
 	create_sections(0, 0, 1UL << (BITS_PER_VA - 1), attrs_uncached_mem());
 
 	/* Map sdram cached. */
-	for_each_memory_bank(bank)
+	for_each_memory_bank(bank) {
+		struct resource *rsv;
+
 		create_sections(bank->start, bank->start, bank->size, CACHED_MEM);
 
+		for_each_reserved_region(bank, rsv) {
+			create_sections(resource_first_page(rsv), resource_first_page(rsv),
+					resource_count_pages(rsv), attrs_uncached_mem());
+		}
+	}
+
 	/* Make zero page faulting to catch NULL pointer derefs */
 	zero_page_faulting();
 
-- 
2.30.2




More information about the barebox mailing list