[PATCH] uml: fixrange_init 3-level page table support

From: Al Viro - add three-level page table support to fixrange_init.

Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: <viro@parcelfarce.linux.theplanet.co.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Jeff Dike and committed by Linus Torvalds 12f49643 7b9014c1

+31 -9
+31 -9
arch/um/kernel/mem.c
··· 100 100 #endif 101 101 } 102 102 103 + /* 104 + * Create a page table and place a pointer to it in a middle page 105 + * directory entry. 106 + */ 107 + static void __init one_page_table_init(pmd_t *pmd) 108 + { 109 + if (pmd_none(*pmd)) { 110 + pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); 111 + set_pmd(pmd, __pmd(_KERNPG_TABLE + 112 + (unsigned long) __pa(pte))); 113 + if (pte != pte_offset_kernel(pmd, 0)) 114 + BUG(); 115 + } 116 + } 117 + 118 + static void __init one_md_table_init(pud_t *pud) 119 + { 120 + #ifdef CONFIG_3_LEVEL_PGTABLES 121 + pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); 122 + set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); 123 + if (pmd_table != pmd_offset(pud, 0)) 124 + BUG(); 125 + #endif 126 + } 127 + 103 128 static void __init fixrange_init(unsigned long start, unsigned long end, 104 129 pgd_t *pgd_base) 105 130 { 106 131 pgd_t *pgd; 132 + pud_t *pud; 107 133 pmd_t *pmd; 108 - pte_t *pte; 109 134 int i, j; 110 135 unsigned long vaddr; 111 136 ··· 140 115 pgd = pgd_base + i; 141 116 142 117 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { 143 - pmd = (pmd_t *)pgd; 118 + pud = pud_offset(pgd, vaddr); 119 + if (pud_none(*pud)) 120 + one_md_table_init(pud); 121 + pmd = pmd_offset(pud, vaddr); 144 122 for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { 145 - if (pmd_none(*pmd)) { 146 - pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); 147 - set_pmd(pmd, __pmd(_KERNPG_TABLE + 148 - (unsigned long) __pa(pte))); 149 - if (pte != pte_offset_kernel(pmd, 0)) 150 - BUG(); 151 - } 123 + one_page_table_init(pmd); 152 124 vaddr += PMD_SIZE; 153 125 } 154 126 j = 0;