--- linux-2.6.18.i686/arch/x86_64/mm/init-xen.c.orig	2010-07-16 15:00:33.874810000 -0700
+++ linux-2.6.18.i686/arch/x86_64/mm/init-xen.c	2010-07-16 15:24:12.324881000 -0700
@@ -568,17 +568,16 @@ void __init xen_init_pt(void)
 void __init extend_init_mapping(unsigned long tables_space)
 {
 	unsigned long va = __START_KERNEL_map;
-	unsigned long phys, addr, *pte_page;
+	unsigned long phys, addr, *pte_page, *pmd_page=NULL;
+	pud_t *pud;
 	pmd_t *pmd;
 	pte_t *pte, new_pte;
 	unsigned long *page = (unsigned long *)init_level4_pgt;
 
 	addr = page[pgd_index(va)];
 	addr_to_page(addr, page);
-	addr = page[pud_index(va)];
-	addr_to_page(addr, page);
 
-	/* Kill mapping of low 1MB. */
+	/* Kill low mappings */
 	while (va < (unsigned long)&_text) {
 		HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
 		va += PAGE_SIZE;
@@ -588,14 +587,25 @@ void __init extend_init_mapping(unsigned
 	while (va < (__START_KERNEL_map
 		     + (start_pfn << PAGE_SHIFT)
 		     + tables_space)) {
-		pmd = (pmd_t *)&page[pmd_index(va)];
+
+		pud = (pud_t *)&page[pud_index(va)];    /* get pud entry */
+		if (pud_none(*pud)) {
+			pmd_page = alloc_static_page(&phys);
+			early_make_page_readonly(
+				pmd_page, XENFEAT_writable_page_tables);
+			set_pud(pud, __pud(phys | _KERNPG_TABLE));
+		} else {
+			addr = page[pud_index(va)];
+			addr_to_page(addr, pmd_page);
+		}
+		pmd = (pmd_t *)&pmd_page[pmd_index(va)];
 		if (pmd_none(*pmd)) {
 			pte_page = alloc_static_page(&phys);
 			early_make_page_readonly(
 				pte_page, XENFEAT_writable_page_tables);
 			set_pmd(pmd, __pmd(phys | _KERNPG_TABLE));
 		} else {
-			addr = page[pmd_index(va)];
+			addr = pmd_page[pmd_index(va)];
 			addr_to_page(addr, pte_page);
 		}
 		pte = (pte_t *)&pte_page[pte_index(va)];
@@ -610,7 +620,7 @@ void __init extend_init_mapping(unsigned
 
 	/* Finally, blow away any spurious initial mappings. */
 	while (1) {
-		pmd = (pmd_t *)&page[pmd_index(va)];
+		pmd = (pmd_t *)&pmd_page[pmd_index(va)];
 		if (pmd_none(*pmd))
 			break;
 		HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
