diff options
author | Jeff Dike <jdike@addtoit.com> | 2005-05-20 16:59:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-20 18:48:18 -0400 |
commit | 12f49643bc44c428919b210148a930496827dd26 (patch) | |
tree | 7a2a17f124a36cb498b3ce4f2b91568e086bb7ed /arch/um | |
parent | 7b9014c1da380384efe7752db38a0253a74d0238 (diff) |
[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>
Diffstat (limited to 'arch/um')
-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; |