Commit | Line | Data |
---|---|---|
f5e706ad SR |
1 | #ifndef _SPARC64_PGALLOC_H |
2 | #define _SPARC64_PGALLOC_H | |
3 | ||
4 | #include <linux/kernel.h> | |
5 | #include <linux/sched.h> | |
6 | #include <linux/mm.h> | |
7 | #include <linux/slab.h> | |
f5e706ad SR |
8 | |
9 | #include <asm/spitfire.h> | |
10 | #include <asm/cpudata.h> | |
11 | #include <asm/cacheflush.h> | |
12 | #include <asm/page.h> | |
13 | ||
14 | /* Page table allocation/freeing. */ | |
15 | ||
4dedbf8d DM |
16 | extern struct kmem_cache *pgtable_cache; |
17 | ||
f5e706ad SR |
18 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
19 | { | |
4dedbf8d | 20 | return kmem_cache_alloc(pgtable_cache, GFP_KERNEL); |
f5e706ad SR |
21 | } |
22 | ||
23 | static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |
24 | { | |
4dedbf8d | 25 | kmem_cache_free(pgtable_cache, pgd); |
f5e706ad SR |
26 | } |
27 | ||
28 | #define pud_populate(MM, PUD, PMD) pud_set(PUD, PMD) | |
29 | ||
30 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) | |
31 | { | |
4dedbf8d DM |
32 | return kmem_cache_alloc(pgtable_cache, |
33 | GFP_KERNEL|__GFP_REPEAT); | |
f5e706ad SR |
34 | } |
35 | ||
36 | static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
37 | { | |
4dedbf8d | 38 | kmem_cache_free(pgtable_cache, pmd); |
f5e706ad SR |
39 | } |
40 | ||
c460bec7 DM |
41 | extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, |
42 | unsigned long address); | |
43 | extern pgtable_t pte_alloc_one(struct mm_struct *mm, | |
44 | unsigned long address); | |
45 | extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte); | |
46 | extern void pte_free(struct mm_struct *mm, pgtable_t ptepage); | |
f5e706ad | 47 | |
f5e706ad | 48 | #define pmd_populate_kernel(MM, PMD, PTE) pmd_set(PMD, PTE) |
c460bec7 DM |
49 | #define pmd_populate(MM, PMD, PTE) pmd_set(PMD, PTE) |
50 | #define pmd_pgtable(PMD) ((pte_t *)__pmd_page(PMD)) | |
f5e706ad | 51 | |
4dedbf8d | 52 | #define check_pgt_cache() do { } while (0) |
f5e706ad | 53 | |
c460bec7 | 54 | extern void pgtable_free(void *table, bool is_page); |
4a0100f7 DM |
55 | |
56 | #ifdef CONFIG_SMP | |
57 | ||
58 | struct mmu_gather; | |
59 | extern void tlb_remove_table(struct mmu_gather *, void *); | |
60 | ||
61 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page) | |
62 | { | |
63 | unsigned long pgf = (unsigned long)table; | |
64 | if (is_page) | |
65 | pgf |= 0x1UL; | |
66 | tlb_remove_table(tlb, (void *)pgf); | |
67 | } | |
68 | ||
69 | static inline void __tlb_remove_table(void *_table) | |
70 | { | |
71 | void *table = (void *)((unsigned long)_table & ~0x1UL); | |
72 | bool is_page = false; | |
73 | ||
74 | if ((unsigned long)_table & 0x1UL) | |
75 | is_page = true; | |
76 | pgtable_free(table, is_page); | |
77 | } | |
78 | #else /* CONFIG_SMP */ | |
79 | static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, bool is_page) | |
80 | { | |
81 | pgtable_free(table, is_page); | |
82 | } | |
83 | #endif /* !CONFIG_SMP */ | |
84 | ||
c460bec7 | 85 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pte_t *pte, |
4a0100f7 DM |
86 | unsigned long address) |
87 | { | |
c460bec7 | 88 | pgtable_free_tlb(tlb, pte, true); |
4a0100f7 DM |
89 | } |
90 | ||
91 | #define __pmd_free_tlb(tlb, pmd, addr) \ | |
92 | pgtable_free_tlb(tlb, pmd, false) | |
90f08e39 | 93 | |
f5e706ad | 94 | #endif /* _SPARC64_PGALLOC_H */ |