diff options
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r-- | arch/avr32/kernel/entry-avr32b.S | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S index 3cdd7071f35e..2b398cae110c 100644 --- a/arch/avr32/kernel/entry-avr32b.S +++ b/arch/avr32/kernel/entry-avr32b.S | |||
@@ -98,10 +98,6 @@ tlb_miss_common: | |||
98 | mfsr r0, SYSREG_TLBEAR | 98 | mfsr r0, SYSREG_TLBEAR |
99 | mfsr r1, SYSREG_PTBR | 99 | mfsr r1, SYSREG_PTBR |
100 | 100 | ||
101 | /* Is it the vmalloc space? */ | ||
102 | bld r0, 31 | ||
103 | brcs handle_vmalloc_miss | ||
104 | |||
105 | /* | 101 | /* |
106 | * First level lookup: The PGD contains virtual pointers to | 102 | * First level lookup: The PGD contains virtual pointers to |
107 | * the second-level page tables, but they may be NULL if not | 103 | * the second-level page tables, but they may be NULL if not |
@@ -143,15 +139,13 @@ pgtbl_lookup: | |||
143 | tlbmiss_restore | 139 | tlbmiss_restore |
144 | rete | 140 | rete |
145 | 141 | ||
146 | handle_vmalloc_miss: | ||
147 | /* Simply do the lookup in init's page table */ | ||
148 | mov r1, lo(swapper_pg_dir) | ||
149 | orh r1, hi(swapper_pg_dir) | ||
150 | rjmp pgtbl_lookup | ||
151 | |||
152 | /* The slow path of the TLB miss handler */ | 142 | /* The slow path of the TLB miss handler */ |
153 | .align 2 | 143 | .align 2 |
154 | page_table_not_present: | 144 | page_table_not_present: |
145 | /* Do we need to synchronize with swapper_pg_dir? */ | ||
146 | bld r0, 31 | ||
147 | brcs sync_with_swapper_pg_dir | ||
148 | |||
155 | page_not_present: | 149 | page_not_present: |
156 | tlbmiss_restore | 150 | tlbmiss_restore |
157 | sub sp, 4 | 151 | sub sp, 4 |
@@ -162,6 +156,34 @@ page_not_present: | |||
162 | rcall do_page_fault | 156 | rcall do_page_fault |
163 | rjmp ret_from_exception | 157 | rjmp ret_from_exception |
164 | 158 | ||
159 | .align 2 | ||
160 | sync_with_swapper_pg_dir: | ||
161 | /* | ||
162 | * If swapper_pg_dir contains a non-NULL second-level page | ||
163 | * table pointer, copy it into the current PGD. If not, we | ||
164 | * must handle it as a full-blown page fault. | ||
165 | * | ||
166 | * Jumping back to pgtbl_lookup causes an unnecessary lookup, | ||
167 | * but it is guaranteed to be a cache hit, it won't happen | ||
168 | * very often, and we absolutely do not want to sacrifice any | ||
169 | * performance in the fast path in order to improve this. | ||
170 | */ | ||
171 | mov r1, lo(swapper_pg_dir) | ||
172 | orh r1, hi(swapper_pg_dir) | ||
173 | ld.w r3, r1[r2 << 2] | ||
174 | cp.w r3, 0 | ||
175 | breq page_not_present | ||
176 | mfsr r1, SYSREG_PTBR | ||
177 | st.w r1[r2 << 2], r3 | ||
178 | rjmp pgtbl_lookup | ||
179 | |||
180 | /* | ||
181 | * We currently have two bytes left at this point until we | ||
182 | * crash into the system call handler... | ||
183 | * | ||
184 | * Don't worry, the assembler will let us know. | ||
185 | */ | ||
186 | |||
165 | 187 | ||
166 | /* --- System Call --- */ | 188 | /* --- System Call --- */ |
167 | 189 | ||