Branch data Line data Source code
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 : : */ 19 : : static inline pte_t *__pte_alloc_one_kernel(struct mm_struct *mm) 20 : : { 21 : 3 : 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 : : */ 31 : : static 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 : : */ 42 : : static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 43 : : { 44 : 2 : 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 : : */ 59 : 3 : static 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 : 3 : if (!pte) 65 : : return NULL; 66 : : if (!pgtable_pte_page_ctor(pte)) { 67 : : __free_page(pte); 68 : : return NULL; 69 : : } 70 : : 71 : 3 : 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 : : */ 83 : : static 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 : : */ 99 : 3 : static inline void pte_free(struct mm_struct *mm, struct page *pte_page) 100 : : { 101 : : pgtable_pte_page_dtor(pte_page); 102 : 3 : __free_page(pte_page); 103 : 3 : } 104 : : 105 : : #endif /* CONFIG_MMU */ 106 : : 107 : : #endif /* __ASM_GENERIC_PGALLOC_H */