1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * include/asm-xtensa/pgalloc.h 4 * 5 * Copyright (C) 2001-2007 Tensilica Inc. 6 */ 7 8 #ifndef _XTENSA_PGALLOC_H 9 #define _XTENSA_PGALLOC_H 10 11 #ifdef CONFIG_MMU 12 #include <linux/highmem.h> 13 #include <linux/slab.h> 14 15 #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL 16 #define __HAVE_ARCH_PTE_ALLOC_ONE 17 #include <asm-generic/pgalloc.h> 18 19 /* 20 * Allocating and freeing a pmd is trivial: the 1-entry pmd is 21 * inside the pgd, so has no extra memory associated with it. 22 */ 23 24 #define pmd_populate_kernel(mm, pmdp, ptep) \ 25 (pmd_val(*(pmdp)) = ((unsigned long)ptep)) 26 #define pmd_populate(mm, pmdp, page) \ 27 (pmd_val(*(pmdp)) = ((unsigned long)page_to_virt(page))) 28 #define pmd_pgtable(pmd) pmd_page(pmd) 29 30 static inline pgd_t* 31 pgd_alloc(struct mm_struct *mm) 32 { 33 return (pgd_t*) __get_free_pages(GFP_KERNEL | __GFP_ZERO, PGD_ORDER); 34 } 35 36 static inline void ptes_clear(pte_t *ptep) 37 { 38 int i; 39 40 for (i = 0; i < PTRS_PER_PTE; i++) 41 pte_clear(NULL, 0, ptep + i); 42 } 43 44 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 45 { 46 pte_t *ptep; 47 48 ptep = (pte_t *)__pte_alloc_one_kernel(mm); 49 if (!ptep) 50 return NULL; 51 ptes_clear(ptep); 52 return ptep; 53 } 54 55 static inline pgtable_t pte_alloc_one(struct mm_struct *mm) 56 { 57 struct page *page; 58 59 page = __pte_alloc_one(mm, GFP_PGTABLE_USER); 60 if (!page) 61 return NULL; 62 ptes_clear(page_address(page)); 63 return page; 64 } 65 66 #define pmd_pgtable(pmd) pmd_page(pmd) 67 #endif /* CONFIG_MMU */ 68 69 #endif /* _XTENSA_PGALLOC_H */ 70