Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2a5eacca | 2 | #include <linux/mm.h> |
5a0e3ad6 | 3 | #include <linux/slab.h> |
2a5eacca | 4 | |
884ed4cb | 5 | #define PGALLOC_GFP GFP_KERNEL | __GFP_ZERO |
2a5eacca MF |
6 | |
7 | static struct kmem_cache *pgd_cachep; | |
782bb5a5 | 8 | #if PAGETABLE_LEVELS > 2 |
2a5eacca MF |
9 | static struct kmem_cache *pmd_cachep; |
10 | #endif | |
11 | ||
12 | void pgd_ctor(void *x) | |
13 | { | |
14 | pgd_t *pgd = x; | |
15 | ||
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)); | |
19 | } | |
20 | ||
21 | void pgtable_cache_init(void) | |
22 | { | |
23 | pgd_cachep = kmem_cache_create("pgd_cache", | |
24 | PTRS_PER_PGD * (1<<PTE_MAGNITUDE), | |
25 | PAGE_SIZE, SLAB_PANIC, pgd_ctor); | |
782bb5a5 | 26 | #if PAGETABLE_LEVELS > 2 |
2a5eacca MF |
27 | pmd_cachep = kmem_cache_create("pmd_cache", |
28 | PTRS_PER_PMD * (1<<PTE_MAGNITUDE), | |
29 | PAGE_SIZE, SLAB_PANIC, NULL); | |
30 | #endif | |
31 | } | |
32 | ||
33 | pgd_t *pgd_alloc(struct mm_struct *mm) | |
34 | { | |
35 | return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP); | |
36 | } | |
37 | ||
38 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |
39 | { | |
40 | kmem_cache_free(pgd_cachep, pgd); | |
41 | } | |
42 | ||
782bb5a5 | 43 | #if PAGETABLE_LEVELS > 2 |
2a5eacca MF |
44 | void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) |
45 | { | |
46 | set_pud(pud, __pud((unsigned long)pmd)); | |
47 | } | |
48 | ||
49 | pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | |
50 | { | |
51 | return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP); | |
52 | } | |
53 | ||
54 | void pmd_free(struct mm_struct *mm, pmd_t *pmd) | |
55 | { | |
56 | kmem_cache_free(pmd_cachep, pmd); | |
57 | } | |
782bb5a5 | 58 | #endif /* PAGETABLE_LEVELS > 2 */ |