1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2deae26bfSKyle McMartin #ifndef _ASM_PGALLOC_H
3deae26bfSKyle McMartin #define _ASM_PGALLOC_H
4deae26bfSKyle McMartin
5deae26bfSKyle McMartin #include <linux/gfp.h>
6deae26bfSKyle McMartin #include <linux/mm.h>
7deae26bfSKyle McMartin #include <linux/threads.h>
8deae26bfSKyle McMartin #include <asm/processor.h>
9deae26bfSKyle McMartin #include <asm/fixmap.h>
10deae26bfSKyle McMartin
11deae26bfSKyle McMartin #include <asm/cache.h>
12deae26bfSKyle McMartin
136f6aea7eSMike Rapoport #define __HAVE_ARCH_PMD_ALLOC_ONE
141355c31eSMike Rapoport #define __HAVE_ARCH_PMD_FREE
15f9cb654cSMike Rapoport #define __HAVE_ARCH_PGD_FREE
161355c31eSMike Rapoport #include <asm-generic/pgalloc.h>
173f4a1308SMike Rapoport
18b7795074SHelge Deller /* Allocate the top level pgd (page directory) */
pgd_alloc(struct mm_struct * mm)19deae26bfSKyle McMartin static inline pgd_t *pgd_alloc(struct mm_struct *mm)
20deae26bfSKyle McMartin {
21b7795074SHelge Deller pgd_t *pgd;
22deae26bfSKyle McMartin
23*4501a7a0SMike Rapoport pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_TABLE_ORDER);
24b7795074SHelge Deller if (unlikely(pgd == NULL))
25b7795074SHelge Deller return NULL;
26b7795074SHelge Deller
27*4501a7a0SMike Rapoport memset(pgd, 0, PAGE_SIZE << PGD_TABLE_ORDER);
28b7795074SHelge Deller
29b7795074SHelge Deller return pgd;
30deae26bfSKyle McMartin }
31deae26bfSKyle McMartin
pgd_free(struct mm_struct * mm,pgd_t * pgd)32deae26bfSKyle McMartin static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
33deae26bfSKyle McMartin {
34*4501a7a0SMike Rapoport free_pages((unsigned long)pgd, PGD_TABLE_ORDER);
35deae26bfSKyle McMartin }
36deae26bfSKyle McMartin
37f24ffde4SKirill A. Shutemov #if CONFIG_PGTABLE_LEVELS == 3
38deae26bfSKyle McMartin
39deae26bfSKyle McMartin /* Three Level Page Table Support for pmd's */
40deae26bfSKyle McMartin
pud_populate(struct mm_struct * mm,pud_t * pud,pmd_t * pmd)41d96885e2SMike Rapoport static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
42deae26bfSKyle McMartin {
43d96885e2SMike Rapoport set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
44d96885e2SMike Rapoport (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
45deae26bfSKyle McMartin }
46deae26bfSKyle McMartin
pmd_alloc_one(struct mm_struct * mm,unsigned long address)476f6aea7eSMike Rapoport static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
486f6aea7eSMike Rapoport {
49b7795074SHelge Deller pmd_t *pmd;
50b7795074SHelge Deller
517bf82eb3SMatthew Wilcox (Oracle) pmd = (pmd_t *)__get_free_pages(GFP_PGTABLE_KERNEL, PMD_TABLE_ORDER);
52b7795074SHelge Deller if (likely(pmd))
537bf82eb3SMatthew Wilcox (Oracle) memset ((void *)pmd, 0, PAGE_SIZE << PMD_TABLE_ORDER);
54b7795074SHelge Deller return pmd;
556f6aea7eSMike Rapoport }
566f6aea7eSMike Rapoport
pmd_free(struct mm_struct * mm,pmd_t * pmd)57deae26bfSKyle McMartin static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
58deae26bfSKyle McMartin {
597bf82eb3SMatthew Wilcox (Oracle) free_pages((unsigned long)pmd, PMD_TABLE_ORDER);
60deae26bfSKyle McMartin }
61deae26bfSKyle McMartin #endif
62deae26bfSKyle McMartin
63deae26bfSKyle McMartin static inline void
pmd_populate_kernel(struct mm_struct * mm,pmd_t * pmd,pte_t * pte)64deae26bfSKyle McMartin pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
65deae26bfSKyle McMartin {
66d96885e2SMike Rapoport set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
67d96885e2SMike Rapoport + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
68deae26bfSKyle McMartin }
69deae26bfSKyle McMartin
70deae26bfSKyle McMartin #define pmd_populate(mm, pmd, pte_page) \
71deae26bfSKyle McMartin pmd_populate_kernel(mm, pmd, page_address(pte_page))
72deae26bfSKyle McMartin
73deae26bfSKyle McMartin #endif
74