]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef __ASM_SH_PGALLOC_H |
2 | #define __ASM_SH_PGALLOC_H | |
3 | ||
5f8c9908 PM |
4 | #include <linux/quicklist.h> |
5 | #include <asm/page.h> | |
6 | ||
7 | #define QUICK_PGD 0 /* We preserve special mappings over free */ | |
8 | #define QUICK_PT 1 /* Other page table pages that are zero on free */ | |
9 | ||
99a596f9 SM |
10 | static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, |
11 | pte_t *pte) | |
12 | { | |
13 | set_pmd(pmd, __pmd((unsigned long)pte)); | |
14 | } | |
1da177e4 LT |
15 | |
16 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | |
17 | struct page *pte) | |
18 | { | |
99a596f9 | 19 | set_pmd(pmd, __pmd((unsigned long)page_address(pte))); |
1da177e4 LT |
20 | } |
21 | ||
5f8c9908 PM |
22 | static inline void pgd_ctor(void *x) |
23 | { | |
24 | pgd_t *pgd = x; | |
25 | ||
26 | memcpy(pgd + USER_PTRS_PER_PGD, | |
27 | swapper_pg_dir + USER_PTRS_PER_PGD, | |
28 | (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); | |
29 | } | |
30 | ||
1da177e4 LT |
31 | /* |
32 | * Allocate and free page tables. | |
33 | */ | |
34 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | |
35 | { | |
5f8c9908 | 36 | return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); |
1da177e4 LT |
37 | } |
38 | ||
39 | static inline void pgd_free(pgd_t *pgd) | |
40 | { | |
5f8c9908 | 41 | quicklist_free(QUICK_PGD, NULL, pgd); |
1da177e4 LT |
42 | } |
43 | ||
44 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, | |
45 | unsigned long address) | |
46 | { | |
1039b9a9 | 47 | return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); |
1da177e4 LT |
48 | } |
49 | ||
50 | static inline struct page *pte_alloc_one(struct mm_struct *mm, | |
51 | unsigned long address) | |
52 | { | |
1039b9a9 | 53 | void *pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); |
5f8c9908 | 54 | return pg ? virt_to_page(pg) : NULL; |
1da177e4 LT |
55 | } |
56 | ||
57 | static inline void pte_free_kernel(pte_t *pte) | |
58 | { | |
5f8c9908 | 59 | quicklist_free(QUICK_PT, NULL, pte); |
1da177e4 LT |
60 | } |
61 | ||
62 | static inline void pte_free(struct page *pte) | |
63 | { | |
5f8c9908 | 64 | quicklist_free_page(QUICK_PT, NULL, pte); |
1da177e4 LT |
65 | } |
66 | ||
67 | #define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) | |
68 | ||
69 | /* | |
70 | * allocating and freeing a pmd is trivial: the 1-entry pmd is | |
71 | * inside the pgd, so has no extra memory associated with it. | |
72 | */ | |
73 | ||
1da177e4 LT |
74 | #define pmd_free(x) do { } while (0) |
75 | #define __pmd_free_tlb(tlb,x) do { } while (0) | |
5f8c9908 PM |
76 | |
77 | static inline void check_pgt_cache(void) | |
78 | { | |
79 | quicklist_trim(QUICK_PGD, NULL, 25, 16); | |
80 | quicklist_trim(QUICK_PT, NULL, 25, 16); | |
81 | } | |
1da177e4 | 82 | |
1da177e4 | 83 | #endif /* __ASM_SH_PGALLOC_H */ |