mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [PATCH master 8/8] ARM: mmu: fix hang reserving memory after text area
Date: Tue,  5 Aug 2025 19:45:41 +0200	[thread overview]
Message-ID: <20250805174541.2606267-9-a.fatoum@barebox.org> (raw)
In-Reply-To: <20250805174541.2606267-1-a.fatoum@barebox.org>

The loop in mmu_remap_memory_banks first looks at reserved memory
regions and then maps everything eXecute Never up to the start of the
region. If the region happens to be in the same bank as the text area
and it comes after it, this means the text area is temporarily mapped
eXecute Never, while barebox is running from it, which results in a
hang.

Fix this by remapping only after both reserved memory regions and text
area have been considered.

Fixes: 5916385fae83 ("ARM: MMU: map text segment ro and data segments execute never")
Fixes: 03dfb3f142fb ("ARM: MMU64: map text segment ro and data segments execute never")
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
 arch/arm/cpu/mmu-common.c | 51 ++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/arch/arm/cpu/mmu-common.c b/arch/arm/cpu/mmu-common.c
index 575fb32282d1..1de20d931876 100644
--- a/arch/arm/cpu/mmu-common.c
+++ b/arch/arm/cpu/mmu-common.c
@@ -70,21 +70,50 @@ void zero_page_faulting(void)
 	remap_range(0x0, PAGE_SIZE, MAP_FAULT);
 }
 
+/**
+ * remap_range_end - remap a range identified by [start, end)
+ *
+ * @start:    start of the range
+ * @end:      end of the first range (exclusive)
+ * @map_type: mapping type to apply
+ */
+static inline void remap_range_end(unsigned long start, unsigned long end,
+				   unsigned map_type)
+{
+	remap_range((void *)start, end - start, map_type);
+}
+
+static inline void remap_range_end_sans_text(unsigned long start, unsigned long end,
+					     unsigned map_type)
+{
+	unsigned long text_start = (unsigned long)&_stext;
+	unsigned long text_end = (unsigned long)&_etext;
+
+	if (region_overlap_end_exclusive(start, end, text_start, text_end)) {
+		remap_range_end(start, text_start, MAP_CACHED);
+		/* skip barebox segments here, will be mapped later */
+		start = text_end;
+	}
+
+	remap_range_end(start, end, MAP_CACHED);
+}
+
 static void mmu_remap_memory_banks(void)
 {
 	struct memory_bank *bank;
-	unsigned long text_start = (unsigned long)&_stext;
-	unsigned long code_start = text_start;
+	unsigned long code_start = (unsigned long)&_stext;
 	unsigned long code_size = (unsigned long)&__start_rodata - (unsigned long)&_stext;
-	unsigned long text_size = (unsigned long)&_etext - text_start;
 	unsigned long rodata_start = (unsigned long)&__start_rodata;
 	unsigned long rodata_size = (unsigned long)&__end_rodata - rodata_start;
 
 	/*
 	 * Early mmu init will have mapped everything but the initial memory area
 	 * (excluding final OPTEE_SIZE bytes) uncached. We have now discovered
-	 * all memory banks, so let's map all pages, excluding reserved memory areas,
-	 * cacheable and executable.
+	 * all memory banks, so let's map all pages, excluding reserved memory areas
+	 * and barebox text area cacheable.
+	 *
+	 * This code will become much less complex once we switch over to using
+	 * CONFIG_MEMORY_ATTRIBUTES for MMU as well.
 	 */
 	for_each_memory_bank(bank) {
 		struct resource *rsv;
@@ -94,20 +123,14 @@ static void mmu_remap_memory_banks(void)
 
 		/* Skip reserved regions */
 		for_each_reserved_region(bank, rsv) {
-			remap_range((void *)pos, rsv->start - pos, MAP_CACHED);
+			remap_range_end_sans_text(pos, rsv->start, MAP_CACHED);
 			pos = rsv->end + 1;
 		}
 
-		if (region_overlap_size(pos, bank->start + bank->size - pos,
-		    text_start, text_size)) {
-			remap_range((void *)pos, text_start - pos, MAP_CACHED);
-			/* skip barebox segments here, will be mapped below */
-			pos = text_start + text_size;
-		}
-
-		remap_range((void *)pos, bank->start + bank->size - pos, MAP_CACHED);
+		remap_range_end_sans_text(pos, bank->start + bank->size, MAP_CACHED);
 	}
 
+	/* Do this while interrupt vectors are still writable */
 	setup_trap_pages();
 
 	remap_range((void *)code_start, code_size, MAP_CODE);
-- 
2.39.5




  parent reply	other threads:[~2025-08-05 18:37 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-05 17:45 [PATCH master 0/8] " Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 1/8] partition: rename region_overlap_end to region_overlap_end_inclusive Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 2/8] partition: define new region_overlap_end_exclusive helper Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 3/8] ARM: mmu: skip TLB invalidation if remapping zero bytes Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 4/8] ARM64: mmu: pass map type not PTE flags to early_remap_range Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 5/8] ARM: mmu: provide setup_trap_pages for both 32- and 64-bit Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 6/8] ARM: mmu: setup trap pages before remapping R/O Ahmad Fatoum
2025-08-05 17:45 ` [PATCH master 7/8] ARM: mmu: share common memory bank remapping code Ahmad Fatoum
2025-08-05 17:45 ` Ahmad Fatoum [this message]
2025-08-06  6:31 ` [PATCH master 0/8] ARM: mmu: fix hang reserving memory after text area Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250805174541.2606267-9-a.fatoum@barebox.org \
    --to=a.fatoum@barebox.org \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox