aboutsummaryrefslogtreecommitdiffstats
path: root/arch/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 /arch/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 'arch/avr32')
-rw-r--r--arch/avr32/kernel/entry-avr32b.S42
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
146handle_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
154page_table_not_present: 144page_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
155page_not_present: 149page_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
160sync_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