1*f15cbe6fSPaul Mundt #ifndef __ASM_SH_PGALLOC_H 2*f15cbe6fSPaul Mundt #define __ASM_SH_PGALLOC_H 3*f15cbe6fSPaul Mundt 4*f15cbe6fSPaul Mundt #include <linux/quicklist.h> 5*f15cbe6fSPaul Mundt #include <asm/page.h> 6*f15cbe6fSPaul Mundt 7*f15cbe6fSPaul Mundt #define QUICK_PGD 0 /* We preserve special mappings over free */ 8*f15cbe6fSPaul Mundt #define QUICK_PT 1 /* Other page table pages that are zero on free */ 9*f15cbe6fSPaul Mundt 10*f15cbe6fSPaul Mundt static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 11*f15cbe6fSPaul Mundt pte_t *pte) 12*f15cbe6fSPaul Mundt { 13*f15cbe6fSPaul Mundt set_pmd(pmd, __pmd((unsigned long)pte)); 14*f15cbe6fSPaul Mundt } 15*f15cbe6fSPaul Mundt 16*f15cbe6fSPaul Mundt static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 17*f15cbe6fSPaul Mundt pgtable_t pte) 18*f15cbe6fSPaul Mundt { 19*f15cbe6fSPaul Mundt set_pmd(pmd, __pmd((unsigned long)page_address(pte))); 20*f15cbe6fSPaul Mundt } 21*f15cbe6fSPaul Mundt #define pmd_pgtable(pmd) pmd_page(pmd) 22*f15cbe6fSPaul Mundt 23*f15cbe6fSPaul Mundt static inline void pgd_ctor(void *x) 24*f15cbe6fSPaul Mundt { 25*f15cbe6fSPaul Mundt pgd_t *pgd = x; 26*f15cbe6fSPaul Mundt 27*f15cbe6fSPaul Mundt memcpy(pgd + USER_PTRS_PER_PGD, 28*f15cbe6fSPaul Mundt swapper_pg_dir + USER_PTRS_PER_PGD, 29*f15cbe6fSPaul Mundt (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); 30*f15cbe6fSPaul Mundt } 31*f15cbe6fSPaul Mundt 32*f15cbe6fSPaul Mundt /* 33*f15cbe6fSPaul Mundt * Allocate and free page tables. 34*f15cbe6fSPaul Mundt */ 35*f15cbe6fSPaul Mundt static inline pgd_t *pgd_alloc(struct mm_struct *mm) 36*f15cbe6fSPaul Mundt { 37*f15cbe6fSPaul Mundt return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); 38*f15cbe6fSPaul Mundt } 39*f15cbe6fSPaul Mundt 40*f15cbe6fSPaul Mundt static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 41*f15cbe6fSPaul Mundt { 42*f15cbe6fSPaul Mundt quicklist_free(QUICK_PGD, NULL, pgd); 43*f15cbe6fSPaul Mundt } 44*f15cbe6fSPaul Mundt 45*f15cbe6fSPaul Mundt static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 46*f15cbe6fSPaul Mundt unsigned long address) 47*f15cbe6fSPaul Mundt { 48*f15cbe6fSPaul Mundt return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); 49*f15cbe6fSPaul Mundt } 50*f15cbe6fSPaul Mundt 51*f15cbe6fSPaul Mundt static inline pgtable_t pte_alloc_one(struct mm_struct *mm, 52*f15cbe6fSPaul Mundt unsigned long address) 53*f15cbe6fSPaul Mundt { 54*f15cbe6fSPaul Mundt struct page *page; 55*f15cbe6fSPaul Mundt void *pg; 56*f15cbe6fSPaul Mundt 57*f15cbe6fSPaul Mundt pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); 58*f15cbe6fSPaul Mundt if (!pg) 59*f15cbe6fSPaul Mundt return NULL; 60*f15cbe6fSPaul Mundt page = virt_to_page(pg); 61*f15cbe6fSPaul Mundt pgtable_page_ctor(page); 62*f15cbe6fSPaul Mundt return page; 63*f15cbe6fSPaul Mundt } 64*f15cbe6fSPaul Mundt 65*f15cbe6fSPaul Mundt static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 66*f15cbe6fSPaul Mundt { 67*f15cbe6fSPaul Mundt quicklist_free(QUICK_PT, NULL, pte); 68*f15cbe6fSPaul Mundt } 69*f15cbe6fSPaul Mundt 70*f15cbe6fSPaul Mundt static inline void pte_free(struct mm_struct *mm, pgtable_t pte) 71*f15cbe6fSPaul Mundt { 72*f15cbe6fSPaul Mundt pgtable_page_dtor(pte); 73*f15cbe6fSPaul Mundt quicklist_free_page(QUICK_PT, NULL, pte); 74*f15cbe6fSPaul Mundt } 75*f15cbe6fSPaul Mundt 76*f15cbe6fSPaul Mundt #define __pte_free_tlb(tlb,pte) \ 77*f15cbe6fSPaul Mundt do { \ 78*f15cbe6fSPaul Mundt pgtable_page_dtor(pte); \ 79*f15cbe6fSPaul Mundt tlb_remove_page((tlb), (pte)); \ 80*f15cbe6fSPaul Mundt } while (0) 81*f15cbe6fSPaul Mundt 82*f15cbe6fSPaul Mundt /* 83*f15cbe6fSPaul Mundt * allocating and freeing a pmd is trivial: the 1-entry pmd is 84*f15cbe6fSPaul Mundt * inside the pgd, so has no extra memory associated with it. 85*f15cbe6fSPaul Mundt */ 86*f15cbe6fSPaul Mundt 87*f15cbe6fSPaul Mundt #define pmd_free(mm, x) do { } while (0) 88*f15cbe6fSPaul Mundt #define __pmd_free_tlb(tlb,x) do { } while (0) 89*f15cbe6fSPaul Mundt 90*f15cbe6fSPaul Mundt static inline void check_pgt_cache(void) 91*f15cbe6fSPaul Mundt { 92*f15cbe6fSPaul Mundt quicklist_trim(QUICK_PGD, NULL, 25, 16); 93*f15cbe6fSPaul Mundt quicklist_trim(QUICK_PT, NULL, 25, 16); 94*f15cbe6fSPaul Mundt } 95*f15cbe6fSPaul Mundt 96*f15cbe6fSPaul Mundt #endif /* __ASM_SH_PGALLOC_H */ 97