---
 arch/x86/mm/init.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

Index: linux-2.6/arch/x86/mm/init.c
===================================================================
--- linux-2.6.orig/arch/x86/mm/init.c
+++ linux-2.6/arch/x86/mm/init.c
@@ -359,6 +359,39 @@ unsigned long __init_refok init_memory_m
 	return ret >> PAGE_SHIFT;
 }
 
+static long __init early_init_memory_mapping(unsigned long start,
+					       unsigned long end)
+{
+	unsigned long ret;
+	unsigned long tables, good_end;
+
+	pr_info("init_memory_mapping: [mem %#010lx-%#010lx]\n",
+	       start, end - 1);
+
+	tables = calculate_table_space_size(start, end);
+	good_end = ISA_END_ADDRESS;
+
+	find_early_table_space(0, good_end, tables);
+
+	printk(KERN_DEBUG "kernel direct mapping tables from %#lx to %#lx @ [mem %#010lx-%#010lx] prealloc\n",
+		start, end - 1, pgt_buf_start << PAGE_SHIFT,
+		(pgt_buf_top << PAGE_SHIFT) - 1);
+
+	ret = init_memory_mapping(start, end);
+
+	if (pgt_buf_end > pgt_buf_start) {
+		printk(KERN_DEBUG "kernel direct mapping tables from %#lx to %#lx @ [mem %#010lx-%#010lx] final\n",
+			start, end - 1, pgt_buf_start << PAGE_SHIFT,
+			(pgt_buf_end << PAGE_SHIFT) - 1);
+		x86_init.mapping.pagetable_reserve(PFN_PHYS(pgt_buf_start),
+				PFN_PHYS(pgt_buf_end));
+	}
+
+	early_memtest(start, end);
+
+	return ret;
+}
+
 /*
  * Iterate through E820 memory map and create direct mappings for only E820_RAM
  * regions. We cannot simply create direct mappings for all pfns from
@@ -395,6 +428,20 @@ void __init init_mem_mapping(void)
 #endif
 	walk_ram_ranges(size_work_fn, &tables);
 	find_early_table_space(0, good_end, tables);
+
+	if (pgt_buf_top >= max_pfn_mapped) {
+		unsigned long old_pgt_buf_start = pgt_buf_start;
+		unsigned long old_pgt_buf_end = pgt_buf_end;
+		unsigned long old_pgt_buf_top = pgt_buf_top;
+
+		early_init_memory_mapping(old_pgt_buf_start << PAGE_SHIFT,
+					  old_pgt_buf_top << PAGE_SHIFT);
+
+		pgt_buf_start = old_pgt_buf_start;
+		pgt_buf_end = old_pgt_buf_end;
+		pgt_buf_top = old_pgt_buf_top;
+	}
+
 	printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx] prealloc\n",
 		end - 1, pgt_buf_start << PAGE_SHIFT,
 		(pgt_buf_top << PAGE_SHIFT) - 1);
