2012-03-05 11:49:27 +00:00
/*
* PGD allocation / freeing
*
* Copyright ( C ) 2012 ARM Ltd .
* Author : Catalin Marinas < catalin . marinas @ arm . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/mm.h>
# include <linux/gfp.h>
# include <linux/highmem.h>
# include <linux/slab.h>
# include <asm/pgalloc.h>
# include <asm/page.h>
# include <asm/tlbflush.h>
2017-11-22 21:43:59 +09:00
static struct kmem_cache * pgd_cache __ro_after_init ;
2014-10-10 15:37:28 +01:00
2012-03-05 11:49:27 +00:00
pgd_t * pgd_alloc ( struct mm_struct * mm )
{
if ( PGD_SIZE = = PAGE_SIZE )
2014-11-19 17:44:12 +00:00
return ( pgd_t * ) __get_free_page ( PGALLOC_GFP ) ;
2012-03-05 11:49:27 +00:00
else
2014-11-19 17:44:12 +00:00
return kmem_cache_alloc ( pgd_cache , PGALLOC_GFP ) ;
2012-03-05 11:49:27 +00:00
}
void pgd_free ( struct mm_struct * mm , pgd_t * pgd )
{
if ( PGD_SIZE = = PAGE_SIZE )
free_page ( ( unsigned long ) pgd ) ;
else
2014-10-10 15:37:28 +01:00
kmem_cache_free ( pgd_cache , pgd ) ;
}
2016-01-05 15:36:59 +00:00
void __init pgd_cache_init ( void )
2014-10-10 15:37:28 +01:00
{
2016-01-05 15:36:59 +00:00
if ( PGD_SIZE = = PAGE_SIZE )
return ;
2017-12-13 17:07:18 +00:00
# ifdef CONFIG_ARM64_PA_BITS_52
/*
* With 52 - bit physical addresses , the architecture requires the
* top - level table to be aligned to at least 64 bytes .
*/
BUILD_BUG_ON ( PGD_SIZE < 64 ) ;
# endif
2014-10-10 15:37:28 +01:00
/*
* Naturally aligned pgds required by the architecture .
*/
2016-01-05 15:36:59 +00:00
pgd_cache = kmem_cache_create ( " pgd_cache " , PGD_SIZE , PGD_SIZE ,
SLAB_PANIC , NULL ) ;
2012-03-05 11:49:27 +00:00
}