aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/pgalloc.h10
-rw-r--r--arch/sh/include/asm/pgalloc_nopmd.h30
-rw-r--r--arch/sh/include/asm/pgalloc_pmd.h41
-rw-r--r--arch/sh/include/asm/pgtable.h4
-rw-r--r--arch/sh/mm/Makefile2
-rw-r--r--arch/sh/mm/pgtable.c57
6 files changed, 66 insertions, 78 deletions
diff --git a/arch/sh/include/asm/pgalloc.h b/arch/sh/include/asm/pgalloc.h
index 4ea27855c3b5..e106474996b2 100644
--- a/arch/sh/include/asm/pgalloc.h
+++ b/arch/sh/include/asm/pgalloc.h
@@ -6,10 +6,13 @@
6 6
7#define QUICK_PT 1 /* Other page table pages that are zero on free */ 7#define QUICK_PT 1 /* Other page table pages that are zero on free */
8 8
9extern pgd_t *pgd_alloc(struct mm_struct *);
10extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
11
9#ifdef CONFIG_PGTABLE_LEVELS_3 12#ifdef CONFIG_PGTABLE_LEVELS_3
10#include <asm/pgalloc_pmd.h> 13extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
11#else 14extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
12#include <asm/pgalloc_nopmd.h> 15extern void pmd_free(struct mm_struct *mm, pmd_t *pmd);
13#endif 16#endif
14 17
15static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, 18static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
@@ -67,7 +70,6 @@ do { \
67 70
68static inline void check_pgt_cache(void) 71static inline void check_pgt_cache(void)
69{ 72{
70 __check_pgt_cache();
71 quicklist_trim(QUICK_PT, NULL, 25, 16); 73 quicklist_trim(QUICK_PT, NULL, 25, 16);
72} 74}
73 75
diff --git a/arch/sh/include/asm/pgalloc_nopmd.h b/arch/sh/include/asm/pgalloc_nopmd.h
deleted file mode 100644
index e4b344c37e74..000000000000
--- a/arch/sh/include/asm/pgalloc_nopmd.h
+++ /dev/null
@@ -1,30 +0,0 @@
1#ifndef __ASM_SH_PGALLOC_NOPMD_H
2#define __ASM_SH_PGALLOC_NOPMD_H
3
4#define QUICK_PGD 0 /* We preserve special mappings over free */
5
6static inline void pgd_ctor(void *x)
7{
8 pgd_t *pgd = x;
9
10 memcpy(pgd + USER_PTRS_PER_PGD,
11 swapper_pg_dir + USER_PTRS_PER_PGD,
12 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
13}
14
15static inline pgd_t *pgd_alloc(struct mm_struct *mm)
16{
17 return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor);
18}
19
20static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
21{
22 quicklist_free(QUICK_PGD, NULL, pgd);
23}
24
25static inline void __check_pgt_cache(void)
26{
27 quicklist_trim(QUICK_PGD, NULL, 25, 16);
28}
29
30#endif /* __ASM_SH_PGALLOC_NOPMD_H */
diff --git a/arch/sh/include/asm/pgalloc_pmd.h b/arch/sh/include/asm/pgalloc_pmd.h
deleted file mode 100644
index 20f75cc4eb09..000000000000
--- a/arch/sh/include/asm/pgalloc_pmd.h
+++ /dev/null
@@ -1,41 +0,0 @@
1#ifndef __ASM_SH_PGALLOC_PMD_H
2#define __ASM_SH_PGALLOC_PMD_H
3
4static inline pgd_t *pgd_alloc(struct mm_struct *mm)
5{
6 pgd_t *pgd;
7 int i;
8
9 pgd = kzalloc(sizeof(*pgd) * PTRS_PER_PGD, GFP_KERNEL | __GFP_REPEAT);
10
11 for (i = USER_PTRS_PER_PGD; i < PTRS_PER_PGD; i++)
12 pgd[i] = swapper_pg_dir[i];
13
14 return pgd;
15}
16
17static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
18{
19 kfree(pgd);
20}
21
22static inline void __check_pgt_cache(void)
23{
24}
25
26static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
27{
28 set_pud(pud, __pud((unsigned long)pmd));
29}
30
31static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
32{
33 return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL);
34}
35
36static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
37{
38 quicklist_free(QUICK_PT, NULL, pmd);
39}
40
41#endif /* __ASM_SH_PGALLOC_PMD_H */
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index 9effcc3b0d10..78598ec33d0a 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -141,9 +141,9 @@ typedef pte_t *pte_addr_t;
141#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) 141#define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT)))
142 142
143/* 143/*
144 * No page table caches to initialise 144 * Initialise the page table caches
145 */ 145 */
146#define pgtable_cache_init() do { } while (0) 146extern void pgtable_cache_init(void);
147 147
148struct vm_area_struct; 148struct vm_area_struct;
149 149
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 8a70535fa7ce..dd5010c708e0 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -15,7 +15,7 @@ obj-y += $(cacheops-y)
15 15
16mmu-y := nommu.o extable_32.o 16mmu-y := nommu.o extable_32.o
17mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \ 17mmu-$(CONFIG_MMU) := extable_$(BITS).o fault_$(BITS).o \
18 ioremap_$(BITS).o kmap.o tlbflush_$(BITS).o 18 ioremap_$(BITS).o kmap.o pgtable.o tlbflush_$(BITS).o
19 19
20obj-y += $(mmu-y) 20obj-y += $(mmu-y)
21obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o 21obj-$(CONFIG_DEBUG_FS) += asids-debugfs.o
diff --git a/arch/sh/mm/pgtable.c b/arch/sh/mm/pgtable.c
new file mode 100644
index 000000000000..e1bc5483cc07
--- /dev/null
+++ b/arch/sh/mm/pgtable.c
@@ -0,0 +1,57 @@
1#include <linux/mm.h>
2
3#define PGALLOC_GFP GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO
4
5static struct kmem_cache *pgd_cachep;
6
7#ifdef CONFIG_PGTABLE_LEVELS_3
8static struct kmem_cache *pmd_cachep;
9#endif
10
11void pgd_ctor(void *x)
12{
13 pgd_t *pgd = x;
14
15 memcpy(pgd + USER_PTRS_PER_PGD,
16 swapper_pg_dir + USER_PTRS_PER_PGD,
17 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
18}
19
20void pgtable_cache_init(void)
21{
22 pgd_cachep = kmem_cache_create("pgd_cache",
23 PTRS_PER_PGD * (1<<PTE_MAGNITUDE),
24 PAGE_SIZE, SLAB_PANIC, pgd_ctor);
25#ifdef CONFIG_PGTABLE_LEVELS_3
26 pmd_cachep = kmem_cache_create("pmd_cache",
27 PTRS_PER_PMD * (1<<PTE_MAGNITUDE),
28 PAGE_SIZE, SLAB_PANIC, NULL);
29#endif
30}
31
32pgd_t *pgd_alloc(struct mm_struct *mm)
33{
34 return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
35}
36
37void pgd_free(struct mm_struct *mm, pgd_t *pgd)
38{
39 kmem_cache_free(pgd_cachep, pgd);
40}
41
42#ifdef CONFIG_PGTABLE_LEVELS_3
43void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
44{
45 set_pud(pud, __pud((unsigned long)pmd));
46}
47
48pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
49{
50 return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
51}
52
53void pmd_free(struct mm_struct *mm, pmd_t *pmd)
54{
55 kmem_cache_free(pmd_cachep, pmd);
56}
57#endif /* CONFIG_PGTABLE_LEVELS_3 */