ChangeSet 1.2229.1.18, 2005/04/04 07:38:58-07:00, [EMAIL PROTECTED]

        [PATCH] ppc64: Fix boot memory corruption
        
        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 <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 prom.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletion(-)


diff -Nru a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
--- a/arch/ppc64/kernel/prom.c  2005-04-04 08:17:19 -07:00
+++ b/arch/ppc64/kernel/prom.c  2005-04-04 08:17:19 -07:00
@@ -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);
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to