2008-07-17 21:55:51 -07:00
# ifndef _SPARC64_PGALLOC_H
# define _SPARC64_PGALLOC_H
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/mm.h>
# include <linux/slab.h>
# include <asm/spitfire.h>
# include <asm/cpudata.h>
# include <asm/cacheflush.h>
# include <asm/page.h>
/* Page table allocation/freeing. */
2011-07-25 17:12:20 -07:00
extern struct kmem_cache * pgtable_cache ;
2014-09-26 21:19:46 -07:00
static inline void __pgd_populate ( pgd_t * pgd , pud_t * pud )
{
pgd_set ( pgd , pud ) ;
}
# define pgd_populate(MM, PGD, PUD) __pgd_populate(PGD, PUD)
2008-07-17 21:55:51 -07:00
static inline pgd_t * pgd_alloc ( struct mm_struct * mm )
{
2011-07-25 17:12:20 -07:00
return kmem_cache_alloc ( pgtable_cache , GFP_KERNEL ) ;
2008-07-17 21:55:51 -07:00
}
static inline void pgd_free ( struct mm_struct * mm , pgd_t * pgd )
{
2011-07-25 17:12:20 -07:00
kmem_cache_free ( pgtable_cache , pgd ) ;
2008-07-17 21:55:51 -07:00
}
2014-09-26 21:19:46 -07:00
static inline void __pud_populate ( pud_t * pud , pmd_t * pmd )
{
pud_set ( pud , pmd ) ;
}
# define pud_populate(MM, PUD, PMD) __pud_populate(PUD, PMD)
static inline pud_t * pud_alloc_one ( struct mm_struct * mm , unsigned long addr )
{
2016-06-24 14:49:14 -07:00
return kmem_cache_alloc ( pgtable_cache , GFP_KERNEL ) ;
2014-09-26 21:19:46 -07:00
}
static inline void pud_free ( struct mm_struct * mm , pud_t * pud )
{
kmem_cache_free ( pgtable_cache , pud ) ;
}
2008-07-17 21:55:51 -07:00
static inline pmd_t * pmd_alloc_one ( struct mm_struct * mm , unsigned long addr )
{
2016-06-24 14:49:14 -07:00
return kmem_cache_alloc ( pgtable_cache , GFP_KERNEL ) ;
2008-07-17 21:55:51 -07:00
}
static inline void pmd_free ( struct mm_struct * mm , pmd_t * pmd )
{
2011-07-25 17:12:20 -07:00
kmem_cache_free ( pgtable_cache , pmd ) ;
2008-07-17 21:55:51 -07:00
}
2014-05-16 23:25:50 +02:00
pte_t * pte_alloc_one_kernel ( struct mm_struct * mm ,
unsigned long address ) ;
pgtable_t pte_alloc_one ( struct mm_struct * mm ,
unsigned long address ) ;
void pte_free_kernel ( struct mm_struct * mm , pte_t * pte ) ;
void pte_free ( struct mm_struct * mm , pgtable_t ptepage ) ;
2008-07-17 21:55:51 -07:00
2012-10-08 16:34:29 -07:00
# define pmd_populate_kernel(MM, PMD, PTE) pmd_set(MM, PMD, PTE)
# define pmd_populate(MM, PMD, PTE) pmd_set(MM, PMD, PTE)
2012-10-08 16:34:22 -07:00
# define pmd_pgtable(PMD) ((pte_t *)__pmd_page(PMD))
2008-07-17 21:55:51 -07:00
2011-07-25 17:12:20 -07:00
# define check_pgt_cache() do { } while (0)
2008-07-17 21:55:51 -07:00
2014-05-16 23:25:50 +02:00
void pgtable_free ( void * table , bool is_page ) ;
2011-07-25 17:12:21 -07:00
# ifdef CONFIG_SMP
struct mmu_gather ;
2014-05-16 23:25:50 +02:00
void tlb_remove_table ( struct mmu_gather * , void * ) ;
2011-07-25 17:12:21 -07:00
static inline void pgtable_free_tlb ( struct mmu_gather * tlb , void * table , bool is_page )
{
unsigned long pgf = ( unsigned long ) table ;
if ( is_page )
pgf | = 0x1UL ;
tlb_remove_table ( tlb , ( void * ) pgf ) ;
}
static inline void __tlb_remove_table ( void * _table )
{
void * table = ( void * ) ( ( unsigned long ) _table & ~ 0x1UL ) ;
bool is_page = false ;
if ( ( unsigned long ) _table & 0x1UL )
is_page = true ;
pgtable_free ( table , is_page ) ;
}
# else /* CONFIG_SMP */
static inline void pgtable_free_tlb ( struct mmu_gather * tlb , void * table , bool is_page )
{
pgtable_free ( table , is_page ) ;
}
# endif /* !CONFIG_SMP */
2012-10-08 16:34:22 -07:00
static inline void __pte_free_tlb ( struct mmu_gather * tlb , pte_t * pte ,
2011-07-25 17:12:21 -07:00
unsigned long address )
{
2012-10-08 16:34:22 -07:00
pgtable_free_tlb ( tlb , pte , true ) ;
2011-07-25 17:12:21 -07:00
}
# define __pmd_free_tlb(tlb, pmd, addr) \
pgtable_free_tlb ( tlb , pmd , false )
2011-05-24 17:11:50 -07:00
2014-09-26 21:19:46 -07:00
# define __pud_free_tlb(tlb, pud, addr) \
pgtable_free_tlb ( tlb , pud , false )
2008-07-17 21:55:51 -07:00
# endif /* _SPARC64_PGALLOC_H */