]> err.no Git - linux-2.6/blob - arch/x86/mm/pgtable.c
Merge branch 'linus' into x86/fixmap
[linux-2.6] / arch / x86 / mm / pgtable.c
1 #include <linux/mm.h>
2 #include <asm/pgalloc.h>
3 #include <asm/pgtable.h>
4 #include <asm/tlb.h>
5 #include <asm/fixmap.h>
6
7 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
8 {
9         return (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
10 }
11
12 pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address)
13 {
14         struct page *pte;
15
16 #ifdef CONFIG_HIGHPTE
17         pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0);
18 #else
19         pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
20 #endif
21         if (pte)
22                 pgtable_page_ctor(pte);
23         return pte;
24 }
25
26 void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
27 {
28         pgtable_page_dtor(pte);
29         paravirt_release_pte(page_to_pfn(pte));
30         tlb_remove_page(tlb, pte);
31 }
32
33 #if PAGETABLE_LEVELS > 2
34 void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
35 {
36         paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT);
37         tlb_remove_page(tlb, virt_to_page(pmd));
38 }
39
40 #if PAGETABLE_LEVELS > 3
41 void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
42 {
43         paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
44         tlb_remove_page(tlb, virt_to_page(pud));
45 }
46 #endif  /* PAGETABLE_LEVELS > 3 */
47 #endif  /* PAGETABLE_LEVELS > 2 */
48
49 static inline void pgd_list_add(pgd_t *pgd)
50 {
51         struct page *page = virt_to_page(pgd);
52
53         list_add(&page->lru, &pgd_list);
54 }
55
56 static inline void pgd_list_del(pgd_t *pgd)
57 {
58         struct page *page = virt_to_page(pgd);
59
60         list_del(&page->lru);
61 }
62
63 #define UNSHARED_PTRS_PER_PGD                           \
64         (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
65
66 static void pgd_ctor(void *p)
67 {
68         pgd_t *pgd = p;
69         unsigned long flags;
70
71         /* Clear usermode parts of PGD */
72         memset(pgd, 0, KERNEL_PGD_BOUNDARY*sizeof(pgd_t));
73
74         spin_lock_irqsave(&pgd_lock, flags);
75
76         /* If the pgd points to a shared pagetable level (either the
77            ptes in non-PAE, or shared PMD in PAE), then just copy the
78            references from swapper_pg_dir. */
79         if (PAGETABLE_LEVELS == 2 ||
80             (PAGETABLE_LEVELS == 3 && SHARED_KERNEL_PMD) ||
81             PAGETABLE_LEVELS == 4) {
82                 clone_pgd_range(pgd + KERNEL_PGD_BOUNDARY,
83                                 swapper_pg_dir + KERNEL_PGD_BOUNDARY,
84                                 KERNEL_PGD_PTRS);
85                 paravirt_alloc_pmd_clone(__pa(pgd) >> PAGE_SHIFT,
86                                          __pa(swapper_pg_dir) >> PAGE_SHIFT,
87                                          KERNEL_PGD_BOUNDARY,
88                                          KERNEL_PGD_PTRS);
89         }
90
91         /* list required to sync kernel mapping updates */
92         if (!SHARED_KERNEL_PMD)
93                 pgd_list_add(pgd);
94
95         spin_unlock_irqrestore(&pgd_lock, flags);
96 }
97
98 static void pgd_dtor(void *pgd)
99 {
100         unsigned long flags; /* can be called from interrupt context */
101
102         if (SHARED_KERNEL_PMD)
103                 return;
104
105         spin_lock_irqsave(&pgd_lock, flags);
106         pgd_list_del(pgd);
107         spin_unlock_irqrestore(&pgd_lock, flags);
108 }
109
110 /*
111  * List of all pgd's needed for non-PAE so it can invalidate entries
112  * in both cached and uncached pgd's; not needed for PAE since the
113  * kernel pmd is shared. If PAE were not to share the pmd a similar
114  * tactic would be needed. This is essentially codepath-based locking
115  * against pageattr.c; it is the unique case in which a valid change
116  * of kernel pagetables can't be lazily synchronized by vmalloc faults.
117  * vmalloc faults work because attached pagetables are never freed.
118  * -- wli
119  */
120
121 #ifdef CONFIG_X86_PAE
122 /*
123  * Mop up any pmd pages which may still be attached to the pgd.
124  * Normally they will be freed by munmap/exit_mmap, but any pmd we
125  * preallocate which never got a corresponding vma will need to be
126  * freed manually.
127  */
128 static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgdp)
129 {
130         int i;
131
132         for(i = 0; i < UNSHARED_PTRS_PER_PGD; i++) {
133                 pgd_t pgd = pgdp[i];
134
135                 if (pgd_val(pgd) != 0) {
136                         pmd_t *pmd = (pmd_t *)pgd_page_vaddr(pgd);
137
138                         pgdp[i] = native_make_pgd(0);
139
140                         paravirt_release_pmd(pgd_val(pgd) >> PAGE_SHIFT);
141                         pmd_free(mm, pmd);
142                 }
143         }
144 }
145
146 /*
147  * In PAE mode, we need to do a cr3 reload (=tlb flush) when
148  * updating the top-level pagetable entries to guarantee the
149  * processor notices the update.  Since this is expensive, and
150  * all 4 top-level entries are used almost immediately in a
151  * new process's life, we just pre-populate them here.
152  *
153  * Also, if we're in a paravirt environment where the kernel pmd is
154  * not shared between pagetables (!SHARED_KERNEL_PMDS), we allocate
155  * and initialize the kernel pmds here.
156  */
157 static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
158 {
159         pud_t *pud;
160         unsigned long addr;
161         int i;
162
163         pud = pud_offset(pgd, 0);
164         for (addr = i = 0; i < UNSHARED_PTRS_PER_PGD;
165              i++, pud++, addr += PUD_SIZE) {
166                 pmd_t *pmd = pmd_alloc_one(mm, addr);
167
168                 if (!pmd) {
169                         pgd_mop_up_pmds(mm, pgd);
170                         return 0;
171                 }
172
173                 if (i >= KERNEL_PGD_BOUNDARY)
174                         memcpy(pmd, (pmd_t *)pgd_page_vaddr(swapper_pg_dir[i]),
175                                sizeof(pmd_t) * PTRS_PER_PMD);
176
177                 pud_populate(mm, pud, pmd);
178         }
179
180         return 1;
181 }
182
183 void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
184 {
185         paravirt_alloc_pmd(mm, __pa(pmd) >> PAGE_SHIFT);
186
187         /* Note: almost everything apart from _PAGE_PRESENT is
188            reserved at the pmd (PDPT) level. */
189         set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT));
190
191         /*
192          * According to Intel App note "TLBs, Paging-Structure Caches,
193          * and Their Invalidation", April 2007, document 317080-001,
194          * section 8.1: in PAE mode we explicitly have to flush the
195          * TLB via cr3 if the top-level pgd is changed...
196          */
197         if (mm == current->active_mm)
198                 write_cr3(read_cr3());
199 }
200 #else  /* !CONFIG_X86_PAE */
201 /* No need to prepopulate any pagetable entries in non-PAE modes. */
202 static int pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd)
203 {
204         return 1;
205 }
206
207 static void pgd_mop_up_pmds(struct mm_struct *mm, pgd_t *pgd)
208 {
209 }
210 #endif  /* CONFIG_X86_PAE */
211
212 pgd_t *pgd_alloc(struct mm_struct *mm)
213 {
214         pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
215
216         /* so that alloc_pmd can use it */
217         mm->pgd = pgd;
218         if (pgd)
219                 pgd_ctor(pgd);
220
221         if (pgd && !pgd_prepopulate_pmd(mm, pgd)) {
222                 pgd_dtor(pgd);
223                 free_page((unsigned long)pgd);
224                 pgd = NULL;
225         }
226
227         return pgd;
228 }
229
230 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
231 {
232         pgd_mop_up_pmds(mm, pgd);
233         pgd_dtor(pgd);
234         free_page((unsigned long)pgd);
235 }
236
237 int ptep_set_access_flags(struct vm_area_struct *vma,
238                           unsigned long address, pte_t *ptep,
239                           pte_t entry, int dirty)
240 {
241         int changed = !pte_same(*ptep, entry);
242
243         if (changed && dirty) {
244                 *ptep = entry;
245                 pte_update_defer(vma->vm_mm, address, ptep);
246                 flush_tlb_page(vma, address);
247         }
248
249         return changed;
250 }
251
252 int ptep_test_and_clear_young(struct vm_area_struct *vma,
253                               unsigned long addr, pte_t *ptep)
254 {
255         int ret = 0;
256
257         if (pte_young(*ptep))
258                 ret = test_and_clear_bit(_PAGE_BIT_ACCESSED,
259                                          &ptep->pte);
260
261         if (ret)
262                 pte_update(vma->vm_mm, addr, ptep);
263
264         return ret;
265 }
266
267 int ptep_clear_flush_young(struct vm_area_struct *vma,
268                            unsigned long address, pte_t *ptep)
269 {
270         int young;
271
272         young = ptep_test_and_clear_young(vma, address, ptep);
273         if (young)
274                 flush_tlb_page(vma, address);
275
276         return young;
277 }
278
279 int fixmaps_set;
280
281 void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
282 {
283         unsigned long address = __fix_to_virt(idx);
284
285         if (idx >= __end_of_fixed_addresses) {
286                 BUG();
287                 return;
288         }
289         set_pte_vaddr(address, pte);
290         fixmaps_set++;
291 }
292
293 void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
294 {
295         __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
296 }