1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2f15cbe6fSPaul Mundt #ifndef __ASM_SH_PGALLOC_H 3f15cbe6fSPaul Mundt #define __ASM_SH_PGALLOC_H 4f15cbe6fSPaul Mundt 5f15cbe6fSPaul Mundt #include <linux/quicklist.h> 6f15cbe6fSPaul Mundt #include <asm/page.h> 7f15cbe6fSPaul Mundt 80176bd3dSPaul Mundt #define QUICK_PT 0 /* Other page table pages that are zero on free */ 9f15cbe6fSPaul Mundt 102a5eaccaSMatt Fleming extern pgd_t *pgd_alloc(struct mm_struct *); 112a5eaccaSMatt Fleming extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); 122a5eaccaSMatt Fleming 13782bb5a5SPaul Mundt #if PAGETABLE_LEVELS > 2 142a5eaccaSMatt Fleming extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); 152a5eaccaSMatt Fleming extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address); 162a5eaccaSMatt Fleming extern void pmd_free(struct mm_struct *mm, pmd_t *pmd); 175d9b4b19SMatt Fleming #endif 18b73c8063SMatt Fleming 19f15cbe6fSPaul Mundt static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 20f15cbe6fSPaul Mundt pte_t *pte) 21f15cbe6fSPaul Mundt { 22f15cbe6fSPaul Mundt set_pmd(pmd, __pmd((unsigned long)pte)); 23f15cbe6fSPaul Mundt } 24f15cbe6fSPaul Mundt 25f15cbe6fSPaul Mundt static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 26f15cbe6fSPaul Mundt pgtable_t pte) 27f15cbe6fSPaul Mundt { 28f15cbe6fSPaul Mundt set_pmd(pmd, __pmd((unsigned long)page_address(pte))); 29f15cbe6fSPaul Mundt } 30f15cbe6fSPaul Mundt #define pmd_pgtable(pmd) pmd_page(pmd) 31f15cbe6fSPaul Mundt 32f15cbe6fSPaul Mundt /* 33f15cbe6fSPaul Mundt * Allocate and free page tables. 34f15cbe6fSPaul Mundt */ 354cf58924SJoel Fernandes (Google) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) 36f15cbe6fSPaul Mundt { 3732d6bd90SMichal Hocko return quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL); 38f15cbe6fSPaul Mundt } 39f15cbe6fSPaul Mundt 404cf58924SJoel Fernandes (Google) static inline pgtable_t pte_alloc_one(struct mm_struct *mm) 41f15cbe6fSPaul Mundt { 42f15cbe6fSPaul Mundt struct page *page; 43f15cbe6fSPaul Mundt void *pg; 44f15cbe6fSPaul Mundt 4532d6bd90SMichal Hocko pg = quicklist_alloc(QUICK_PT, GFP_KERNEL, NULL); 46f15cbe6fSPaul Mundt if (!pg) 47f15cbe6fSPaul Mundt return NULL; 48f15cbe6fSPaul Mundt page = virt_to_page(pg); 49478cf8caSKirill A. Shutemov if (!pgtable_page_ctor(page)) { 50478cf8caSKirill A. Shutemov quicklist_free(QUICK_PT, NULL, pg); 51478cf8caSKirill A. Shutemov return NULL; 52478cf8caSKirill A. Shutemov } 53f15cbe6fSPaul Mundt return page; 54f15cbe6fSPaul Mundt } 55f15cbe6fSPaul Mundt 56f15cbe6fSPaul Mundt static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 57f15cbe6fSPaul Mundt { 58f15cbe6fSPaul Mundt quicklist_free(QUICK_PT, NULL, pte); 59f15cbe6fSPaul Mundt } 60f15cbe6fSPaul Mundt 61f15cbe6fSPaul Mundt static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 62f15cbe6fSPaul Mundt { 63f15cbe6fSPaul Mundt pgtable_page_dtor(pte); 64f15cbe6fSPaul Mundt quicklist_free_page(QUICK_PT, NULL, pte); 65f15cbe6fSPaul Mundt } 66f15cbe6fSPaul Mundt 679e1b32caSBenjamin Herrenschmidt #define __pte_free_tlb(tlb,pte,addr) \ 68f15cbe6fSPaul Mundt do { \ 69f15cbe6fSPaul Mundt pgtable_page_dtor(pte); \ 70f15cbe6fSPaul Mundt tlb_remove_page((tlb), (pte)); \ 71f15cbe6fSPaul Mundt } while (0) 72f15cbe6fSPaul Mundt 73*c5b27a88SPeter Zijlstra #if CONFIG_PGTABLE_LEVELS > 2 74*c5b27a88SPeter Zijlstra #define __pmd_free_tlb(tlb, pmdp, addr) \ 75*c5b27a88SPeter Zijlstra do { \ 76*c5b27a88SPeter Zijlstra struct page *page = virt_to_page(pmdp); \ 77*c5b27a88SPeter Zijlstra pgtable_pmd_page_dtor(page); \ 78*c5b27a88SPeter Zijlstra tlb_remove_page((tlb), page); \ 79*c5b27a88SPeter Zijlstra } while (0); 80*c5b27a88SPeter Zijlstra #endif 81*c5b27a88SPeter Zijlstra 82f15cbe6fSPaul Mundt static inline void check_pgt_cache(void) 83f15cbe6fSPaul Mundt { 84f15cbe6fSPaul Mundt quicklist_trim(QUICK_PT, NULL, 25, 16); 85f15cbe6fSPaul Mundt } 86f15cbe6fSPaul Mundt 87f15cbe6fSPaul Mundt #endif /* __ASM_SH_PGALLOC_H */ 88