aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-02-23 21:57:21 -0500
committerTejun Heo <tj@kernel.org>2009-02-23 21:57:21 -0500
commit458a3e644c3327be529393982e24277eda8f1ac7 (patch)
treef39bab1d54eeb222565c8d9086f2e4f645d97f58 /arch/x86
parentc0c0a29379b5848aec2e8f1c58d853d3cb7118b8 (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.h3
-rw-r--r--arch/x86/kernel/setup_percpu.c7
-rw-r--r--arch/x86/mm/init_32.c13
-rw-r--r--arch/x86/mm/init_64.c75
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. */
404void set_pte_vaddr(unsigned long vaddr, pte_t pte); 404void set_pte_vaddr(unsigned long vaddr, pte_t pte);
405void populate_extra_pte(unsigned long vaddr); 405pmd_t *populate_extra_pmd(unsigned long vaddr);
406pte_t *populate_extra_pte(unsigned long vaddr);
406 407
407#ifdef CONFIG_X86_32 408#ifdef CONFIG_X86_32
408extern void native_pagetable_setup_start(pgd_t *base); 409extern 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};
42EXPORT_SYMBOL(__per_cpu_offset); 42EXPORT_SYMBOL(__per_cpu_offset);
43 43
44static void __init pcpu4k_populate_pte(unsigned long addr)
45{
46 populate_extra_pte(addr);
47}
48
44static inline void setup_percpu_segment(int cpu) 49static 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
140void __init populate_extra_pte(unsigned long vaddr) 140pmd_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
148pte_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
150static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd, 157static 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
171void 171static pud_t * __init fill_pud(pgd_t *pgd, unsigned long vaddr)
172set_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); 183static 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
195static 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
206void 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
208void 225void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
209set_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
226void __init populate_extra_pte(unsigned long vaddr) 242pmd_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", 252pte_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/*