2009-05-27 17:47:42 -07:00
/*
* MIPS Huge TLB Page Support for Kernel .
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*
* Copyright ( C ) 2002 , Rohit Seth < rohit . seth @ intel . com >
* Copyright 2005 , Embedded Alley Solutions , Inc .
* Matt Porter < mporter @ embeddedalley . com >
* Copyright ( C ) 2008 , 2009 Cavium Networks , Inc .
*/
# include <linux/fs.h>
# include <linux/mm.h>
# include <linux/hugetlb.h>
# include <linux/pagemap.h>
# include <linux/err.h>
# include <linux/sysctl.h>
# include <asm/mman.h>
# include <asm/tlb.h>
# include <asm/tlbflush.h>
pte_t * huge_pte_alloc ( struct mm_struct * mm , unsigned long addr ,
unsigned long sz )
{
pgd_t * pgd ;
2019-11-21 18:21:33 +02:00
p4d_t * p4d ;
2009-05-27 17:47:42 -07:00
pud_t * pud ;
pte_t * pte = NULL ;
pgd = pgd_offset ( mm , addr ) ;
2019-11-21 18:21:33 +02:00
p4d = p4d_alloc ( mm , pgd , addr ) ;
pud = pud_alloc ( mm , p4d , addr ) ;
2009-05-27 17:47:42 -07:00
if ( pud )
pte = ( pte_t * ) pmd_alloc ( mm , pud , addr ) ;
return pte ;
}
2017-07-06 15:39:42 -07:00
pte_t * huge_pte_offset ( struct mm_struct * mm , unsigned long addr ,
unsigned long sz )
2009-05-27 17:47:42 -07:00
{
pgd_t * pgd ;
2019-11-21 18:21:33 +02:00
p4d_t * p4d ;
2009-05-27 17:47:42 -07:00
pud_t * pud ;
pmd_t * pmd = NULL ;
pgd = pgd_offset ( mm , addr ) ;
if ( pgd_present ( * pgd ) ) {
2019-11-21 18:21:33 +02:00
p4d = p4d_offset ( pgd , addr ) ;
if ( p4d_present ( * p4d ) ) {
pud = pud_offset ( p4d , addr ) ;
if ( pud_present ( * pud ) )
pmd = pmd_offset ( pud , addr ) ;
}
2009-05-27 17:47:42 -07:00
}
return ( pte_t * ) pmd ;
}
/*
* This function checks for proper alignment of input addr and len parameters .
*/
int is_aligned_hugepage_range ( unsigned long addr , unsigned long len )
{
if ( len & ~ HPAGE_MASK )
return - EINVAL ;
if ( addr & ~ HPAGE_MASK )
return - EINVAL ;
return 0 ;
}
int pmd_huge ( pmd_t pmd )
{
return ( pmd_val ( pmd ) & _PAGE_HUGE ) ! = 0 ;
}
int pud_huge ( pud_t pud )
{
return ( pud_val ( pud ) & _PAGE_HUGE ) ! = 0 ;
}