162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 362306a36Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 462306a36Sopenharmony_ci * for more details. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 1994 - 2001, 2003 by Ralf Baechle 762306a36Sopenharmony_ci * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc. 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#ifndef _ASM_PGALLOC_H 1062306a36Sopenharmony_ci#define _ASM_PGALLOC_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/highmem.h> 1362306a36Sopenharmony_ci#include <linux/mm.h> 1462306a36Sopenharmony_ci#include <linux/sched.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define __HAVE_ARCH_PMD_ALLOC_ONE 1762306a36Sopenharmony_ci#define __HAVE_ARCH_PUD_ALLOC_ONE 1862306a36Sopenharmony_ci#define __HAVE_ARCH_PGD_FREE 1962306a36Sopenharmony_ci#include <asm-generic/pgalloc.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 2262306a36Sopenharmony_ci pte_t *pte) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci set_pmd(pmd, __pmd((unsigned long)pte)); 2562306a36Sopenharmony_ci} 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, 2862306a36Sopenharmony_ci pgtable_t pte) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci set_pmd(pmd, __pmd((unsigned long)page_address(pte))); 3162306a36Sopenharmony_ci} 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* 3462306a36Sopenharmony_ci * Initialize a new pmd table with invalid pointers. 3562306a36Sopenharmony_ci */ 3662306a36Sopenharmony_ciextern void pmd_init(void *addr); 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci set_pud(pud, __pud((unsigned long)pmd)); 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci#endif 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* 4762306a36Sopenharmony_ci * Initialize a new pgd table with invalid pointers. 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_ciextern void pgd_init(void *addr); 5062306a36Sopenharmony_ciextern pgd_t *pgd_alloc(struct mm_struct *mm); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci pagetable_free(virt_to_ptdesc(pgd)); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define __pte_free_tlb(tlb, pte, address) \ 5862306a36Sopenharmony_cido { \ 5962306a36Sopenharmony_ci pagetable_pte_dtor(page_ptdesc(pte)); \ 6062306a36Sopenharmony_ci tlb_remove_page_ptdesc((tlb), page_ptdesc(pte)); \ 6162306a36Sopenharmony_ci} while (0) 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_cistatic inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci pmd_t *pmd; 6862306a36Sopenharmony_ci struct ptdesc *ptdesc; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci ptdesc = pagetable_alloc(GFP_KERNEL_ACCOUNT, PMD_TABLE_ORDER); 7162306a36Sopenharmony_ci if (!ptdesc) 7262306a36Sopenharmony_ci return NULL; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if (!pagetable_pmd_ctor(ptdesc)) { 7562306a36Sopenharmony_ci pagetable_free(ptdesc); 7662306a36Sopenharmony_ci return NULL; 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci pmd = ptdesc_address(ptdesc); 8062306a36Sopenharmony_ci pmd_init(pmd); 8162306a36Sopenharmony_ci return pmd; 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci#define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#endif 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#ifndef __PAGETABLE_PUD_FOLDED 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci pud_t *pud; 9362306a36Sopenharmony_ci struct ptdesc *ptdesc = pagetable_alloc(GFP_KERNEL & ~__GFP_HIGHMEM, 9462306a36Sopenharmony_ci PUD_TABLE_ORDER); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci if (!ptdesc) 9762306a36Sopenharmony_ci return NULL; 9862306a36Sopenharmony_ci pud = ptdesc_address(ptdesc); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci pud_init(pud); 10162306a36Sopenharmony_ci return pud; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic inline void p4d_populate(struct mm_struct *mm, p4d_t *p4d, pud_t *pud) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci set_p4d(p4d, __p4d((unsigned long)pud)); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci#define __pud_free_tlb(tlb, x, addr) pud_free((tlb)->mm, x) 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci#endif /* __PAGETABLE_PUD_FOLDED */ 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ciextern void pagetable_init(void); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#endif /* _ASM_PGALLOC_H */ 116