diff options
Diffstat (limited to 'arch/arm/mm/fault.c')
-rw-r--r-- | arch/arm/mm/fault.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 75d491448e45..c04124a095cf 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -183,20 +183,20 @@ good_area: | |||
183 | */ | 183 | */ |
184 | survive: | 184 | survive: |
185 | fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, fsr & (1 << 11)); | 185 | fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, fsr & (1 << 11)); |
186 | 186 | if (unlikely(fault & VM_FAULT_ERROR)) { | |
187 | /* | 187 | if (fault & VM_FAULT_OOM) |
188 | * Handle the "normal" cases first - successful and sigbus | 188 | goto out_of_memory; |
189 | */ | 189 | else if (fault & VM_FAULT_SIGBUS) |
190 | switch (fault) { | 190 | return fault; |
191 | case VM_FAULT_MAJOR: | 191 | BUG(); |
192 | } | ||
193 | if (fault & VM_FAULT_MAJOR) | ||
192 | tsk->maj_flt++; | 194 | tsk->maj_flt++; |
193 | return fault; | 195 | else |
194 | case VM_FAULT_MINOR: | ||
195 | tsk->min_flt++; | 196 | tsk->min_flt++; |
196 | case VM_FAULT_SIGBUS: | 197 | return fault; |
197 | return fault; | ||
198 | } | ||
199 | 198 | ||
199 | out_of_memory: | ||
200 | if (!is_init(tsk)) | 200 | if (!is_init(tsk)) |
201 | goto out; | 201 | goto out; |
202 | 202 | ||
@@ -249,7 +249,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
249 | /* | 249 | /* |
250 | * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR | 250 | * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR |
251 | */ | 251 | */ |
252 | if (fault >= VM_FAULT_MINOR) | 252 | if (likely(!(fault & VM_FAULT_ERROR))) |
253 | return 0; | 253 | return 0; |
254 | 254 | ||
255 | /* | 255 | /* |
@@ -259,8 +259,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
259 | if (!user_mode(regs)) | 259 | if (!user_mode(regs)) |
260 | goto no_context; | 260 | goto no_context; |
261 | 261 | ||
262 | switch (fault) { | 262 | if (fault & VM_FAULT_OOM) { |
263 | case VM_FAULT_OOM: | ||
264 | /* | 263 | /* |
265 | * We ran out of memory, or some other thing | 264 | * We ran out of memory, or some other thing |
266 | * happened to us that made us unable to handle | 265 | * happened to us that made us unable to handle |
@@ -269,17 +268,15 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
269 | printk("VM: killing process %s\n", tsk->comm); | 268 | printk("VM: killing process %s\n", tsk->comm); |
270 | do_exit(SIGKILL); | 269 | do_exit(SIGKILL); |
271 | return 0; | 270 | return 0; |
272 | 271 | } | |
273 | case VM_FAULT_SIGBUS: | 272 | if (fault & VM_FAULT_SIGBUS) { |
274 | /* | 273 | /* |
275 | * We had some memory, but were unable to | 274 | * We had some memory, but were unable to |
276 | * successfully fix up this page fault. | 275 | * successfully fix up this page fault. |
277 | */ | 276 | */ |
278 | sig = SIGBUS; | 277 | sig = SIGBUS; |
279 | code = BUS_ADRERR; | 278 | code = BUS_ADRERR; |
280 | break; | 279 | } else { |
281 | |||
282 | default: | ||
283 | /* | 280 | /* |
284 | * Something tried to access memory that | 281 | * Something tried to access memory that |
285 | * isn't in our memory map.. | 282 | * isn't in our memory map.. |
@@ -287,7 +284,6 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
287 | sig = SIGSEGV; | 284 | sig = SIGSEGV; |
288 | code = fault == VM_FAULT_BADACCESS ? | 285 | code = fault == VM_FAULT_BADACCESS ? |
289 | SEGV_ACCERR : SEGV_MAPERR; | 286 | SEGV_ACCERR : SEGV_MAPERR; |
290 | break; | ||
291 | } | 287 | } |
292 | 288 | ||
293 | __do_user_fault(tsk, addr, fsr, sig, code, regs); | 289 | __do_user_fault(tsk, addr, fsr, sig, code, regs); |