Index: linux-2.6.18-mm3/arch/x86_64/Kconfig =================================================================== --- linux-2.6.18-mm3.orig/arch/x86_64/Kconfig 2006-10-04 21:39:45.000000000 -0700 +++ linux-2.6.18-mm3/arch/x86_64/Kconfig 2006-10-04 21:41:32.000000000 -0700 @@ -105,6 +105,10 @@ default y depends on BUG +config VIRTUAL_MEM_MAP + bool + default y + source "init/Kconfig" @@ -362,10 +366,6 @@ def_bool y depends on NUMA -config ARCH_SPARSEMEM_ENABLE - def_bool y - depends on (NUMA || EXPERIMENTAL) - config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG Index: linux-2.6.18-mm3/arch/x86_64/mm/init.c =================================================================== --- linux-2.6.18-mm3.orig/arch/x86_64/mm/init.c 2006-10-04 21:43:10.000000000 -0700 +++ linux-2.6.18-mm3/arch/x86_64/mm/init.c 2006-10-04 22:06:41.000000000 -0700 @@ -567,6 +567,10 @@ datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; +#ifdef CONFIG_VIRTUAL_MEM_MAP + mem_map = (struct page *)VMEMMAP_START; + max_mapnr = MAX_MEM >> PAGE_SIZE; +#endif /* Register memory areas for /proc/kcore */ kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, Index: linux-2.6.18-mm3/arch/x86_64/mm/numa.c =================================================================== --- linux-2.6.18-mm3.orig/arch/x86_64/mm/numa.c 2006-10-04 21:41:40.000000000 -0700 +++ linux-2.6.18-mm3/arch/x86_64/mm/numa.c 2006-10-04 22:08:36.000000000 -0700 @@ -93,13 +93,6 @@ return shift; } -#ifdef CONFIG_SPARSEMEM -int early_pfn_to_nid(unsigned long pfn) -{ - return phys_to_nid(pfn << PAGE_SHIFT); -} -#endif - static void * __init early_node_mem(int nodeid, unsigned long start, unsigned long end, unsigned long size) @@ -174,6 +167,7 @@ /* Initialize final allocator for a zone */ void __init setup_node_zones(int nodeid) { +#ifndef CONFIG_VIRTUAL_MEM_MAP unsigned long start_pfn, end_pfn, memmapsize, limit; start_pfn = node_start_pfn(nodeid); @@ -193,6 +187,7 @@ round_down(limit - memmapsize, PAGE_SIZE), limit); #endif +#endif } void __init numa_init_array(void) @@ -321,33 +316,17 @@ return pages; } -#ifdef CONFIG_SPARSEMEM -static void __init arch_sparse_init(void) -{ - int i; - - for_each_online_node(i) - memory_present(i, node_start_pfn(i), node_end_pfn(i)); - - sparse_init(); -} -#else -#define arch_sparse_init() do {} while (0) -#endif - void __init paging_init(void) { int i; unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN, MAX_DMA32_PFN, end_pfn}; - - arch_sparse_init(); - +#ifndef CONFIG_VIRTUAL_MEM_MAP for_each_online_node(i) { setup_node_zones(i); } - +#endif free_area_init_nodes(max_zone_pfns); } Index: linux-2.6.18-mm3/include/asm-x86_64/pgtable.h =================================================================== --- linux-2.6.18-mm3.orig/include/asm-x86_64/pgtable.h 2006-10-04 21:33:44.000000000 -0700 +++ linux-2.6.18-mm3/include/asm-x86_64/pgtable.h 2006-10-04 21:38:10.000000000 -0700 @@ -130,7 +130,12 @@ #ifndef __ASSEMBLY__ #define MAXMEM 0x3fffffffffffUL +#define VMEMMAP_START 0xffff000000000000UL +#define VMMEMAP_SIZE (MAX_MEM << PAGE_SIZE * sizeof(struct page)) #define VMALLOC_START 0xffffc20000000000UL +#if (VMALLOC_START > VMMEMAP_START + VMEMMAP_START) +#error Virtual mem_map reaches into VMALLOC area +#endif #define VMALLOC_END 0xffffe1ffffffffffUL #define MODULES_VADDR 0xffffffff88000000UL #define MODULES_END 0xfffffffffff00000UL Index: linux-2.6.18-mm3/mm/page_alloc.c =================================================================== --- linux-2.6.18-mm3.orig/mm/page_alloc.c 2006-10-04 22:11:03.000000000 -0700 +++ linux-2.6.18-mm3/mm/page_alloc.c 2006-10-04 22:14:36.000000000 -0700 @@ -2540,7 +2540,7 @@ if (!pgdat->node_spanned_pages) return; -#ifdef CONFIG_FLAT_NODE_MEM_MAP +#if defined(CONFIG_FLAT_NODE_MEM_MAP) && !defined(CONFIG_VIRTUAL_MEM_MAP) /* ia64 gets its own node_mem_map, before this, without bootmem */ if (!pgdat->node_mem_map) { unsigned long size, start, end; @@ -2560,7 +2560,7 @@ map = alloc_bootmem_node(pgdat, size); pgdat->node_mem_map = map + (pgdat->node_start_pfn - start); } -#ifdef CONFIG_FLATMEM +#if defined(CONFIG_FLATMEM) && !defined(CONFIG_VIRTUAL_MEM_MAP) /* * With no DISCONTIG, the global mem_map is just set as node 0's */