1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/slab.h>
5 #define PGALLOC_GFP GFP_KERNEL | __GFP_ZERO
7 static struct kmem_cache
*pgd_cachep
;
8 #if PAGETABLE_LEVELS > 2
9 static struct kmem_cache
*pmd_cachep
;
12 void pgd_ctor(void *x
)
16 memcpy(pgd
+ USER_PTRS_PER_PGD
,
17 swapper_pg_dir
+ USER_PTRS_PER_PGD
,
18 (PTRS_PER_PGD
- USER_PTRS_PER_PGD
) * sizeof(pgd_t
));
21 void pgtable_cache_init(void)
23 pgd_cachep
= kmem_cache_create("pgd_cache",
24 PTRS_PER_PGD
* (1<<PTE_MAGNITUDE
),
25 PAGE_SIZE
, SLAB_PANIC
, pgd_ctor
);
26 #if PAGETABLE_LEVELS > 2
27 pmd_cachep
= kmem_cache_create("pmd_cache",
28 PTRS_PER_PMD
* (1<<PTE_MAGNITUDE
),
29 PAGE_SIZE
, SLAB_PANIC
, NULL
);
33 pgd_t
*pgd_alloc(struct mm_struct
*mm
)
35 return kmem_cache_alloc(pgd_cachep
, PGALLOC_GFP
);
38 void pgd_free(struct mm_struct
*mm
, pgd_t
*pgd
)
40 kmem_cache_free(pgd_cachep
, pgd
);
43 #if PAGETABLE_LEVELS > 2
44 void pud_populate(struct mm_struct
*mm
, pud_t
*pud
, pmd_t
*pmd
)
46 set_pud(pud
, __pud((unsigned long)pmd
));
49 pmd_t
*pmd_alloc_one(struct mm_struct
*mm
, unsigned long address
)
51 return kmem_cache_alloc(pmd_cachep
, PGALLOC_GFP
);
54 void pmd_free(struct mm_struct
*mm
, pmd_t
*pmd
)
56 kmem_cache_free(pmd_cachep
, pmd
);
58 #endif /* PAGETABLE_LEVELS > 2 */