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