Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[sfrench/cifs-2.6.git] / include / asm-x86 / pgalloc_32.h
1 #ifndef _I386_PGALLOC_H
2 #define _I386_PGALLOC_H
3
4 #include <linux/threads.h>
5 #include <linux/mm.h>           /* for struct page */
6 #include <asm/tlb.h>
7 #include <asm-generic/tlb.h>
8
9 #ifdef CONFIG_PARAVIRT
10 #include <asm/paravirt.h>
11 #else
12 #define paravirt_alloc_pt(mm, pfn) do { } while (0)
13 #define paravirt_alloc_pd(mm, pfn) do { } while (0)
14 #define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) do { } while (0)
15 #define paravirt_release_pt(pfn) do { } while (0)
16 #define paravirt_release_pd(pfn) do { } while (0)
17 #endif
18
19 static inline void pmd_populate_kernel(struct mm_struct *mm,
20                                        pmd_t *pmd, pte_t *pte)
21 {
22         paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);
23         set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
24 }
25
26 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
27 {
28         unsigned long pfn = page_to_pfn(pte);
29
30         paravirt_alloc_pt(mm, pfn);
31         set_pmd(pmd, __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE));
32 }
33
34 /*
35  * Allocate and free page tables.
36  */
37 extern pgd_t *pgd_alloc(struct mm_struct *);
38 extern void pgd_free(pgd_t *pgd);
39
40 extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
41 extern struct page *pte_alloc_one(struct mm_struct *, unsigned long);
42
43 static inline void pte_free_kernel(pte_t *pte)
44 {
45         free_page((unsigned long)pte);
46 }
47
48 static inline void pte_free(struct page *pte)
49 {
50         __free_page(pte);
51 }
52
53
54 static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
55 {
56         paravirt_release_pt(page_to_pfn(pte));
57         tlb_remove_page(tlb, pte);
58 }
59
60 #ifdef CONFIG_X86_PAE
61 /*
62  * In the PAE case we free the pmds as part of the pgd.
63  */
64 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
65 {
66         return (pmd_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT);
67 }
68
69 static inline void pmd_free(pmd_t *pmd)
70 {
71         BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
72         free_page((unsigned long)pmd);
73 }
74
75 static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
76 {
77         /* This is called just after the pmd has been detached from
78            the pgd, which requires a full tlb flush to be recognized
79            by the CPU.  Rather than incurring multiple tlb flushes
80            while the address space is being pulled down, make the tlb
81            gathering machinery do a full flush when we're done. */
82         tlb->fullmm = 1;
83
84         paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT);
85         tlb_remove_page(tlb, virt_to_page(pmd));
86 }
87
88 static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
89 {
90         paravirt_alloc_pd(mm, __pa(pmd) >> PAGE_SHIFT);
91
92         /* Note: almost everything apart from _PAGE_PRESENT is
93            reserved at the pmd (PDPT) level. */
94         set_pud(pudp, __pud(__pa(pmd) | _PAGE_PRESENT));
95
96         /*
97          * Pentium-II erratum A13: in PAE mode we explicitly have to flush
98          * the TLB via cr3 if the top-level pgd is changed...
99          */
100         if (mm == current->active_mm)
101                 write_cr3(read_cr3());
102 }
103 #endif  /* CONFIG_X86_PAE */
104
105 #endif /* _I386_PGALLOC_H */