Skip to contentSkip to conversation

sparc32: don't clear the nocache pool through the PROM mappings

PATCH Superseded Imre Kaloz 2 participants 3 messages Sep 27 – Sep 28

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore

Imre Kaloz

author
#0 lore raw

PATCH 1/1 sparc32: don't clear the nocache pool through the PROM mappings

srmmu_nocache_init() runs before the switch to srmmu_swapper_pg_dir, so lowmem is still reached through the PROM mappings the head code inherits for KERNBASE, which end at 10MB on a SPARCstation 20. The pool, up to 5MB and allocated right above the kernel, was cleared there twice, by memblock_alloc() and by the memset(). Once the kernel image ends above 5MB the clear runs past the PROM's window, faults, and the boot CPU enters error mode.

Every user of the pool clears what it allocates, so allocate the pool with memblock_alloc_raw(), after the bitmap so the bitmap lands below it.

This has been broken since 2.4.0-test2pre2.

---

Notes:
No Fixes: tag: this has been broken since 2.4.0-test2pre2, before the git history.

 arch/sparc/mm/srmmu.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
arch/sparc/mm/srmmu.c +13 -4
index 9a74902ad181..16d5cde4f949 100644
@@ -277,15 +277,24 @@ static void __init srmmu_nocache_init(void)
 
 	bitmap_bits = srmmu_nocache_size >> SRMMU_NOCACHE_BITMAP_SHIFT;
 
-	srmmu_nocache_pool = memblock_alloc_or_panic(srmmu_nocache_size,
-					    SRMMU_NOCACHE_ALIGN_MAX);
-	memset(srmmu_nocache_pool, 0, srmmu_nocache_size);
-
 	srmmu_nocache_bitmap =
 		memblock_alloc_or_panic(BITS_TO_LONGS(bitmap_bits) * sizeof(long),
 			       SMP_CACHE_BYTES);
 	bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits);
 
+	/*
+	 * Until the switch to srmmu_swapper_pg_dir, lowmem is only reachable
+	 * through the PROM's mappings, which may end below the top of the pool
+	 * (at 10MB on the SPARCstation 20). Allocate the pool after the bitmap
+	 * so the bitmap stays below it, and leave it uncleared: every user of
+	 * the pool clears what it allocates.
+	 */
+	srmmu_nocache_pool = memblock_alloc_raw(srmmu_nocache_size,
+						SRMMU_NOCACHE_ALIGN_MAX);
+	if (!srmmu_nocache_pool)
+		panic("%s: Failed to allocate %lu bytes\n", __func__,
+		      srmmu_nocache_size);
+
 	srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
 	memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE);
 	init_mm.pgd = srmmu_swapper_pg_dir;

base-commit: 62f4c998b297cf233997a2b4cd6fc2d2df0319c9

Signature · 1 line
2.47.3
#1 lore raw

Hi Imre,

Quoted 9 lines · Imre Kaloz

srmmu_nocache_init() runs before the switch to srmmu_swapper_pg_dir, so lowmem is still reached through the PROM mappings the head code inherits for KERNBASE, which end at 10MB on a SPARCstation 20. The pool, up to 5MB and allocated right above the kernel, was cleared there twice, by memblock_alloc() and by the memset(). Once the kernel image ends above 5MB the clear runs past the PROM's window, faults, and the boot CPU enters error mode.

Quoted 7 lines

Every user of the pool clears what it allocates, so allocate the pool with memblock_alloc_raw(), after the bitmap so the bitmap lands below it.

This has been broken since 2.4.0-test2pre2.

Very nice work, this makes a lot of sense.

For the record, an unpatched kernel
(carrying only the patch series needed to boot:)
https://lore.kernel.org/sparclinux/[email protected]/T/#t

boots fine here: SS-20, PROM 2.25R, 512MB, 6MB kernel image, nocache pool at its 1280-page cap. So the PROM window is not always small enough for this to bite. Happy to dig into what this machine actually maps and report back.

Magnus

Quoted 48 lines

---

Notes:
No Fixes: tag: this has been broken since 2.4.0-test2pre2, before the git history.

 arch/sparc/mm/srmmu.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
arch/sparc/mm/srmmu.c +13 -4
index 9a74902ad181..16d5cde4f949 100644
@@ -277,15 +277,24 @@ static void __init srmmu_nocache_init(void)
 
        bitmap_bits = srmmu_nocache_size >> SRMMU_NOCACHE_BITMAP_SHIFT;
 
-       srmmu_nocache_pool = memblock_alloc_or_panic(srmmu_nocache_size,
-                                           SRMMU_NOCACHE_ALIGN_MAX);
-       memset(srmmu_nocache_pool, 0, srmmu_nocache_size);
-
        srmmu_nocache_bitmap =
                memblock_alloc_or_panic(BITS_TO_LONGS(bitmap_bits) * sizeof(long),
                               SMP_CACHE_BYTES);
        bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits);
 
+       /*
+        * Until the switch to srmmu_swapper_pg_dir, lowmem is only reachable
+        * through the PROM's mappings, which may end below the top of the pool
+        * (at 10MB on the SPARCstation 20). Allocate the pool after the bitmap
+        * so the bitmap stays below it, and leave it uncleared: every user of
+        * the pool clears what it allocates.
+        */
+       srmmu_nocache_pool = memblock_alloc_raw(srmmu_nocache_size,
+                                               SRMMU_NOCACHE_ALIGN_MAX);
+       if (!srmmu_nocache_pool)
+               panic("%s: Failed to allocate %lu bytes\n", __func__,
+                     srmmu_nocache_size);
+
        srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
        memset(__nocache_fix(srmmu_swapper_pg_dir), 0, SRMMU_PGD_TABLE_SIZE);
        init_mm.pgd = srmmu_swapper_pg_dir;

base-commit: 62f4c998b297cf233997a2b4cd6fc2d2df0319c9 --
2.47.3

author
#2 lore raw

Hi Magnus,

Quoted 21 lines · Magnus Lindholm
Quoted 9 lines · Imre Kaloz

srmmu_nocache_init() runs before the switch to srmmu_swapper_pg_dir, so lowmem is still reached through the PROM mappings the head code inherits for KERNBASE, which end at 10MB on a SPARCstation 20. The pool, up to 5MB and allocated right above the kernel, was cleared there twice, by memblock_alloc() and by the memset(). Once the kernel image ends above 5MB the clear runs past the PROM's window, faults, and the boot CPU enters error mode.

Quoted 7 lines

Every user of the pool clears what it allocates, so allocate the pool with memblock_alloc_raw(), after the bitmap so the bitmap lands below it.

This has been broken since 2.4.0-test2pre2.

Very nice work, this makes a lot of sense.

Quoted 8 lines

For the record, an unpatched kernel
(carrying only the patch series needed to boot:)
https://lore.kernel.org/sparclinux/[email protected]/T/#t

boots fine here: SS-20, PROM 2.25R, 512MB, 6MB kernel image, nocache pool at its 1280-page cap. So the PROM window is not always small enough for this to bite. Happy to dig into what this machine actually maps and report back.

Thanks and looking forward to it :) I suspect your ROSS PROM behaves differently than my standard 2.25 here.

Best,
Imre