diff options
author | Tejun Heo <tj@kernel.org> | 2009-02-23 21:57:21 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-02-23 21:57:21 -0500 |
commit | 458a3e644c3327be529393982e24277eda8f1ac7 (patch) | |
tree | f39bab1d54eeb222565c8d9086f2e4f645d97f58 /arch/x86 | |
parent | c0c0a29379b5848aec2e8f1c58d853d3cb7118b8 (diff) |
x86: update populate_extra_pte() and add populate_extra_pmd()
Impact: minor change to populate_extra_pte() and addition of pmd flavor
Update populate_extra_pte() to return pointer to the pte_t for the
specified address and add populate_extra_pmd() which only populates
till the pmd and returns pointer to the pmd entry for the address.
For 64bit, pud/pmd/pte fill functions are separated out from
set_pte_vaddr[_pud]() and used for set_pte_vaddr[_pud]() and
populate_extra_{pte|pmd}().
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/pgtable.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/setup_percpu.c | 7 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 13 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 75 |
4 files changed, 63 insertions, 35 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index dd91c2515c64..46312eb0d682 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -402,7 +402,8 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, | |||
402 | 402 | ||
403 | /* Install a pte for a particular vaddr in kernel space. */ | 403 | /* Install a pte for a particular vaddr in kernel space. */ |
404 | void set_pte_vaddr(unsigned long vaddr, pte_t pte); | 404 | void set_pte_vaddr(unsigned long vaddr, pte_t pte); |
405 | void populate_extra_pte(unsigned long vaddr); | 405 | pmd_t *populate_extra_pmd(unsigned long vaddr); |
406 | pte_t *populate_extra_pte(unsigned long vaddr); | ||
406 | 407 | ||
407 | #ifdef CONFIG_X86_32 | 408 | #ifdef CONFIG_X86_32 |
408 | extern void native_pagetable_setup_start(pgd_t *base); | 409 | extern void native_pagetable_setup_start(pgd_t *base); |
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 2dce43558217..671e6528a82d 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
@@ -41,6 +41,11 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = { | |||
41 | }; | 41 | }; |
42 | EXPORT_SYMBOL(__per_cpu_offset); | 42 | EXPORT_SYMBOL(__per_cpu_offset); |
43 | 43 | ||
44 | static void __init pcpu4k_populate_pte(unsigned long addr) | ||
45 | { | ||
46 | populate_extra_pte(addr); | ||
47 | } | ||
48 | |||
44 | static inline void setup_percpu_segment(int cpu) | 49 | static inline void setup_percpu_segment(int cpu) |
45 | { | 50 | { |
46 | #ifdef CONFIG_X86_32 | 51 | #ifdef CONFIG_X86_32 |
@@ -104,7 +109,7 @@ void __init setup_per_cpu_areas(void) | |||
104 | } | 109 | } |
105 | } | 110 | } |
106 | 111 | ||
107 | pcpu_unit_size = pcpu_setup_static(populate_extra_pte, pages, size); | 112 | pcpu_unit_size = pcpu_setup_static(pcpu4k_populate_pte, pages, size); |
108 | 113 | ||
109 | free_bootmem(__pa(pages), pages_size); | 114 | free_bootmem(__pa(pages), pages_size); |
110 | 115 | ||
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 8b1a0ef7f874..84a26883ab44 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -137,14 +137,21 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) | |||
137 | return pte_offset_kernel(pmd, 0); | 137 | return pte_offset_kernel(pmd, 0); |
138 | } | 138 | } |
139 | 139 | ||
140 | void __init populate_extra_pte(unsigned long vaddr) | 140 | pmd_t * __init populate_extra_pmd(unsigned long vaddr) |
141 | { | 141 | { |
142 | int pgd_idx = pgd_index(vaddr); | 142 | int pgd_idx = pgd_index(vaddr); |
143 | int pmd_idx = pmd_index(vaddr); | 143 | int pmd_idx = pmd_index(vaddr); |
144 | |||
145 | return one_md_table_init(swapper_pg_dir + pgd_idx) + pmd_idx; | ||
146 | } | ||
147 | |||
148 | pte_t * __init populate_extra_pte(unsigned long vaddr) | ||
149 | { | ||
150 | int pte_idx = pte_index(vaddr); | ||
144 | pmd_t *pmd; | 151 | pmd_t *pmd; |
145 | 152 | ||
146 | pmd = one_md_table_init(swapper_pg_dir + pgd_idx); | 153 | pmd = populate_extra_pmd(vaddr); |
147 | one_page_table_init(pmd + pmd_idx); | 154 | return one_page_table_init(pmd) + pte_idx; |
148 | } | 155 | } |
149 | 156 | ||
150 | static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, | 157 | static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 7f91e2cdc4ce..7d4e76da3368 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -168,34 +168,51 @@ static __ref void *spp_getpage(void) | |||
168 | return ptr; | 168 | return ptr; |
169 | } | 169 | } |
170 | 170 | ||
171 | void | 171 | static pud_t * __init fill_pud(pgd_t *pgd, unsigned long vaddr) |
172 | set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) | ||
173 | { | 172 | { |
174 | pud_t *pud; | 173 | if (pgd_none(*pgd)) { |
175 | pmd_t *pmd; | 174 | pud_t *pud = (pud_t *)spp_getpage(); |
176 | pte_t *pte; | 175 | pgd_populate(&init_mm, pgd, pud); |
176 | if (pud != pud_offset(pgd, 0)) | ||
177 | printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n", | ||
178 | pud, pud_offset(pgd, 0)); | ||
179 | } | ||
180 | return pud_offset(pgd, vaddr); | ||
181 | } | ||
177 | 182 | ||
178 | pud = pud_page + pud_index(vaddr); | 183 | static pmd_t * __init fill_pmd(pud_t *pud, unsigned long vaddr) |
184 | { | ||
179 | if (pud_none(*pud)) { | 185 | if (pud_none(*pud)) { |
180 | pmd = (pmd_t *) spp_getpage(); | 186 | pmd_t *pmd = (pmd_t *) spp_getpage(); |
181 | pud_populate(&init_mm, pud, pmd); | 187 | pud_populate(&init_mm, pud, pmd); |
182 | if (pmd != pmd_offset(pud, 0)) { | 188 | if (pmd != pmd_offset(pud, 0)) |
183 | printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n", | 189 | printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n", |
184 | pmd, pmd_offset(pud, 0)); | 190 | pmd, pmd_offset(pud, 0)); |
185 | return; | ||
186 | } | ||
187 | } | 191 | } |
188 | pmd = pmd_offset(pud, vaddr); | 192 | return pmd_offset(pud, vaddr); |
193 | } | ||
194 | |||
195 | static pte_t * __init fill_pte(pmd_t *pmd, unsigned long vaddr) | ||
196 | { | ||
189 | if (pmd_none(*pmd)) { | 197 | if (pmd_none(*pmd)) { |
190 | pte = (pte_t *) spp_getpage(); | 198 | pte_t *pte = (pte_t *) spp_getpage(); |
191 | pmd_populate_kernel(&init_mm, pmd, pte); | 199 | pmd_populate_kernel(&init_mm, pmd, pte); |
192 | if (pte != pte_offset_kernel(pmd, 0)) { | 200 | if (pte != pte_offset_kernel(pmd, 0)) |
193 | printk(KERN_ERR "PAGETABLE BUG #02!\n"); | 201 | printk(KERN_ERR "PAGETABLE BUG #02!\n"); |
194 | return; | ||
195 | } | ||
196 | } | 202 | } |
203 | return pte_offset_kernel(pmd, vaddr); | ||
204 | } | ||
205 | |||
206 | void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) | ||
207 | { | ||
208 | pud_t *pud; | ||
209 | pmd_t *pmd; | ||
210 | pte_t *pte; | ||
211 | |||
212 | pud = pud_page + pud_index(vaddr); | ||
213 | pmd = fill_pmd(pud, vaddr); | ||
214 | pte = fill_pte(pmd, vaddr); | ||
197 | 215 | ||
198 | pte = pte_offset_kernel(pmd, vaddr); | ||
199 | set_pte(pte, new_pte); | 216 | set_pte(pte, new_pte); |
200 | 217 | ||
201 | /* | 218 | /* |
@@ -205,8 +222,7 @@ set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte) | |||
205 | __flush_tlb_one(vaddr); | 222 | __flush_tlb_one(vaddr); |
206 | } | 223 | } |
207 | 224 | ||
208 | void | 225 | void set_pte_vaddr(unsigned long vaddr, pte_t pteval) |
209 | set_pte_vaddr(unsigned long vaddr, pte_t pteval) | ||
210 | { | 226 | { |
211 | pgd_t *pgd; | 227 | pgd_t *pgd; |
212 | pud_t *pud_page; | 228 | pud_t *pud_page; |
@@ -223,23 +239,22 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval) | |||
223 | set_pte_vaddr_pud(pud_page, vaddr, pteval); | 239 | set_pte_vaddr_pud(pud_page, vaddr, pteval); |
224 | } | 240 | } |
225 | 241 | ||
226 | void __init populate_extra_pte(unsigned long vaddr) | 242 | pmd_t * __init populate_extra_pmd(unsigned long vaddr) |
227 | { | 243 | { |
228 | pgd_t *pgd; | 244 | pgd_t *pgd; |
229 | pud_t *pud; | 245 | pud_t *pud; |
230 | 246 | ||
231 | pgd = pgd_offset_k(vaddr); | 247 | pgd = pgd_offset_k(vaddr); |
232 | if (pgd_none(*pgd)) { | 248 | pud = fill_pud(pgd, vaddr); |
233 | pud = (pud_t *)spp_getpage(); | 249 | return fill_pmd(pud, vaddr); |
234 | pgd_populate(&init_mm, pgd, pud); | 250 | } |
235 | if (pud != pud_offset(pgd, 0)) { | 251 | |
236 | printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n", | 252 | pte_t * __init populate_extra_pte(unsigned long vaddr) |
237 | pud, pud_offset(pgd, 0)); | 253 | { |
238 | return; | 254 | pmd_t *pmd; |
239 | } | ||
240 | } | ||
241 | 255 | ||
242 | set_pte_vaddr_pud((pud_t *)pgd_page_vaddr(*pgd), vaddr, __pte(0)); | 256 | pmd = populate_extra_pmd(vaddr); |
257 | return fill_pte(pmd, vaddr); | ||
243 | } | 258 | } |
244 | 259 | ||
245 | /* | 260 | /* |