diff options
author | Nick Piggin <npiggin@suse.de> | 2007-07-19 04:47:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:41 -0400 |
commit | 83c54070ee1a2d05c89793884bea1a03f2851ed4 (patch) | |
tree | dc732f5a9b93fb7004ed23f551bd98b77cc580e0 /arch/arm | |
parent | d0217ac04ca6591841e5665f518e38064f4e65bd (diff) |
mm: fault feedback #2
This patch completes Linus's wish that the fault return codes be made into
bit flags, which I agree makes everything nicer. This requires requires
all handle_mm_fault callers to be modified (possibly the modifications
should go further and do things like fault accounting in handle_mm_fault --
however that would be for another patch).
[akpm@linux-foundation.org: fix alpha build]
[akpm@linux-foundation.org: fix s390 build]
[akpm@linux-foundation.org: fix sparc build]
[akpm@linux-foundation.org: fix sparc64 build]
[akpm@linux-foundation.org: fix ia64 build]
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Ian Molton <spyro@f2s.com>
Cc: Bryan Wu <bryan.wu@analog.com>
Cc: Mikael Starvik <starvik@axis.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Greg Ungerer <gerg@uclinux.org>
Cc: Matthew Wilcox <willy@debian.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
Cc: Richard Curnow <rc@rc0.org.uk>
Cc: William Lee Irwin III <wli@holomorphy.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Cc: Miles Bader <uclinux-v850@lsi.nec.co.jp>
Cc: Chris Zankel <chris@zankel.net>
Acked-by: Kyle McMartin <kyle@mcmartin.ca>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-by: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ Still apparently needs some ARM and PPC loving - Linus ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/arm')
-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); |