Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * PGD allocation/freeing
0004  *
0005  * Copyright (C) 2012 ARM Ltd.
0006  * Author: Catalin Marinas <catalin.marinas@arm.com>
0007  */
0008 
0009 #include <linux/mm.h>
0010 #include <linux/gfp.h>
0011 #include <linux/highmem.h>
0012 #include <linux/slab.h>
0013 
0014 #include <asm/pgalloc.h>
0015 #include <asm/page.h>
0016 #include <asm/tlbflush.h>
0017 
0018 static struct kmem_cache *pgd_cache __ro_after_init;
0019 
0020 pgd_t *pgd_alloc(struct mm_struct *mm)
0021 {
0022     gfp_t gfp = GFP_PGTABLE_USER;
0023 
0024     if (PGD_SIZE == PAGE_SIZE)
0025         return (pgd_t *)__get_free_page(gfp);
0026     else
0027         return kmem_cache_alloc(pgd_cache, gfp);
0028 }
0029 
0030 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
0031 {
0032     if (PGD_SIZE == PAGE_SIZE)
0033         free_page((unsigned long)pgd);
0034     else
0035         kmem_cache_free(pgd_cache, pgd);
0036 }
0037 
0038 void __init pgtable_cache_init(void)
0039 {
0040     if (PGD_SIZE == PAGE_SIZE)
0041         return;
0042 
0043 #ifdef CONFIG_ARM64_PA_BITS_52
0044     /*
0045      * With 52-bit physical addresses, the architecture requires the
0046      * top-level table to be aligned to at least 64 bytes.
0047      */
0048     BUILD_BUG_ON(PGD_SIZE < 64);
0049 #endif
0050 
0051     /*
0052      * Naturally aligned pgds required by the architecture.
0053      */
0054     pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
0055                       SLAB_PANIC, NULL);
0056 }