1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _MOTOROLA_PGALLOC_H 3 #define _MOTOROLA_PGALLOC_H 4 5 #include <asm/tlb.h> 6 #include <asm/tlbflush.h> 7 8 extern pmd_t *get_pointer_table(void); 9 extern int free_pointer_table(pmd_t *); 10 11 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 12 { 13 pte_t *pte; 14 15 pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_ZERO); 16 if (pte) { 17 __flush_page_to_ram(pte); 18 flush_tlb_kernel_page(pte); 19 nocache_page(pte); 20 } 21 22 return pte; 23 } 24 25 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 26 { 27 cache_page(pte); 28 free_page((unsigned long) pte); 29 } 30 31 static inline pgtable_t pte_alloc_one(struct mm_struct *mm) 32 { 33 struct page *page; 34 pte_t *pte; 35 36 page = alloc_pages(GFP_KERNEL|__GFP_ZERO, 0); 37 if(!page) 38 return NULL; 39 if (!pgtable_pte_page_ctor(page)) { 40 __free_page(page); 41 return NULL; 42 } 43 44 pte = kmap(page); 45 __flush_page_to_ram(pte); 46 flush_tlb_kernel_page(pte); 47 nocache_page(pte); 48 kunmap(page); 49 return page; 50 } 51 52 static inline void pte_free(struct mm_struct *mm, pgtable_t page) 53 { 54 pgtable_pte_page_dtor(page); 55 cache_page(kmap(page)); 56 kunmap(page); 57 __free_page(page); 58 } 59 60 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page, 61 unsigned long address) 62 { 63 pgtable_pte_page_dtor(page); 64 cache_page(kmap(page)); 65 kunmap(page); 66 __free_page(page); 67 } 68 69 70 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) 71 { 72 return get_pointer_table(); 73 } 74 75 static inline int pmd_free(struct mm_struct *mm, pmd_t *pmd) 76 { 77 return free_pointer_table(pmd); 78 } 79 80 static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, 81 unsigned long address) 82 { 83 return free_pointer_table(pmd); 84 } 85 86 87 static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 88 { 89 pmd_free(mm, (pmd_t *)pgd); 90 } 91 92 static inline pgd_t *pgd_alloc(struct mm_struct *mm) 93 { 94 return (pgd_t *)get_pointer_table(); 95 } 96 97 98 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) 99 { 100 pmd_set(pmd, pte); 101 } 102 103 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) 104 { 105 pmd_set(pmd, page_address(page)); 106 } 107 #define pmd_pgtable(pmd) pmd_page(pmd) 108 109 static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 110 { 111 pud_set(pud, pmd); 112 } 113 114 #endif /* _MOTOROLA_PGALLOC_H */ 115