Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=23be8c7ddf4fd31a14579a2109c89845f7a0fbb6
Commit:     23be8c7ddf4fd31a14579a2109c89845f7a0fbb6
Parent:     5d5d80001df3fbd06bd2b8893b6e3847e38a12d6
Author:     Ingo Molnar <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 15 16:44:37 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Tue Jan 15 16:44:37 2008 +0100

    x86: fix boot crash on HIGHMEM4G && SPARSEMEM
    
    Denys Fedoryshchenko reported a bootup crash when he upgraded
    his system from 3GB to 4GB RAM:
    
       http://lkml.org/lkml/2008/1/7/9
    
    the bug is due to HIGHMEM4G && SPARSEMEM kernels making pfn_to_page()
    to return an invalid pointer when the pfn is in a memory hole. The
    256 MB PCI aperture at the end of RAM was not mapped by sparsemem,
    and hence the pfn was not valid. But set_highmem_pages_init() iterated
    this range without checking the pfn's validity first.
    
    this bug was probably present in the sparsemem code ever since sparsemem
    has been introduced in v2.6.13. It was masked due to HIGHMEM64G using
    larger memory regions in sparsemem_32.h:
    
     #ifdef CONFIG_X86_PAE
     #define SECTION_SIZE_BITS       30
     #define MAX_PHYSADDR_BITS       36
     #define MAX_PHYSMEM_BITS        36
     #else
     #define SECTION_SIZE_BITS       26
     #define MAX_PHYSADDR_BITS       32
     #define MAX_PHYSMEM_BITS        32
     #endif
    
    which creates 1GB sparsemem regions instead of 64MB sparsemem regions.
    So in practice we only ever created true sparsemem holes on x86 with
    HIGHMEM4G - but that was rarely used by distros.
    
    ( btw., we could probably save 2MB of mem_map[]s on X86_PAE if we reduced
      the sparsemem region size to 256 MB. )
    
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Acked-by: Thomas Gleixner <[EMAIL PROTECTED]>
---
 arch/x86/mm/init_32.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index c7d1947..3c76d19 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -321,8 +321,13 @@ extern void set_highmem_pages_init(int);
 static void __init set_highmem_pages_init(int bad_ppro)
 {
        int pfn;
-       for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
-               add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
+       for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) {
+               /*
+                * Holes under sparsemem might not have no mem_map[]:
+                */
+               if (pfn_valid(pfn))
+                       add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
+       }
        totalram_pages += totalhigh_pages;
 }
 #endif /* CONFIG_FLATMEM */
-
To unsubscribe from this list: send the line "unsubscribe git-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