[PATCH] ppc64: Fix boot memory corruption

Benjamin Herrenschmidt benh at kernel.crashing.org
Sun Apr 3 11:16:28 EST 2005


Hi !

Nathan's patch "make OF node fixup code usable at runtim" is introducing
a snaky bug. We do 2 passes over this code, one to measure how much
memory will be needed so we can allocate a single block, and one to do
the actual fixup. However, the new code does some result-checking of
prom_alloc() which breaks this mecanism, as the first pass always starts
at "0", thus we fail to measure the additional size properly and
allocate a block smaller than what we'll actually use for the fixup.
This cause us to override whatever sits there, with variable results
depending on the memory layout of the machine (but typically crashes).

This patch fixes it by starting the "measure" pass with an initial size
set to 16 and not 0.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>

Index: linux-work/arch/ppc64/kernel/prom.c
===================================================================
--- linux-work.orig/arch/ppc64/kernel/prom.c	2005-04-03 10:02:55.000000000 +1000
+++ linux-work/arch/ppc64/kernel/prom.c	2005-04-03 11:08:18.000000000 +1000
@@ -601,8 +601,19 @@
 	/* Initialize virtual IRQ map */
 	virt_irq_init();
 
-	/* Finish device-tree (pre-parsing some properties etc...) */
+	/*
+	 * Finish device-tree (pre-parsing some properties etc...)
+	 * We do this in 2 passes. One with "measure_only" set, which
+	 * will only measure the amount of memory needed, then we can
+	 * allocate that memory, and call finish_node again. However,
+	 * we must be careful as most routines will fail nowadays when
+	 * prom_alloc() returns 0, so we must make sure our first pass
+	 * doesn't start at 0. We pre-initialize size to 16 for that
+	 * reason and then remove those additional 16 bytes
+	 */
+	size = 16;
 	finish_node(allnodes, &size, NULL, 0, 0, 1);
+	size -= 16;
 	end = start = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
 	finish_node(allnodes, &end, NULL, 0, 0, 0);
 	BUG_ON(end != start + size);





More information about the Linuxppc64-dev mailing list