xref: /linux/arch/xtensa/include/asm/pgalloc.h (revision 0e9ab8e4d44ae9d9aaf213bfd2c90bbe7289337b)
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 
29 static inline pgd_t*
30 pgd_alloc(struct mm_struct *mm)
31 {
32 	return (pgd_t*) __get_free_page(GFP_KERNEL | __GFP_ZERO);
33 }
34 
35 static inline void ptes_clear(pte_t *ptep)
36 {
37 	int i;
38 
39 	for (i = 0; i < PTRS_PER_PTE; i++)
40 		pte_clear(NULL, 0, ptep + i);
41 }
42 
43 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
44 {
45 	pte_t *ptep;
46 
47 	ptep = (pte_t *)__pte_alloc_one_kernel(mm);
48 	if (!ptep)
49 		return NULL;
50 	ptes_clear(ptep);
51 	return ptep;
52 }
53 
54 static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
55 {
56 	struct page *page;
57 
58 	page = __pte_alloc_one(mm, GFP_PGTABLE_USER);
59 	if (!page)
60 		return NULL;
61 	ptes_clear(page_address(page));
62 	return page;
63 }
64 
65 #endif /* CONFIG_MMU */
66 
67 #endif /* _XTENSA_PGALLOC_H */
68