aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include')
-rw-r--r--arch/powerpc/include/asm/pgalloc-32.h45
-rw-r--r--arch/powerpc/include/asm/pgalloc-64.h157
-rw-r--r--arch/powerpc/include/asm/pgalloc.h46
3 files changed, 189 insertions, 59 deletions
diff --git a/arch/powerpc/include/asm/pgalloc-32.h b/arch/powerpc/include/asm/pgalloc-32.h
index 580cf73b96e8..27b2386f738a 100644
--- a/arch/powerpc/include/asm/pgalloc-32.h
+++ b/arch/powerpc/include/asm/pgalloc-32.h
@@ -37,6 +37,17 @@ extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
37extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); 37extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
38extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr); 38extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
39 39
40static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
41{
42 free_page((unsigned long)pte);
43}
44
45static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
46{
47 pgtable_page_dtor(ptepage);
48 __free_page(ptepage);
49}
50
40static inline void pgtable_free(void *table, unsigned index_size) 51static inline void pgtable_free(void *table, unsigned index_size)
41{ 52{
42 BUG_ON(index_size); /* 32-bit doesn't use this */ 53 BUG_ON(index_size); /* 32-bit doesn't use this */
@@ -45,4 +56,38 @@ static inline void pgtable_free(void *table, unsigned index_size)
45 56
46#define check_pgt_cache() do { } while (0) 57#define check_pgt_cache() do { } while (0)
47 58
59#ifdef CONFIG_SMP
60static inline void pgtable_free_tlb(struct mmu_gather *tlb,
61 void *table, int shift)
62{
63 unsigned long pgf = (unsigned long)table;
64 BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
65 pgf |= shift;
66 tlb_remove_table(tlb, (void *)pgf);
67}
68
69static inline void __tlb_remove_table(void *_table)
70{
71 void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
72 unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
73
74 pgtable_free(table, shift);
75}
76#else
77static inline void pgtable_free_tlb(struct mmu_gather *tlb,
78 void *table, int shift)
79{
80 pgtable_free(table, shift);
81}
82#endif
83
84static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
85 unsigned long address)
86{
87 struct page *page = page_address(table);
88
89 tlb_flush_pgtable(tlb, address);
90 pgtable_page_dtor(page);
91 pgtable_free_tlb(tlb, page, 0);
92}
48#endif /* _ASM_POWERPC_PGALLOC_32_H */ 93#endif /* _ASM_POWERPC_PGALLOC_32_H */
diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h
index 69e352a5252b..d39012352f94 100644
--- a/arch/powerpc/include/asm/pgalloc-64.h
+++ b/arch/powerpc/include/asm/pgalloc-64.h
@@ -75,8 +75,83 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
75#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte)) 75#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, (unsigned long)(pte))
76#define pmd_pgtable(pmd) pmd_page(pmd) 76#define pmd_pgtable(pmd) pmd_page(pmd)
77 77
78static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
79 unsigned long address)
80{
81 return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
82}
83
84static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
85 unsigned long address)
86{
87 struct page *page;
88 pte_t *pte;
89
90 pte = pte_alloc_one_kernel(mm, address);
91 if (!pte)
92 return NULL;
93 page = virt_to_page(pte);
94 pgtable_page_ctor(page);
95 return page;
96}
97
98static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
99{
100 free_page((unsigned long)pte);
101}
102
103static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
104{
105 pgtable_page_dtor(ptepage);
106 __free_page(ptepage);
107}
108
109static inline void pgtable_free(void *table, unsigned index_size)
110{
111 if (!index_size)
112 free_page((unsigned long)table);
113 else {
114 BUG_ON(index_size > MAX_PGTABLE_INDEX_SIZE);
115 kmem_cache_free(PGT_CACHE(index_size), table);
116 }
117}
118
119#ifdef CONFIG_SMP
120static inline void pgtable_free_tlb(struct mmu_gather *tlb,
121 void *table, int shift)
122{
123 unsigned long pgf = (unsigned long)table;
124 BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
125 pgf |= shift;
126 tlb_remove_table(tlb, (void *)pgf);
127}
128
129static inline void __tlb_remove_table(void *_table)
130{
131 void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
132 unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
133
134 pgtable_free(table, shift);
135}
136#else /* !CONFIG_SMP */
137static inline void pgtable_free_tlb(struct mmu_gather *tlb,
138 void *table, int shift)
139{
140 pgtable_free(table, shift);
141}
142#endif /* CONFIG_SMP */
143
144static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
145 unsigned long address)
146{
147 struct page *page = page_address(table);
148
149 tlb_flush_pgtable(tlb, address);
150 pgtable_page_dtor(page);
151 pgtable_free_tlb(tlb, page, 0);
152}
78 153
79#else /* CONFIG_PPC_64K_PAGES */ 154#else /* if CONFIG_PPC_64K_PAGES */
80 155
81#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd) 156#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd)
82 157
@@ -86,31 +161,25 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
86 pmd_set(pmd, (unsigned long)pte); 161 pmd_set(pmd, (unsigned long)pte);
87} 162}
88 163
89#define pmd_populate(mm, pmd, pte_page) \ 164static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
90 pmd_populate_kernel(mm, pmd, page_address(pte_page)) 165 pgtable_t pte_page)
91#define pmd_pgtable(pmd) pmd_page(pmd)
92
93#endif /* CONFIG_PPC_64K_PAGES */
94
95static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
96{ 166{
97 return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE), 167 pmd_populate_kernel(mm, pmd, page_address(pte_page));
98 GFP_KERNEL|__GFP_REPEAT);
99} 168}
100 169
101static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) 170static inline pgtable_t pmd_pgtable(pmd_t pmd)
102{ 171{
103 kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd); 172 return pmd_page(pmd);
104} 173}
105 174
106static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 175static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
107 unsigned long address) 176 unsigned long address)
108{ 177{
109 return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); 178 return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
110} 179}
111 180
112static inline pgtable_t pte_alloc_one(struct mm_struct *mm, 181static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
113 unsigned long address) 182 unsigned long address)
114{ 183{
115 struct page *page; 184 struct page *page;
116 pte_t *pte; 185 pte_t *pte;
@@ -123,6 +192,17 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
123 return page; 192 return page;
124} 193}
125 194
195static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
196{
197 free_page((unsigned long)pte);
198}
199
200static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
201{
202 pgtable_page_dtor(ptepage);
203 __free_page(ptepage);
204}
205
126static inline void pgtable_free(void *table, unsigned index_size) 206static inline void pgtable_free(void *table, unsigned index_size)
127{ 207{
128 if (!index_size) 208 if (!index_size)
@@ -133,6 +213,55 @@ static inline void pgtable_free(void *table, unsigned index_size)
133 } 213 }
134} 214}
135 215
216#ifdef CONFIG_SMP
217static inline void pgtable_free_tlb(struct mmu_gather *tlb,
218 void *table, int shift)
219{
220 unsigned long pgf = (unsigned long)table;
221 BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
222 pgf |= shift;
223 tlb_remove_table(tlb, (void *)pgf);
224}
225
226static inline void __tlb_remove_table(void *_table)
227{
228 void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
229 unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
230
231 pgtable_free(table, shift);
232}
233#else /* !CONFIG_SMP */
234static inline void pgtable_free_tlb(struct mmu_gather *tlb,
235 void *table, int shift)
236{
237 pgtable_free(table, shift);
238}
239#endif /* CONFIG_SMP */
240
241static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
242 unsigned long address)
243{
244 struct page *page = page_address(table);
245
246 tlb_flush_pgtable(tlb, address);
247 pgtable_page_dtor(page);
248 pgtable_free_tlb(tlb, page, 0);
249}
250
251#endif /* CONFIG_PPC_64K_PAGES */
252
253static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
254{
255 return kmem_cache_alloc(PGT_CACHE(PMD_INDEX_SIZE),
256 GFP_KERNEL|__GFP_REPEAT);
257}
258
259static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
260{
261 kmem_cache_free(PGT_CACHE(PMD_INDEX_SIZE), pmd);
262}
263
264
136#define __pmd_free_tlb(tlb, pmd, addr) \ 265#define __pmd_free_tlb(tlb, pmd, addr) \
137 pgtable_free_tlb(tlb, pmd, PMD_INDEX_SIZE) 266 pgtable_free_tlb(tlb, pmd, PMD_INDEX_SIZE)
138#ifndef CONFIG_PPC_64K_PAGES 267#ifndef CONFIG_PPC_64K_PAGES
diff --git a/arch/powerpc/include/asm/pgalloc.h b/arch/powerpc/include/asm/pgalloc.h
index bf301ac62f35..e9a9f60e596d 100644
--- a/arch/powerpc/include/asm/pgalloc.h
+++ b/arch/powerpc/include/asm/pgalloc.h
@@ -3,6 +3,7 @@
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <linux/mm.h> 5#include <linux/mm.h>
6#include <asm-generic/tlb.h>
6 7
7#ifdef CONFIG_PPC_BOOK3E 8#ifdef CONFIG_PPC_BOOK3E
8extern void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address); 9extern void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address);
@@ -13,56 +14,11 @@ static inline void tlb_flush_pgtable(struct mmu_gather *tlb,
13} 14}
14#endif /* !CONFIG_PPC_BOOK3E */ 15#endif /* !CONFIG_PPC_BOOK3E */
15 16
16static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
17{
18 free_page((unsigned long)pte);
19}
20
21static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
22{
23 pgtable_page_dtor(ptepage);
24 __free_page(ptepage);
25}
26
27#ifdef CONFIG_PPC64 17#ifdef CONFIG_PPC64
28#include <asm/pgalloc-64.h> 18#include <asm/pgalloc-64.h>
29#else 19#else
30#include <asm/pgalloc-32.h> 20#include <asm/pgalloc-32.h>
31#endif 21#endif
32 22
33#ifdef CONFIG_SMP
34struct mmu_gather;
35extern void tlb_remove_table(struct mmu_gather *, void *);
36
37static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
38{
39 unsigned long pgf = (unsigned long)table;
40 BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
41 pgf |= shift;
42 tlb_remove_table(tlb, (void *)pgf);
43}
44
45static inline void __tlb_remove_table(void *_table)
46{
47 void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
48 unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
49
50 pgtable_free(table, shift);
51}
52#else /* CONFIG_SMP */
53static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
54{
55 pgtable_free(table, shift);
56}
57#endif /* !CONFIG_SMP */
58
59static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
60 unsigned long address)
61{
62 tlb_flush_pgtable(tlb, address);
63 pgtable_page_dtor(ptepage);
64 pgtable_free_tlb(tlb, page_address(ptepage), 0);
65}
66
67#endif /* __KERNEL__ */ 23#endif /* __KERNEL__ */
68#endif /* _ASM_POWERPC_PGALLOC_H */ 24#endif /* _ASM_POWERPC_PGALLOC_H */