1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/slab.h>
5 #include <asm/pgalloc.h>
7 static struct kmem_cache
*pgd_cachep
;
8 #if PAGETABLE_LEVELS > 2
9 static struct kmem_cache
*pmd_cachep
;
12 static void pgd_ctor(void *x
)
16 memset(pgd
, 0, USER_PTRS_PER_PGD
* sizeof(pgd_t
));
17 memcpy(pgd
+ USER_PTRS_PER_PGD
,
18 swapper_pg_dir
+ USER_PTRS_PER_PGD
,
19 (PTRS_PER_PGD
- USER_PTRS_PER_PGD
) * sizeof(pgd_t
));
22 void pgtable_cache_init(void)
24 pgd_cachep
= kmem_cache_create("pgd_cache",
25 PTRS_PER_PGD
* (1<<PTE_MAGNITUDE
),
26 PAGE_SIZE
, SLAB_PANIC
, pgd_ctor
);
27 #if PAGETABLE_LEVELS > 2
28 pmd_cachep
= kmem_cache_create("pmd_cache",
29 PTRS_PER_PMD
* (1<<PTE_MAGNITUDE
),
30 PAGE_SIZE
, SLAB_PANIC
, NULL
);
34 pgd_t
*pgd_alloc(struct mm_struct
*mm
)
36 return kmem_cache_alloc(pgd_cachep
, GFP_KERNEL
);
39 void pgd_free(struct mm_struct
*mm
, pgd_t
*pgd
)
41 kmem_cache_free(pgd_cachep
, pgd
);
44 #if PAGETABLE_LEVELS > 2
45 void pud_populate(struct mm_struct
*mm
, pud_t
*pud
, pmd_t
*pmd
)
47 set_pud(pud
, __pud((unsigned long)pmd
));
50 pmd_t
*pmd_alloc_one(struct mm_struct
*mm
, unsigned long address
)
52 return kmem_cache_alloc(pmd_cachep
, GFP_KERNEL
| __GFP_ZERO
);
55 void pmd_free(struct mm_struct
*mm
, pmd_t
*pmd
)
57 kmem_cache_free(pmd_cachep
, pmd
);
59 #endif /* PAGETABLE_LEVELS > 2 */