diff options
Diffstat (limited to 'arch/um/kernel/mem.c')
| -rw-r--r-- | arch/um/kernel/mem.c | 40 | 
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 | */ | ||
| 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 | static void __init fixrange_init(unsigned long start, unsigned long end, | 128 | static 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; | 
