aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/pgtable_32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/pgtable_32.c')
-rw-r--r--arch/powerpc/mm/pgtable_32.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 50fad3801f30..03b1a3b0fbd5 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -63,7 +63,6 @@ void setbat(int index, unsigned long virt, phys_addr_t phys,
63#endif /* HAVE_BATS */ 63#endif /* HAVE_BATS */
64 64
65#ifdef HAVE_TLBCAM 65#ifdef HAVE_TLBCAM
66extern unsigned int tlbcam_index;
67extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); 66extern phys_addr_t v_mapped_by_tlbcam(unsigned long va);
68extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); 67extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa);
69#else /* !HAVE_TLBCAM */ 68#else /* !HAVE_TLBCAM */
@@ -73,13 +72,25 @@ extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa);
73 72
74#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) 73#define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT)
75 74
75#ifndef CONFIG_PPC_4K_PAGES
76static struct kmem_cache *pgtable_cache;
77
78void pgtable_cache_init(void)
79{
80 pgtable_cache = kmem_cache_create("PGDIR cache", 1 << PGDIR_ORDER,
81 1 << PGDIR_ORDER, 0, NULL);
82 if (pgtable_cache == NULL)
83 panic("Couldn't allocate pgtable caches");
84}
85#endif
86
76pgd_t *pgd_alloc(struct mm_struct *mm) 87pgd_t *pgd_alloc(struct mm_struct *mm)
77{ 88{
78 pgd_t *ret; 89 pgd_t *ret;
79 90
80 /* pgdir take page or two with 4K pages and a page fraction otherwise */ 91 /* pgdir take page or two with 4K pages and a page fraction otherwise */
81#ifndef CONFIG_PPC_4K_PAGES 92#ifndef CONFIG_PPC_4K_PAGES
82 ret = kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); 93 ret = kmem_cache_alloc(pgtable_cache, GFP_KERNEL | __GFP_ZERO);
83#else 94#else
84 ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 95 ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
85 PGDIR_ORDER - PAGE_SHIFT); 96 PGDIR_ORDER - PAGE_SHIFT);
@@ -90,7 +101,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
90void pgd_free(struct mm_struct *mm, pgd_t *pgd) 101void pgd_free(struct mm_struct *mm, pgd_t *pgd)
91{ 102{
92#ifndef CONFIG_PPC_4K_PAGES 103#ifndef CONFIG_PPC_4K_PAGES
93 kfree((void *)pgd); 104 kmem_cache_free(pgtable_cache, (void *)pgd);
94#else 105#else
95 free_pages((unsigned long)pgd, PGDIR_ORDER - PAGE_SHIFT); 106 free_pages((unsigned long)pgd, PGDIR_ORDER - PAGE_SHIFT);
96#endif 107#endif
@@ -147,7 +158,7 @@ void __iomem *
147ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags) 158ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
148{ 159{
149 /* writeable implies dirty for kernel addresses */ 160 /* writeable implies dirty for kernel addresses */
150 if (flags & _PAGE_RW) 161 if ((flags & (_PAGE_RW | _PAGE_RO)) != _PAGE_RO)
151 flags |= _PAGE_DIRTY | _PAGE_HWWRITE; 162 flags |= _PAGE_DIRTY | _PAGE_HWWRITE;
152 163
153 /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */ 164 /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */