1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * PGD allocation/freeing 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2012 ARM Ltd. 6*4882a593Smuzhiyun * Author: Catalin Marinas <catalin.marinas@arm.com> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <linux/mm.h> 10*4882a593Smuzhiyun #include <linux/gfp.h> 11*4882a593Smuzhiyun #include <linux/highmem.h> 12*4882a593Smuzhiyun #include <linux/slab.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include <asm/pgalloc.h> 15*4882a593Smuzhiyun #include <asm/page.h> 16*4882a593Smuzhiyun #include <asm/tlbflush.h> 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun static struct kmem_cache *pgd_cache __ro_after_init; 19*4882a593Smuzhiyun pgd_alloc(struct mm_struct * mm)20*4882a593Smuzhiyunpgd_t *pgd_alloc(struct mm_struct *mm) 21*4882a593Smuzhiyun { 22*4882a593Smuzhiyun gfp_t gfp = GFP_PGTABLE_USER; 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun if (PGD_SIZE == PAGE_SIZE) 25*4882a593Smuzhiyun return (pgd_t *)__get_free_page(gfp); 26*4882a593Smuzhiyun else 27*4882a593Smuzhiyun return kmem_cache_alloc(pgd_cache, gfp); 28*4882a593Smuzhiyun } 29*4882a593Smuzhiyun pgd_free(struct mm_struct * mm,pgd_t * pgd)30*4882a593Smuzhiyunvoid pgd_free(struct mm_struct *mm, pgd_t *pgd) 31*4882a593Smuzhiyun { 32*4882a593Smuzhiyun if (PGD_SIZE == PAGE_SIZE) 33*4882a593Smuzhiyun free_page((unsigned long)pgd); 34*4882a593Smuzhiyun else 35*4882a593Smuzhiyun kmem_cache_free(pgd_cache, pgd); 36*4882a593Smuzhiyun } 37*4882a593Smuzhiyun pgtable_cache_init(void)38*4882a593Smuzhiyunvoid __init pgtable_cache_init(void) 39*4882a593Smuzhiyun { 40*4882a593Smuzhiyun if (PGD_SIZE == PAGE_SIZE) 41*4882a593Smuzhiyun return; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #ifdef CONFIG_ARM64_PA_BITS_52 44*4882a593Smuzhiyun /* 45*4882a593Smuzhiyun * With 52-bit physical addresses, the architecture requires the 46*4882a593Smuzhiyun * top-level table to be aligned to at least 64 bytes. 47*4882a593Smuzhiyun */ 48*4882a593Smuzhiyun BUILD_BUG_ON(PGD_SIZE < 64); 49*4882a593Smuzhiyun #endif 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun /* 52*4882a593Smuzhiyun * Naturally aligned pgds required by the architecture. 53*4882a593Smuzhiyun */ 54*4882a593Smuzhiyun pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE, 55*4882a593Smuzhiyun SLAB_PANIC, NULL); 56*4882a593Smuzhiyun } 57