aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-avr32
diff options
context:
space:
mode:
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-01-14 17:11:26 -0500
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>2008-07-02 05:01:29 -0400
commita9a934f278613885816aa9f177968c1dac557240 (patch)
treee2199d8039f548c88f95dd82ee87fc254d972767 /include/asm-avr32
parentcfd23e93a0289cf6711fd3877c5226658d87240a (diff)
avr32: Cover the kernel page tables in the user PGDs
Expand the per-process PGDs so that they cover the kernel virtual memory area as well. This simplifies the TLB miss handler fastpath since it doesn't have to check for kernel addresses anymore. If a TLB miss happens on a kernel address and a second-level page table can't be found, we check swapper_pg_dir and copy the PGD entry into the user PGD if it can be found there. Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Diffstat (limited to 'include/asm-avr32')
-rw-r--r--include/asm-avr32/pgalloc.h14
1 files changed, 10 insertions, 4 deletions
diff --git a/include/asm-avr32/pgalloc.h b/include/asm-avr32/pgalloc.h
index 5b768fc2388e..e9636d1f383f 100644
--- a/include/asm-avr32/pgalloc.h
+++ b/include/asm-avr32/pgalloc.h
@@ -9,8 +9,6 @@
9#define __ASM_AVR32_PGALLOC_H 9#define __ASM_AVR32_PGALLOC_H
10 10
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/sched.h>
13#include <linux/slab.h>
14 12
15static inline void pmd_populate_kernel(struct mm_struct *mm, 13static inline void pmd_populate_kernel(struct mm_struct *mm,
16 pmd_t *pmd, pte_t *pte) 14 pmd_t *pmd, pte_t *pte)
@@ -30,12 +28,20 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
30 */ 28 */
31static inline pgd_t *pgd_alloc(struct mm_struct *mm) 29static inline pgd_t *pgd_alloc(struct mm_struct *mm)
32{ 30{
33 return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL); 31 pgd_t *pgd;
32
33 pgd = (pgd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
34 if (likely(pgd))
35 memcpy(pgd + USER_PTRS_PER_PGD,
36 swapper_pg_dir + USER_PTRS_PER_PGD,
37 (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
38
39 return pgd;
34} 40}
35 41
36static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) 42static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
37{ 43{
38 kfree(pgd); 44 free_page((unsigned long)pgd);
39} 45}
40 46
41static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, 47static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,