0001
0002
0003
0004
0005
0006
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
0046
0047
0048 BUILD_BUG_ON(PGD_SIZE < 64);
0049 #endif
0050
0051
0052
0053
0054 pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
0055 SLAB_PANIC, NULL);
0056 }