aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/mem.c')
-rw-r--r--arch/um/kernel/mem.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index f156661781cb..c22825f13e40 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -100,12 +100,37 @@ void mem_init(void)
100#endif 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 */
107static 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
118static 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
103static void __init fixrange_init(unsigned long start, unsigned long end, 128static void __init fixrange_init(unsigned long start, unsigned long end,
104 pgd_t *pgd_base) 129 pgd_t *pgd_base)
105{ 130{
106 pgd_t *pgd; 131 pgd_t *pgd;
132 pud_t *pud;
107 pmd_t *pmd; 133 pmd_t *pmd;
108 pte_t *pte;
109 int i, j; 134 int i, j;
110 unsigned long vaddr; 135 unsigned long vaddr;
111 136
@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
115 pgd = pgd_base + i; 140 pgd = pgd_base + i;
116 141
117 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { 142 for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) {
118 pmd = (pmd_t *)pgd; 143 pud = pud_offset(pgd, vaddr);
144 if (pud_none(*pud))
145 one_md_table_init(pud);
146 pmd = pmd_offset(pud, vaddr);
119 for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { 147 for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) {
120 if (pmd_none(*pmd)) { 148 one_page_table_init(pmd);
121 pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
122 set_pmd(pmd, __pmd(_KERNPG_TABLE +
123 (unsigned long) __pa(pte)));
124 if (pte != pte_offset_kernel(pmd, 0))
125 BUG();
126 }
127 vaddr += PMD_SIZE; 149 vaddr += PMD_SIZE;
128 } 150 }
129 j = 0; 151 j = 0;