diff options
Diffstat (limited to 'arch/powerpc/mm/pgtable_32.c')
-rw-r--r-- | arch/powerpc/mm/pgtable_32.c | 19 |
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 |
66 | extern unsigned int tlbcam_index; | ||
67 | extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); | 66 | extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); |
68 | extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); | 67 | extern 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 | ||
76 | static struct kmem_cache *pgtable_cache; | ||
77 | |||
78 | void 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 | |||
76 | pgd_t *pgd_alloc(struct mm_struct *mm) | 87 | pgd_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) | |||
90 | void pgd_free(struct mm_struct *mm, pgd_t *pgd) | 101 | void 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 * | |||
147 | ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags) | 158 | ioremap_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 */ |