xref: /openbmc/linux/arch/arm64/mm/pgd.c (revision 39b5be9b)
11d18c47cSCatalin Marinas /*
21d18c47cSCatalin Marinas  * PGD allocation/freeing
31d18c47cSCatalin Marinas  *
41d18c47cSCatalin Marinas  * Copyright (C) 2012 ARM Ltd.
51d18c47cSCatalin Marinas  * Author: Catalin Marinas <catalin.marinas@arm.com>
61d18c47cSCatalin Marinas  *
71d18c47cSCatalin Marinas  * This program is free software; you can redistribute it and/or modify
81d18c47cSCatalin Marinas  * it under the terms of the GNU General Public License version 2 as
91d18c47cSCatalin Marinas  * published by the Free Software Foundation.
101d18c47cSCatalin Marinas  *
111d18c47cSCatalin Marinas  * This program is distributed in the hope that it will be useful,
121d18c47cSCatalin Marinas  * but WITHOUT ANY WARRANTY; without even the implied warranty of
131d18c47cSCatalin Marinas  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
141d18c47cSCatalin Marinas  * GNU General Public License for more details.
151d18c47cSCatalin Marinas  *
161d18c47cSCatalin Marinas  * You should have received a copy of the GNU General Public License
171d18c47cSCatalin Marinas  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
181d18c47cSCatalin Marinas  */
191d18c47cSCatalin Marinas 
201d18c47cSCatalin Marinas #include <linux/mm.h>
211d18c47cSCatalin Marinas #include <linux/gfp.h>
221d18c47cSCatalin Marinas #include <linux/highmem.h>
231d18c47cSCatalin Marinas #include <linux/slab.h>
241d18c47cSCatalin Marinas 
251d18c47cSCatalin Marinas #include <asm/pgalloc.h>
261d18c47cSCatalin Marinas #include <asm/page.h>
271d18c47cSCatalin Marinas #include <asm/tlbflush.h>
281d18c47cSCatalin Marinas 
291d18c47cSCatalin Marinas #include "mm.h"
301d18c47cSCatalin Marinas 
312a0b5c0dSCatalin Marinas static struct kmem_cache *pgd_cache;
322a0b5c0dSCatalin Marinas 
331d18c47cSCatalin Marinas pgd_t *pgd_alloc(struct mm_struct *mm)
341d18c47cSCatalin Marinas {
351d18c47cSCatalin Marinas 	if (PGD_SIZE == PAGE_SIZE)
3615670ef1SMark Rutland 		return (pgd_t *)__get_free_page(PGALLOC_GFP);
371d18c47cSCatalin Marinas 	else
3815670ef1SMark Rutland 		return kmem_cache_alloc(pgd_cache, PGALLOC_GFP);
391d18c47cSCatalin Marinas }
401d18c47cSCatalin Marinas 
411d18c47cSCatalin Marinas void pgd_free(struct mm_struct *mm, pgd_t *pgd)
421d18c47cSCatalin Marinas {
431d18c47cSCatalin Marinas 	if (PGD_SIZE == PAGE_SIZE)
441d18c47cSCatalin Marinas 		free_page((unsigned long)pgd);
451d18c47cSCatalin Marinas 	else
462a0b5c0dSCatalin Marinas 		kmem_cache_free(pgd_cache, pgd);
471d18c47cSCatalin Marinas }
482a0b5c0dSCatalin Marinas 
4939b5be9bSWill Deacon void __init pgd_cache_init(void)
502a0b5c0dSCatalin Marinas {
5139b5be9bSWill Deacon 	if (PGD_SIZE == PAGE_SIZE)
5239b5be9bSWill Deacon 		return;
5339b5be9bSWill Deacon 
542a0b5c0dSCatalin Marinas 	/*
552a0b5c0dSCatalin Marinas 	 * Naturally aligned pgds required by the architecture.
562a0b5c0dSCatalin Marinas 	 */
572a0b5c0dSCatalin Marinas 	pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
582a0b5c0dSCatalin Marinas 				      SLAB_PANIC, NULL);
592a0b5c0dSCatalin Marinas }
60