Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / sh / include / asm / pgalloc.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_SH_PGALLOC_H
3 #define __ASM_SH_PGALLOC_H
4
5 #include <linux/quicklist.h>
6 #include <asm/page.h>
7
8 #define QUICK_PT 0      /* Other page table pages that are zero on free */
9
10 extern pgd_t *pgd_alloc(struct mm_struct *);
11 extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
12
13 #if PAGETABLE_LEVELS > 2
14 extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
15 extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
16 extern void pmd_free(struct mm_struct *mm, pmd_t *pmd);
17 #endif
18
19 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
20                                        pte_t *pte)
21 {
22         set_pmd(pmd, __pmd((unsigned long)pte));
23 }
24
25 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
26                                 pgtable_t pte)
27 {
28         set_pmd(pmd, __pmd((unsigned long)page_address(pte)));
29 }
30 #define pmd_pgtable(pmd) pmd_page(pmd)
31
32 /*
33  * Allocate and free page tables.
34  */
35 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
36 {
37         return quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
38 }
39
40 static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
41 {
42         struct page *page;
43         void *pg;
44
45         pg = quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL);
46         if (!pg)
47                 return NULL;
48         page = virt_to_page(pg);
49         if (!pgtable_page_ctor(page)) {
50                 quicklist_free(QUICK_PT, NULL, pg);
51                 return NULL;
52         }
53         return page;
54 }
55
56 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
57 {
58         quicklist_free(QUICK_PT, NULL, pte);
59 }
60
61 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
62 {
63         pgtable_page_dtor(pte);
64         quicklist_free_page(QUICK_PT, NULL, pte);
65 }
66
67 #define __pte_free_tlb(tlb,pte,addr)                    \
68 do {                                                    \
69         pgtable_page_dtor(pte);                         \
70         tlb_remove_page((tlb), (pte));                  \
71 } while (0)
72
73 #if CONFIG_PGTABLE_LEVELS > 2
74 #define __pmd_free_tlb(tlb, pmdp, addr)                 \
75 do {                                                    \
76         struct page *page = virt_to_page(pmdp);         \
77         pgtable_pmd_page_dtor(page);                    \
78         tlb_remove_page((tlb), page);                   \
79 } while (0);
80 #endif
81
82 static inline void check_pgt_cache(void)
83 {
84         quicklist_trim(QUICK_PT, NULL, 25, 16);
85 }
86
87 #endif /* __ASM_SH_PGALLOC_H */