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 #include <asm-generic/pgalloc.h>
153f4a1308SMike Rapoport
16b7795074SHelge Deller /* Allocate the top level pgd (page directory) */
pgd_alloc(struct mm_struct * mm)17deae26bfSKyle McMartin static inline pgd_t *pgd_alloc(struct mm_struct *mm)
18deae26bfSKyle McMartin {
19*a9b3c355SKevin Brodsky return __pgd_alloc(mm, PGD_TABLE_ORDER);
20deae26bfSKyle McMartin }
21deae26bfSKyle McMartin
22f24ffde4SKirill A. Shutemov #if CONFIG_PGTABLE_LEVELS == 3
23deae26bfSKyle McMartin
24deae26bfSKyle McMartin /* Three Level Page Table Support for pmd's */
25deae26bfSKyle McMartin
pud_populate(struct mm_struct * mm,pud_t * pud,pmd_t * pmd)26d96885e2SMike Rapoport static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
27deae26bfSKyle McMartin {
28d96885e2SMike Rapoport set_pud(pud, __pud((PxD_FLAG_PRESENT | PxD_FLAG_VALID) +
29d96885e2SMike Rapoport (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
30deae26bfSKyle McMartin }
31deae26bfSKyle McMartin
pmd_alloc_one(struct mm_struct * mm,unsigned long address)326f6aea7eSMike Rapoport static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
336f6aea7eSMike Rapoport {
343565522eSKevin Brodsky struct ptdesc *ptdesc;
353565522eSKevin Brodsky gfp_t gfp = GFP_PGTABLE_USER;
36b7795074SHelge Deller
373565522eSKevin Brodsky if (mm == &init_mm)
383565522eSKevin Brodsky gfp = GFP_PGTABLE_KERNEL;
393565522eSKevin Brodsky ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER);
403565522eSKevin Brodsky if (!ptdesc)
413565522eSKevin Brodsky return NULL;
423565522eSKevin Brodsky if (!pagetable_pmd_ctor(ptdesc)) {
433565522eSKevin Brodsky pagetable_free(ptdesc);
443565522eSKevin Brodsky return NULL;
456f6aea7eSMike Rapoport }
463565522eSKevin Brodsky return ptdesc_address(ptdesc);
47deae26bfSKyle McMartin }
48deae26bfSKyle McMartin #endif
49deae26bfSKyle McMartin
50deae26bfSKyle McMartin static inline void
pmd_populate_kernel(struct mm_struct * mm,pmd_t * pmd,pte_t * pte)51deae26bfSKyle McMartin pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
52deae26bfSKyle McMartin {
53d96885e2SMike Rapoport set_pmd(pmd, __pmd((PxD_FLAG_PRESENT | PxD_FLAG_VALID)
54d96885e2SMike Rapoport + (__u32)(__pa((unsigned long)pte) >> PxD_VALUE_SHIFT)));
55deae26bfSKyle McMartin }
56deae26bfSKyle McMartin
57deae26bfSKyle McMartin #define pmd_populate(mm, pmd, pte_page) \
58deae26bfSKyle McMartin pmd_populate_kernel(mm, pmd, page_address(pte_page))
59deae26bfSKyle McMartin
60deae26bfSKyle McMartin #endif
61