1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef __ASM_GENERIC_PGALLOC_H 3#define __ASM_GENERIC_PGALLOC_H 4 5#ifdef CONFIG_MMU 6 7#define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO) 8#define GFP_PGTABLE_USER (GFP_PGTABLE_KERNEL | __GFP_ACCOUNT) 9 10/** 11 * __pte_alloc_one_kernel - allocate a page for PTE-level kernel page table 12 * @mm: the mm_struct of the current context 13 * 14 * This function is intended for architectures that need 15 * anything beyond simple page allocation. 16 * 17 * Return: pointer to the allocated memory or %NULL on error 18 */ 19static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm) 20{ 21 return (pte_t *)__get_free_page(GFP_PGTABLE_KERNEL); 22} 23 24#ifndef __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL 25/** 26 * pte_alloc_one_kernel - allocate a page for PTE-level kernel page table 27 * @mm: the mm_struct of the current context 28 * 29 * Return: pointer to the allocated memory or %NULL on error 30 */ 31static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 32{ 33 return __pte_alloc_one_kernel(mm); 34} 35#endif 36 37/** 38 * pte_free_kernel - free PTE-level kernel page table page 39 * @mm: the mm_struct of the current context 40 * @pte: pointer to the memory containing the page table 41 */ 42static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 43{ 44 free_page((unsigned long)pte); 45} 46 47/** 48 * __pte_alloc_one - allocate a page for PTE-level user page table 49 * @mm: the mm_struct of the current context 50 * @gfp: GFP flags to use for the allocation 51 * 52 * Allocates a page and runs the pgtable_pte_page_ctor(). 53 * 54 * This function is intended for architectures that need 55 * anything beyond simple page allocation or must have custom GFP flags. 56 * 57 * Return: `struct page` initialized as page table or %NULL on error 58 */ 59static inline pgtable_t __pte_alloc_one(struct mm_struct *mm, gfp_t gfp) 60{ 61 struct page *pte; 62 63 pte = alloc_page(gfp); 64 if (!pte) 65 return NULL; 66 if (!pgtable_pte_page_ctor(pte)) { 67 __free_page(pte); 68 return NULL; 69 } 70 71 return pte; 72} 73 74#ifndef __HAVE_ARCH_PTE_ALLOC_ONE 75/** 76 * pte_alloc_one - allocate a page for PTE-level user page table 77 * @mm: the mm_struct of the current context 78 * 79 * Allocates a page and runs the pgtable_pte_page_ctor(). 80 * 81 * Return: `struct page` initialized as page table or %NULL on error 82 */ 83static inline pgtable_t pte_alloc_one(struct mm_struct *mm) 84{ 85 return __pte_alloc_one(mm, GFP_PGTABLE_USER); 86} 87#endif 88 89/* 90 * Should really implement gc for free page table pages. This could be 91 * done with a reference count in struct page. 92 */ 93 94/** 95 * pte_free - free PTE-level user page table page 96 * @mm: the mm_struct of the current context 97 * @pte_page: the `struct page` representing the page table 98 */ 99static inline void pte_free(struct mm_struct *mm, struct page *pte_page) 100{ 101 pgtable_pte_page_dtor(pte_page); 102 __free_page(pte_page); 103} 104 105#endif /* CONFIG_MMU */ 106 107#endif /* __ASM_GENERIC_PGALLOC_H */ 108