* H. Peter Anvin <hpa at zytor.com> wrote: > Fix crash on NUMA reported by Dhaval Giani (reported as being a kexec > issue.) here's the delta fix. Ingo Index: linux-x86.q/arch/x86/kernel/setup_32.c =================================================================== --- linux-x86.q.orig/arch/x86/kernel/setup_32.c +++ linux-x86.q/arch/x86/kernel/setup_32.c @@ -510,16 +510,20 @@ static void __init reserve_initrd(void) unsigned long end_of_lowmem = max_low_pfn << PAGE_SHIFT; unsigned long ramdisk_here; + initrd_start = 0; + + if (!boot_params.hdr.type_of_loader || + !ramdisk_image || !ramdisk_size) + return; /* No initrd provided by bootloader */ + if (ramdisk_end < ramdisk_image) { - printk(KERN_ERR "initrd wraps around end of memory\n" - KERN_ERR "disabling initrd\n"); - initrd_start = 0; + printk(KERN_ERR "initrd wraps around end of memory, " + "disabling initrd\n"); return; } if (ramdisk_size >= end_of_lowmem/2) { - printk(KERN_ERR "initrd too large to handle\n" - KERN_ERR "disabling initrd\n"); - initrd_start = 0; + printk(KERN_ERR "initrd too large to handle, " + "disabling initrd\n"); return; } if (ramdisk_end <= end_of_lowmem) { @@ -554,9 +558,10 @@ static void __init relocate_initrd(void) char *p, *q; if (!do_relocate_initrd) - return; /* Nothing to do here... */ + return; ramdisk_here = initrd_start - PAGE_OFFSET; + q = (char *)initrd_start; /* Copy any lowmem portion of the initrd */ @@ -642,11 +647,10 @@ void __init setup_bootmem_allocator(void */ find_smp_config(); #endif - numa_kva_reserve(); #ifdef CONFIG_BLK_DEV_INITRD - if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) - reserve_initrd(); + reserve_initrd(); #endif + numa_kva_reserve(); reserve_crashkernel(); } @@ -799,12 +803,13 @@ void __init setup_arch(char **cmdline_p) /* * NOTE: at this point the bootmem allocator is fully available. */ - paravirt_post_allocator_init(); #ifdef CONFIG_BLK_DEV_INITRD relocate_initrd(); #endif + paravirt_post_allocator_init(); + dmi_scan_machine(); io_delay_init(); Index: linux-x86.q/arch/x86/mm/discontig_32.c =================================================================== --- linux-x86.q.orig/arch/x86/mm/discontig_32.c +++ linux-x86.q/arch/x86/mm/discontig_32.c @@ -288,8 +288,8 @@ unsigned long __init setup_memory(void) #ifdef CONFIG_BLK_DEV_INITRD /* Numa kva area is below the initrd */ - if (boot_params.hdr.type_of_loader && boot_params.hdr.ramdisk_image) - kva_start_pfn = PFN_DOWN(boot_params.hdr.ramdisk_image) + if (initrd_start) + kva_start_pfn = PFN_DOWN(initrd_start - PAGE_OFFSET) - kva_pages; #endif kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1);