xref: /openbmc/linux/arch/sh/mm/pgtable.c (revision 2a5eacca85d39d8b6dffae821d7d260f05584dc7)
1*2a5eaccaSMatt Fleming #include <linux/mm.h>
2*2a5eaccaSMatt Fleming 
3*2a5eaccaSMatt Fleming #define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
4*2a5eaccaSMatt Fleming 
5*2a5eaccaSMatt Fleming static struct kmem_cache *pgd_cachep;
6*2a5eaccaSMatt Fleming 
7*2a5eaccaSMatt Fleming #ifdef CONFIG_PGTABLE_LEVELS_3
8*2a5eaccaSMatt Fleming static struct kmem_cache *pmd_cachep;
9*2a5eaccaSMatt Fleming #endif
10*2a5eaccaSMatt Fleming 
11*2a5eaccaSMatt Fleming void pgd_ctor(void *x)
12*2a5eaccaSMatt Fleming {
13*2a5eaccaSMatt Fleming 	pgd_t *pgd = x;
14*2a5eaccaSMatt Fleming 
15*2a5eaccaSMatt Fleming 	memcpy(pgd + USER_PTRS_PER_PGD,
16*2a5eaccaSMatt Fleming 	       swapper_pg_dir + USER_PTRS_PER_PGD,
17*2a5eaccaSMatt Fleming 	       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
18*2a5eaccaSMatt Fleming }
19*2a5eaccaSMatt Fleming 
20*2a5eaccaSMatt Fleming void pgtable_cache_init(void)
21*2a5eaccaSMatt Fleming {
22*2a5eaccaSMatt Fleming 	pgd_cachep = kmem_cache_create("pgd_cache",
23*2a5eaccaSMatt Fleming 				       PTRS_PER_PGD * (1<<PTE_MAGNITUDE),
24*2a5eaccaSMatt Fleming 				       PAGE_SIZE, SLAB_PANIC, pgd_ctor);
25*2a5eaccaSMatt Fleming #ifdef CONFIG_PGTABLE_LEVELS_3
26*2a5eaccaSMatt Fleming 	pmd_cachep = kmem_cache_create("pmd_cache",
27*2a5eaccaSMatt Fleming 				       PTRS_PER_PMD * (1<<PTE_MAGNITUDE),
28*2a5eaccaSMatt Fleming 				       PAGE_SIZE, SLAB_PANIC, NULL);
29*2a5eaccaSMatt Fleming #endif
30*2a5eaccaSMatt Fleming }
31*2a5eaccaSMatt Fleming 
32*2a5eaccaSMatt Fleming pgd_t *pgd_alloc(struct mm_struct *mm)
33*2a5eaccaSMatt Fleming {
34*2a5eaccaSMatt Fleming 	return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
35*2a5eaccaSMatt Fleming }
36*2a5eaccaSMatt Fleming 
37*2a5eaccaSMatt Fleming void pgd_free(struct mm_struct *mm, pgd_t *pgd)
38*2a5eaccaSMatt Fleming {
39*2a5eaccaSMatt Fleming 	kmem_cache_free(pgd_cachep, pgd);
40*2a5eaccaSMatt Fleming }
41*2a5eaccaSMatt Fleming 
42*2a5eaccaSMatt Fleming #ifdef CONFIG_PGTABLE_LEVELS_3
43*2a5eaccaSMatt Fleming void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
44*2a5eaccaSMatt Fleming {
45*2a5eaccaSMatt Fleming 	set_pud(pud, __pud((unsigned long)pmd));
46*2a5eaccaSMatt Fleming }
47*2a5eaccaSMatt Fleming 
48*2a5eaccaSMatt Fleming pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
49*2a5eaccaSMatt Fleming {
50*2a5eaccaSMatt Fleming 	return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
51*2a5eaccaSMatt Fleming }
52*2a5eaccaSMatt Fleming 
53*2a5eaccaSMatt Fleming void pmd_free(struct mm_struct *mm, pmd_t *pmd)
54*2a5eaccaSMatt Fleming {
55*2a5eaccaSMatt Fleming 	kmem_cache_free(pmd_cachep, pmd);
56*2a5eaccaSMatt Fleming }
57*2a5eaccaSMatt Fleming #endif /* CONFIG_PGTABLE_LEVELS_3 */
58