diff options
-rw-r--r-- | arch/avr32/kernel/entry-avr32b.S | 45 | ||||
-rw-r--r-- | arch/avr32/kernel/vmlinux.lds.S | 4 | ||||
-rw-r--r-- | arch/avr32/mm/init.c | 4 | ||||
-rw-r--r-- | include/asm-avr32/pgalloc.h | 18 | ||||
-rw-r--r-- | include/asm-avr32/pgtable.h | 34 |
5 files changed, 51 insertions, 54 deletions
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 050c006a7f0c..3cdd7071f35e 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S | |||
@@ -74,12 +74,6 @@ exception_vectors: | |||
74 | .align 2 | 74 | .align 2 |
75 | bral do_dtlb_modified | 75 | bral do_dtlb_modified |
76 | 76 | ||
77 | /* | ||
78 | * r0 : PGD/PT/PTE | ||
79 | * r1 : Offending address | ||
80 | * r2 : Scratch register | ||
81 | * r3 : Cause (5, 12 or 13) | ||
82 | */ | ||
83 | #define tlbmiss_save pushm r0-r3 | 77 | #define tlbmiss_save pushm r0-r3 |
84 | #define tlbmiss_restore popm r0-r3 | 78 | #define tlbmiss_restore popm r0-r3 |
85 | 79 | ||
@@ -108,17 +102,17 @@ tlb_miss_common: | |||
108 | bld r0, 31 | 102 | bld r0, 31 |
109 | brcs handle_vmalloc_miss | 103 | brcs handle_vmalloc_miss |
110 | 104 | ||
111 | /* First level lookup */ | 105 | /* |
106 | * First level lookup: The PGD contains virtual pointers to | ||
107 | * the second-level page tables, but they may be NULL if not | ||
108 | * present. | ||
109 | */ | ||
112 | pgtbl_lookup: | 110 | pgtbl_lookup: |
113 | lsr r2, r0, PGDIR_SHIFT | 111 | lsr r2, r0, PGDIR_SHIFT |
114 | ld.w r3, r1[r2 << 2] | 112 | ld.w r3, r1[r2 << 2] |
115 | bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT | 113 | bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT |
116 | bld r3, _PAGE_BIT_PRESENT | 114 | cp.w r3, 0 |
117 | brcc page_table_not_present | 115 | breq page_table_not_present |
118 | |||
119 | /* Translate to virtual address in P1. */ | ||
120 | andl r3, 0xf000 | ||
121 | sbr r3, 31 | ||
122 | 116 | ||
123 | /* Second level lookup */ | 117 | /* Second level lookup */ |
124 | ld.w r2, r3[r1 << 2] | 118 | ld.w r2, r3[r1 << 2] |
@@ -155,6 +149,19 @@ handle_vmalloc_miss: | |||
155 | orh r1, hi(swapper_pg_dir) | 149 | orh r1, hi(swapper_pg_dir) |
156 | rjmp pgtbl_lookup | 150 | rjmp pgtbl_lookup |
157 | 151 | ||
152 | /* The slow path of the TLB miss handler */ | ||
153 | .align 2 | ||
154 | page_table_not_present: | ||
155 | page_not_present: | ||
156 | tlbmiss_restore | ||
157 | sub sp, 4 | ||
158 | stmts --sp, r0-lr | ||
159 | rcall save_full_context_ex | ||
160 | mfsr r12, SYSREG_ECR | ||
161 | mov r11, sp | ||
162 | rcall do_page_fault | ||
163 | rjmp ret_from_exception | ||
164 | |||
158 | 165 | ||
159 | /* --- System Call --- */ | 166 | /* --- System Call --- */ |
160 | 167 | ||
@@ -267,18 +274,6 @@ syscall_exit_work: | |||
267 | brcc syscall_exit_cont | 274 | brcc syscall_exit_cont |
268 | rjmp enter_monitor_mode | 275 | rjmp enter_monitor_mode |
269 | 276 | ||
270 | /* The slow path of the TLB miss handler */ | ||
271 | page_table_not_present: | ||
272 | page_not_present: | ||
273 | tlbmiss_restore | ||
274 | sub sp, 4 | ||
275 | stmts --sp, r0-lr | ||
276 | rcall save_full_context_ex | ||
277 | mfsr r12, SYSREG_ECR | ||
278 | mov r11, sp | ||
279 | rcall do_page_fault | ||
280 | rjmp ret_from_exception | ||
281 | |||
282 | /* This function expects to find offending PC in SYSREG_RAR_EX */ | 277 | /* This function expects to find offending PC in SYSREG_RAR_EX */ |
283 | .type save_full_context_ex, @function | 278 | .type save_full_context_ex, @function |
284 | .align 2 | 279 | .align 2 |
diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S index 033dd46bfa62..5d25d8eeb750 100644 --- a/arch/avr32/kernel/vmlinux.lds.S +++ b/arch/avr32/kernel/vmlinux.lds.S | |||
@@ -99,6 +99,10 @@ SECTIONS | |||
99 | */ | 99 | */ |
100 | *(.data.init_task) | 100 | *(.data.init_task) |
101 | 101 | ||
102 | /* Then, the page-aligned data */ | ||
103 | . = ALIGN(PAGE_SIZE); | ||
104 | *(.data.page_aligned) | ||
105 | |||
102 | /* Then, the cacheline aligned data */ | 106 | /* Then, the cacheline aligned data */ |
103 | . = ALIGN(L1_CACHE_BYTES); | 107 | . = ALIGN(L1_CACHE_BYTES); |
104 | *(.data.cacheline_aligned) | 108 | *(.data.cacheline_aligned) |
diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 0e77578c358d..3f90a87527bb 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c | |||
@@ -24,9 +24,11 @@ | |||
24 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
25 | #include <asm/sections.h> | 25 | #include <asm/sections.h> |
26 | 26 | ||
27 | #define __page_aligned __attribute__((section(".data.page_aligned"))) | ||
28 | |||
27 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 29 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
28 | 30 | ||
29 | pgd_t swapper_pg_dir[PTRS_PER_PGD]; | 31 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned; |
30 | 32 | ||
31 | struct page *empty_zero_page; | 33 | struct page *empty_zero_page; |
32 | EXPORT_SYMBOL(empty_zero_page); | 34 | EXPORT_SYMBOL(empty_zero_page); |
diff --git a/include/asm-avr32/pgalloc.h b/include/asm-avr32/pgalloc.h index 51fc1f6e4b17..5b768fc2388e 100644 --- a/include/asm-avr32/pgalloc.h +++ b/include/asm-avr32/pgalloc.h | |||
@@ -8,25 +8,27 @@ | |||
8 | #ifndef __ASM_AVR32_PGALLOC_H | 8 | #ifndef __ASM_AVR32_PGALLOC_H |
9 | #define __ASM_AVR32_PGALLOC_H | 9 | #define __ASM_AVR32_PGALLOC_H |
10 | 10 | ||
11 | #include <asm/processor.h> | ||
12 | #include <linux/threads.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/sched.h> | ||
13 | #include <linux/slab.h> | ||
15 | 14 | ||
16 | #define pmd_populate_kernel(mm, pmd, pte) \ | 15 | static inline void pmd_populate_kernel(struct mm_struct *mm, |
17 | set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) | 16 | pmd_t *pmd, pte_t *pte) |
17 | { | ||
18 | set_pmd(pmd, __pmd((unsigned long)pte)); | ||
19 | } | ||
18 | 20 | ||
19 | static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | 21 | static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, |
20 | pgtable_t pte) | 22 | pgtable_t pte) |
21 | { | 23 | { |
22 | set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte))); | 24 | set_pmd(pmd, __pmd((unsigned long)page_address(pte))); |
23 | } | 25 | } |
24 | #define pmd_pgtable(pmd) pmd_page(pmd) | 26 | #define pmd_pgtable(pmd) pmd_page(pmd) |
25 | 27 | ||
26 | /* | 28 | /* |
27 | * Allocate and free page tables | 29 | * Allocate and free page tables |
28 | */ | 30 | */ |
29 | static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm) | 31 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
30 | { | 32 | { |
31 | return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL); | 33 | return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL); |
32 | } | 34 | } |
diff --git a/include/asm-avr32/pgtable.h b/include/asm-avr32/pgtable.h index c0e5e29417df..fecdda16f444 100644 --- a/include/asm-avr32/pgtable.h +++ b/include/asm-avr32/pgtable.h | |||
@@ -129,13 +129,6 @@ extern struct page *empty_zero_page; | |||
129 | 129 | ||
130 | #define _PAGE_FLAGS_CACHE_MASK (_PAGE_CACHABLE | _PAGE_BUFFER | _PAGE_WT) | 130 | #define _PAGE_FLAGS_CACHE_MASK (_PAGE_CACHABLE | _PAGE_BUFFER | _PAGE_WT) |
131 | 131 | ||
132 | /* TODO: Check for saneness */ | ||
133 | /* User-mode page table flags (to be set in a pgd or pmd entry) */ | ||
134 | #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_TYPE_SMALL | _PAGE_RW \ | ||
135 | | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
136 | /* Kernel-mode page table flags */ | ||
137 | #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_TYPE_SMALL | _PAGE_RW \ | ||
138 | | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
139 | /* Flags that may be modified by software */ | 132 | /* Flags that may be modified by software */ |
140 | #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY \ | 133 | #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY \ |
141 | | _PAGE_FLAGS_CACHE_MASK) | 134 | | _PAGE_FLAGS_CACHE_MASK) |
@@ -262,10 +255,14 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
262 | } | 255 | } |
263 | 256 | ||
264 | #define pmd_none(x) (!pmd_val(x)) | 257 | #define pmd_none(x) (!pmd_val(x)) |
265 | #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) | 258 | #define pmd_present(x) (pmd_val(x)) |
266 | #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) | 259 | |
267 | #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) \ | 260 | static inline void pmd_clear(pmd_t *pmdp) |
268 | != _KERNPG_TABLE) | 261 | { |
262 | set_pmd(pmdp, __pmd(0)); | ||
263 | } | ||
264 | |||
265 | #define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) | ||
269 | 266 | ||
270 | /* | 267 | /* |
271 | * Permanent address of a page. We don't support highmem, so this is | 268 | * Permanent address of a page. We don't support highmem, so this is |
@@ -303,19 +300,16 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
303 | 300 | ||
304 | #define page_pte(page) page_pte_prot(page, __pgprot(0)) | 301 | #define page_pte(page) page_pte_prot(page, __pgprot(0)) |
305 | 302 | ||
306 | #define pmd_page_vaddr(pmd) \ | 303 | #define pmd_page_vaddr(pmd) pmd_val(pmd) |
307 | ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) | 304 | #define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) |
308 | |||
309 | #define pmd_page(pmd) (phys_to_page(pmd_val(pmd))) | ||
310 | 305 | ||
311 | /* to find an entry in a page-table-directory. */ | 306 | /* to find an entry in a page-table-directory. */ |
312 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) | 307 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) \ |
313 | #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) | 308 | & (PTRS_PER_PGD - 1)) |
314 | #define pgd_offset_current(address) \ | 309 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) |
315 | ((pgd_t *)__mfsr(SYSREG_PTBR) + pgd_index(address)) | ||
316 | 310 | ||
317 | /* to find an entry in a kernel page-table-directory */ | 311 | /* to find an entry in a kernel page-table-directory */ |
318 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | 312 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) |
319 | 313 | ||
320 | /* Find an entry in the third-level page table.. */ | 314 | /* Find an entry in the third-level page table.. */ |
321 | #define pte_index(address) \ | 315 | #define pte_index(address) \ |