aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-07-19 04:47:05 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:41 -0400
commit83c54070ee1a2d05c89793884bea1a03f2851ed4 (patch)
treedc732f5a9b93fb7004ed23f551bd98b77cc580e0 /arch
parentd0217ac04ca6591841e5665f518e38064f4e65bd (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')
-rw-r--r--arch/alpha/mm/fault.c22
-rw-r--r--arch/arm/mm/fault.c36
-rw-r--r--arch/arm26/mm/fault.c30
-rw-r--r--arch/avr32/mm/fault.c23
-rw-r--r--arch/cris/mm/fault.c23
-rw-r--r--arch/frv/mm/fault.c23
-rw-r--r--arch/i386/mm/fault.c23
-rw-r--r--arch/ia64/mm/fault.c26
-rw-r--r--arch/m32r/mm/fault.c23
-rw-r--r--arch/m68k/mm/fault.c21
-rw-r--r--arch/mips/mm/fault.c23
-rw-r--r--arch/parisc/mm/fault.c23
-rw-r--r--arch/powerpc/mm/fault.c26
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c28
-rw-r--r--arch/ppc/mm/fault.c23
-rw-r--r--arch/s390/lib/uaccess_pt.c23
-rw-r--r--arch/s390/mm/fault.c30
-rw-r--r--arch/sh/mm/fault.c23
-rw-r--r--arch/sh64/mm/fault.c24
-rw-r--r--arch/sparc/mm/fault.c22
-rw-r--r--arch/sparc64/mm/fault.c24
-rw-r--r--arch/um/kernel/trap.c29
-rw-r--r--arch/x86_64/mm/fault.c25
-rw-r--r--arch/xtensa/mm/fault.c23
24 files changed, 287 insertions, 309 deletions
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index f5862792a167..a0e18da594d9 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -148,21 +148,17 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
148 the fault. */ 148 the fault. */
149 fault = handle_mm_fault(mm, vma, address, cause > 0); 149 fault = handle_mm_fault(mm, vma, address, cause > 0);
150 up_read(&mm->mmap_sem); 150 up_read(&mm->mmap_sem);
151 151 if (unlikely(fault & VM_FAULT_ERROR)) {
152 switch (fault) { 152 if (fault & VM_FAULT_OOM)
153 case VM_FAULT_MINOR: 153 goto out_of_memory;
154 current->min_flt++; 154 else if (fault & VM_FAULT_SIGBUS)
155 break; 155 goto do_sigbus;
156 case VM_FAULT_MAJOR:
157 current->maj_flt++;
158 break;
159 case VM_FAULT_SIGBUS:
160 goto do_sigbus;
161 case VM_FAULT_OOM:
162 goto out_of_memory;
163 default:
164 BUG(); 156 BUG();
165 } 157 }
158 if (fault & VM_FAULT_MAJOR)
159 current->maj_flt++;
160 else
161 current->min_flt++;
166 return; 162 return;
167 163
168 /* Something tried to access memory that isn't in our memory map. 164 /* Something tried to access memory that isn't in our memory map.
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 */
184survive: 184survive:
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
199out_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);
diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c
index 93c0cee0fb5e..dec638a0c8d9 100644
--- a/arch/arm26/mm/fault.c
+++ b/arch/arm26/mm/fault.c
@@ -170,20 +170,20 @@ good_area:
170 */ 170 */
171survive: 171survive:
172 fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr)); 172 fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr));
173 173 if (unlikely(fault & VM_FAULT_ERROR)) {
174 /* 174 if (fault & VM_FAULT_OOM)
175 * Handle the "normal" cases first - successful and sigbus 175 goto out_of_memory;
176 */ 176 else if (fault & VM_FAULT_SIGBUS)
177 switch (fault) { 177 return fault;
178 case VM_FAULT_MAJOR: 178 BUG();
179 }
180 if (fault & VM_FAULT_MAJOR)
179 tsk->maj_flt++; 181 tsk->maj_flt++;
180 return fault; 182 else
181 case VM_FAULT_MINOR:
182 tsk->min_flt++; 183 tsk->min_flt++;
183 case VM_FAULT_SIGBUS: 184 return fault;
184 return fault;
185 }
186 185
186out_of_memory:
187 fault = -3; /* out of memory */ 187 fault = -3; /* out of memory */
188 if (!is_init(tsk)) 188 if (!is_init(tsk))
189 goto out; 189 goto out;
@@ -225,13 +225,11 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
225 /* 225 /*
226 * Handle the "normal" case first 226 * Handle the "normal" case first
227 */ 227 */
228 switch (fault) { 228 if (likely(!(fault & VM_FAULT_ERROR)))
229 case VM_FAULT_MINOR:
230 case VM_FAULT_MAJOR:
231 return 0; 229 return 0;
232 case VM_FAULT_SIGBUS: 230 if (fault & VM_FAULT_SIGBUS)
233 goto do_sigbus; 231 goto do_sigbus;
234 } 232 /* else VM_FAULT_OOM */
235 233
236 /* 234 /*
237 * If we are in kernel mode at this point, we 235 * If we are in kernel mode at this point, we
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 4b2495285d94..ae2d2c593b2b 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -64,6 +64,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
64 int writeaccess; 64 int writeaccess;
65 long signr; 65 long signr;
66 int code; 66 int code;
67 int fault;
67 68
68 if (notify_page_fault(regs, ecr)) 69 if (notify_page_fault(regs, ecr))
69 return; 70 return;
@@ -132,20 +133,18 @@ good_area:
132 * fault. 133 * fault.
133 */ 134 */
134survive: 135survive:
135 switch (handle_mm_fault(mm, vma, address, writeaccess)) { 136 fault = handle_mm_fault(mm, vma, address, writeaccess);
136 case VM_FAULT_MINOR: 137 if (unlikely(fault & VM_FAULT_ERROR)) {
137 tsk->min_flt++; 138 if (fault & VM_FAULT_OOM)
138 break; 139 goto out_of_memory;
139 case VM_FAULT_MAJOR: 140 else if (fault & VM_FAULT_SIGBUS)
140 tsk->maj_flt++; 141 goto do_sigbus;
141 break;
142 case VM_FAULT_SIGBUS:
143 goto do_sigbus;
144 case VM_FAULT_OOM:
145 goto out_of_memory;
146 default:
147 BUG(); 142 BUG();
148 } 143 }
144 if (fault & VM_FAULT_MAJOR)
145 tsk->maj_flt++;
146 else
147 tsk->min_flt++;
149 148
150 up_read(&mm->mmap_sem); 149 up_read(&mm->mmap_sem);
151 return; 150 return;
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index c73e91f1299a..8672ab7d7978 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -179,6 +179,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
179 struct mm_struct *mm; 179 struct mm_struct *mm;
180 struct vm_area_struct * vma; 180 struct vm_area_struct * vma;
181 siginfo_t info; 181 siginfo_t info;
182 int fault;
182 183
183 D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n", 184 D(printk("Page fault for %lX on %X at %lX, prot %d write %d\n",
184 address, smp_processor_id(), instruction_pointer(regs), 185 address, smp_processor_id(), instruction_pointer(regs),
@@ -283,18 +284,18 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
283 * the fault. 284 * the fault.
284 */ 285 */
285 286
286 switch (handle_mm_fault(mm, vma, address, writeaccess & 1)) { 287 fault = handle_mm_fault(mm, vma, address, writeaccess & 1);
287 case VM_FAULT_MINOR: 288 if (unlikely(fault & VM_FAULT_ERROR)) {
288 tsk->min_flt++; 289 if (fault & VM_FAULT_OOM)
289 break; 290 goto out_of_memory;
290 case VM_FAULT_MAJOR: 291 else if (fault & VM_FAULT_SIGBUS)
291 tsk->maj_flt++; 292 goto do_sigbus;
292 break; 293 BUG();
293 case VM_FAULT_SIGBUS:
294 goto do_sigbus;
295 default:
296 goto out_of_memory;
297 } 294 }
295 if (fault & VM_FAULT_MAJOR)
296 tsk->maj_flt++;
297 else
298 tsk->min_flt++;
298 299
299 up_read(&mm->mmap_sem); 300 up_read(&mm->mmap_sem);
300 return; 301 return;
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
index 3f12296c3688..6798fa0257b1 100644
--- a/arch/frv/mm/fault.c
+++ b/arch/frv/mm/fault.c
@@ -40,6 +40,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
40 pud_t *pue; 40 pud_t *pue;
41 pte_t *pte; 41 pte_t *pte;
42 int write; 42 int write;
43 int fault;
43 44
44#if 0 45#if 0
45 const char *atxc[16] = { 46 const char *atxc[16] = {
@@ -162,18 +163,18 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
162 * make sure we exit gracefully rather than endlessly redo 163 * make sure we exit gracefully rather than endlessly redo
163 * the fault. 164 * the fault.
164 */ 165 */
165 switch (handle_mm_fault(mm, vma, ear0, write)) { 166 fault = handle_mm_fault(mm, vma, ear0, write);
166 case VM_FAULT_MINOR: 167 if (unlikely(fault & VM_FAULT_ERROR)) {
167 current->min_flt++; 168 if (fault & VM_FAULT_OOM)
168 break; 169 goto out_of_memory;
169 case VM_FAULT_MAJOR: 170 else if (fault & VM_FAULT_SIGBUS)
170 current->maj_flt++; 171 goto do_sigbus;
171 break; 172 BUG();
172 case VM_FAULT_SIGBUS:
173 goto do_sigbus;
174 default:
175 goto out_of_memory;
176 } 173 }
174 if (fault & VM_FAULT_MAJOR)
175 current->maj_flt++;
176 else
177 current->min_flt++;
177 178
178 up_read(&mm->mmap_sem); 179 up_read(&mm->mmap_sem);
179 return; 180 return;
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 1ecb3e43b523..e92a10124935 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -303,6 +303,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
303 struct vm_area_struct * vma; 303 struct vm_area_struct * vma;
304 unsigned long address; 304 unsigned long address;
305 int write, si_code; 305 int write, si_code;
306 int fault;
306 307
307 /* get the address */ 308 /* get the address */
308 address = read_cr2(); 309 address = read_cr2();
@@ -422,20 +423,18 @@ good_area:
422 * make sure we exit gracefully rather than endlessly redo 423 * make sure we exit gracefully rather than endlessly redo
423 * the fault. 424 * the fault.
424 */ 425 */
425 switch (handle_mm_fault(mm, vma, address, write)) { 426 fault = handle_mm_fault(mm, vma, address, write);
426 case VM_FAULT_MINOR: 427 if (unlikely(fault & VM_FAULT_ERROR)) {
427 tsk->min_flt++; 428 if (fault & VM_FAULT_OOM)
428 break;
429 case VM_FAULT_MAJOR:
430 tsk->maj_flt++;
431 break;
432 case VM_FAULT_SIGBUS:
433 goto do_sigbus;
434 case VM_FAULT_OOM:
435 goto out_of_memory; 429 goto out_of_memory;
436 default: 430 else if (fault & VM_FAULT_SIGBUS)
437 BUG(); 431 goto do_sigbus;
432 BUG();
438 } 433 }
434 if (fault & VM_FAULT_MAJOR)
435 tsk->maj_flt++;
436 else
437 tsk->min_flt++;
439 438
440 /* 439 /*
441 * Did it hit the DOS screen memory VA from vm86 mode? 440 * Did it hit the DOS screen memory VA from vm86 mode?
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index b87f785c2416..73ccb6010c05 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -80,6 +80,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
80 struct mm_struct *mm = current->mm; 80 struct mm_struct *mm = current->mm;
81 struct siginfo si; 81 struct siginfo si;
82 unsigned long mask; 82 unsigned long mask;
83 int fault;
83 84
84 /* mmap_sem is performance critical.... */ 85 /* mmap_sem is performance critical.... */
85 prefetchw(&mm->mmap_sem); 86 prefetchw(&mm->mmap_sem);
@@ -147,26 +148,25 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
147 * sure we exit gracefully rather than endlessly redo the 148 * sure we exit gracefully rather than endlessly redo the
148 * fault. 149 * fault.
149 */ 150 */
150 switch (handle_mm_fault(mm, vma, address, (mask & VM_WRITE) != 0)) { 151 fault = handle_mm_fault(mm, vma, address, (mask & VM_WRITE) != 0);
151 case VM_FAULT_MINOR: 152 if (unlikely(fault & VM_FAULT_ERROR)) {
152 ++current->min_flt;
153 break;
154 case VM_FAULT_MAJOR:
155 ++current->maj_flt;
156 break;
157 case VM_FAULT_SIGBUS:
158 /* 153 /*
159 * We ran out of memory, or some other thing happened 154 * We ran out of memory, or some other thing happened
160 * to us that made us unable to handle the page fault 155 * to us that made us unable to handle the page fault
161 * gracefully. 156 * gracefully.
162 */ 157 */
163 signal = SIGBUS; 158 if (fault & VM_FAULT_OOM) {
164 goto bad_area; 159 goto out_of_memory;
165 case VM_FAULT_OOM: 160 } else if (fault & VM_FAULT_SIGBUS) {
166 goto out_of_memory; 161 signal = SIGBUS;
167 default: 162 goto bad_area;
163 }
168 BUG(); 164 BUG();
169 } 165 }
166 if (fault & VM_FAULT_MAJOR)
167 current->maj_flt++;
168 else
169 current->min_flt++;
170 up_read(&mm->mmap_sem); 170 up_read(&mm->mmap_sem);
171 return; 171 return;
172 172
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index f3935ba24946..676a1c443d28 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -80,6 +80,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
80 struct vm_area_struct * vma; 80 struct vm_area_struct * vma;
81 unsigned long page, addr; 81 unsigned long page, addr;
82 int write; 82 int write;
83 int fault;
83 siginfo_t info; 84 siginfo_t info;
84 85
85 /* 86 /*
@@ -195,20 +196,18 @@ survive:
195 */ 196 */
196 addr = (address & PAGE_MASK); 197 addr = (address & PAGE_MASK);
197 set_thread_fault_code(error_code); 198 set_thread_fault_code(error_code);
198 switch (handle_mm_fault(mm, vma, addr, write)) { 199 fault = handle_mm_fault(mm, vma, addr, write);
199 case VM_FAULT_MINOR: 200 if (unlikely(fault & VM_FAULT_ERROR)) {
200 tsk->min_flt++; 201 if (fault & VM_FAULT_OOM)
201 break;
202 case VM_FAULT_MAJOR:
203 tsk->maj_flt++;
204 break;
205 case VM_FAULT_SIGBUS:
206 goto do_sigbus;
207 case VM_FAULT_OOM:
208 goto out_of_memory; 202 goto out_of_memory;
209 default: 203 else if (fault & VM_FAULT_SIGBUS)
210 BUG(); 204 goto do_sigbus;
205 BUG();
211 } 206 }
207 if (fault & VM_FAULT_MAJOR)
208 tsk->maj_flt++;
209 else
210 tsk->min_flt++;
212 set_thread_fault_code(0); 211 set_thread_fault_code(0);
213 up_read(&mm->mmap_sem); 212 up_read(&mm->mmap_sem);
214 return; 213 return;
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index 2adbeb16e1b8..578b48f47b9e 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -159,18 +159,17 @@ good_area:
159#ifdef DEBUG 159#ifdef DEBUG
160 printk("handle_mm_fault returns %d\n",fault); 160 printk("handle_mm_fault returns %d\n",fault);
161#endif 161#endif
162 switch (fault) { 162 if (unlikely(fault & VM_FAULT_ERROR)) {
163 case VM_FAULT_MINOR: 163 if (fault & VM_FAULT_OOM)
164 current->min_flt++; 164 goto out_of_memory;
165 break; 165 else if (fault & VM_FAULT_SIGBUS)
166 case VM_FAULT_MAJOR: 166 goto bus_err;
167 current->maj_flt++; 167 BUG();
168 break;
169 case VM_FAULT_SIGBUS:
170 goto bus_err;
171 default:
172 goto out_of_memory;
173 } 168 }
169 if (fault & VM_FAULT_MAJOR)
170 current->maj_flt++;
171 else
172 current->min_flt++;
174 173
175 up_read(&mm->mmap_sem); 174 up_read(&mm->mmap_sem);
176 return 0; 175 return 0;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 7ebea331edb8..521771b373de 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -39,6 +39,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
39 struct mm_struct *mm = tsk->mm; 39 struct mm_struct *mm = tsk->mm;
40 const int field = sizeof(unsigned long) * 2; 40 const int field = sizeof(unsigned long) * 2;
41 siginfo_t info; 41 siginfo_t info;
42 int fault;
42 43
43#if 0 44#if 0
44 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(), 45 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
@@ -102,20 +103,18 @@ survive:
102 * make sure we exit gracefully rather than endlessly redo 103 * make sure we exit gracefully rather than endlessly redo
103 * the fault. 104 * the fault.
104 */ 105 */
105 switch (handle_mm_fault(mm, vma, address, write)) { 106 fault = handle_mm_fault(mm, vma, address, write);
106 case VM_FAULT_MINOR: 107 if (unlikely(fault & VM_FAULT_ERROR)) {
107 tsk->min_flt++; 108 if (fault & VM_FAULT_OOM)
108 break; 109 goto out_of_memory;
109 case VM_FAULT_MAJOR: 110 else if (fault & VM_FAULT_SIGBUS)
110 tsk->maj_flt++; 111 goto do_sigbus;
111 break;
112 case VM_FAULT_SIGBUS:
113 goto do_sigbus;
114 case VM_FAULT_OOM:
115 goto out_of_memory;
116 default:
117 BUG(); 112 BUG();
118 } 113 }
114 if (fault & VM_FAULT_MAJOR)
115 tsk->maj_flt++;
116 else
117 tsk->min_flt++;
119 118
120 up_read(&mm->mmap_sem); 119 up_read(&mm->mmap_sem);
121 return; 120 return;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index f6f67554c623..7899ab87785a 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -147,6 +147,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
147 struct mm_struct *mm = tsk->mm; 147 struct mm_struct *mm = tsk->mm;
148 const struct exception_table_entry *fix; 148 const struct exception_table_entry *fix;
149 unsigned long acc_type; 149 unsigned long acc_type;
150 int fault;
150 151
151 if (in_atomic() || !mm) 152 if (in_atomic() || !mm)
152 goto no_context; 153 goto no_context;
@@ -173,23 +174,23 @@ good_area:
173 * fault. 174 * fault.
174 */ 175 */
175 176
176 switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) { 177 fault = handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0);
177 case VM_FAULT_MINOR: 178 if (unlikely(fault & VM_FAULT_ERROR)) {
178 ++current->min_flt;
179 break;
180 case VM_FAULT_MAJOR:
181 ++current->maj_flt;
182 break;
183 case VM_FAULT_SIGBUS:
184 /* 179 /*
185 * We hit a shared mapping outside of the file, or some 180 * We hit a shared mapping outside of the file, or some
186 * other thing happened to us that made us unable to 181 * other thing happened to us that made us unable to
187 * handle the page fault gracefully. 182 * handle the page fault gracefully.
188 */ 183 */
189 goto bad_area; 184 if (fault & VM_FAULT_OOM)
190 default: 185 goto out_of_memory;
191 goto out_of_memory; 186 else if (fault & VM_FAULT_SIGBUS)
187 goto bad_area;
188 BUG();
192 } 189 }
190 if (fault & VM_FAULT_MAJOR)
191 current->maj_flt++;
192 else
193 current->min_flt++;
193 up_read(&mm->mmap_sem); 194 up_read(&mm->mmap_sem);
194 return; 195 return;
195 196
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 0ece51310bfe..3767211b3d0f 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -145,7 +145,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
145 struct mm_struct *mm = current->mm; 145 struct mm_struct *mm = current->mm;
146 siginfo_t info; 146 siginfo_t info;
147 int code = SEGV_MAPERR; 147 int code = SEGV_MAPERR;
148 int is_write = 0; 148 int is_write = 0, ret;
149 int trap = TRAP(regs); 149 int trap = TRAP(regs);
150 int is_exec = trap == 0x400; 150 int is_exec = trap == 0x400;
151 151
@@ -330,22 +330,18 @@ good_area:
330 * the fault. 330 * the fault.
331 */ 331 */
332 survive: 332 survive:
333 switch (handle_mm_fault(mm, vma, address, is_write)) { 333 ret = handle_mm_fault(mm, vma, address, is_write);
334 334 if (unlikely(ret & VM_FAULT_ERROR)) {
335 case VM_FAULT_MINOR: 335 if (ret & VM_FAULT_OOM)
336 current->min_flt++; 336 goto out_of_memory;
337 break; 337 else if (ret & VM_FAULT_SIGBUS)
338 case VM_FAULT_MAJOR: 338 goto do_sigbus;
339 current->maj_flt++;
340 break;
341 case VM_FAULT_SIGBUS:
342 goto do_sigbus;
343 case VM_FAULT_OOM:
344 goto out_of_memory;
345 default:
346 BUG(); 339 BUG();
347 } 340 }
348 341 if (ret & VM_FAULT_MAJOR)
342 current->maj_flt++;
343 else
344 current->min_flt++;
349 up_read(&mm->mmap_sem); 345 up_read(&mm->mmap_sem);
350 return 0; 346 return 0;
351 347
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index e064d0c0d80e..07f88de0544d 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -74,23 +74,21 @@ good_area:
74 goto bad_area; 74 goto bad_area;
75 } 75 }
76 ret = 0; 76 ret = 0;
77 *flt = handle_mm_fault(mm, vma, ea, is_write); 77 fault = handle_mm_fault(mm, vma, ea, is_write);
78 switch (*flt) { 78 if (unlikely(fault & VM_FAULT_ERROR)) {
79 case VM_FAULT_MINOR: 79 if (fault & VM_FAULT_OOM) {
80 current->min_flt++; 80 ret = -ENOMEM;
81 break; 81 goto bad_area;
82 case VM_FAULT_MAJOR: 82 } else if (fault & VM_FAULT_SIGBUS) {
83 current->maj_flt++; 83 ret = -EFAULT;
84 break; 84 goto bad_area;
85 case VM_FAULT_SIGBUS: 85 }
86 ret = -EFAULT;
87 goto bad_area;
88 case VM_FAULT_OOM:
89 ret = -ENOMEM;
90 goto bad_area;
91 default:
92 BUG(); 86 BUG();
93 } 87 }
88 if (fault & VM_FAULT_MAJOR)
89 current->maj_flt++;
90 else
91 current->min_flt++;
94 up_read(&mm->mmap_sem); 92 up_read(&mm->mmap_sem);
95 return ret; 93 return ret;
96 94
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 465f451f3bc3..b98244e277fb 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -96,6 +96,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
96 struct mm_struct *mm = current->mm; 96 struct mm_struct *mm = current->mm;
97 siginfo_t info; 97 siginfo_t info;
98 int code = SEGV_MAPERR; 98 int code = SEGV_MAPERR;
99 int fault;
99#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE) 100#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
100 int is_write = error_code & ESR_DST; 101 int is_write = error_code & ESR_DST;
101#else 102#else
@@ -249,20 +250,18 @@ good_area:
249 * the fault. 250 * the fault.
250 */ 251 */
251 survive: 252 survive:
252 switch (handle_mm_fault(mm, vma, address, is_write)) { 253 fault = handle_mm_fault(mm, vma, address, is_write);
253 case VM_FAULT_MINOR: 254 if (unlikely(fault & VM_FAULT_ERROR)) {
254 current->min_flt++; 255 if (fault & VM_FAULT_OOM)
255 break; 256 goto out_of_memory;
256 case VM_FAULT_MAJOR: 257 else if (fault & VM_FAULT_SIGBUS)
257 current->maj_flt++; 258 goto do_sigbus;
258 break;
259 case VM_FAULT_SIGBUS:
260 goto do_sigbus;
261 case VM_FAULT_OOM:
262 goto out_of_memory;
263 default:
264 BUG(); 259 BUG();
265 } 260 }
261 if (fault & VM_FAULT_MAJOR)
262 current->maj_flt++;
263 else
264 current->min_flt++;
266 265
267 up_read(&mm->mmap_sem); 266 up_read(&mm->mmap_sem);
268 /* 267 /*
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 63181671e3e3..60604b2819b2 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -20,6 +20,7 @@ static int __handle_fault(struct mm_struct *mm, unsigned long address,
20{ 20{
21 struct vm_area_struct *vma; 21 struct vm_area_struct *vma;
22 int ret = -EFAULT; 22 int ret = -EFAULT;
23 int fault;
23 24
24 if (in_atomic()) 25 if (in_atomic())
25 return ret; 26 return ret;
@@ -44,20 +45,18 @@ static int __handle_fault(struct mm_struct *mm, unsigned long address,
44 } 45 }
45 46
46survive: 47survive:
47 switch (handle_mm_fault(mm, vma, address, write_access)) { 48 fault = handle_mm_fault(mm, vma, address, write_access);
48 case VM_FAULT_MINOR: 49 if (unlikely(fault & VM_FAULT_ERROR)) {
49 current->min_flt++; 50 if (fault & VM_FAULT_OOM)
50 break; 51 goto out_of_memory;
51 case VM_FAULT_MAJOR: 52 else if (fault & VM_FAULT_SIGBUS)
52 current->maj_flt++; 53 goto out_sigbus;
53 break;
54 case VM_FAULT_SIGBUS:
55 goto out_sigbus;
56 case VM_FAULT_OOM:
57 goto out_of_memory;
58 default:
59 BUG(); 54 BUG();
60 } 55 }
56 if (fault & VM_FAULT_MAJOR)
57 current->maj_flt++;
58 else
59 current->min_flt++;
61 ret = 0; 60 ret = 0;
62out: 61out:
63 up_read(&mm->mmap_sem); 62 up_read(&mm->mmap_sem);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index d855cdbf8fb8..54055194e9af 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -307,6 +307,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write)
307 unsigned long address; 307 unsigned long address;
308 int space; 308 int space;
309 int si_code; 309 int si_code;
310 int fault;
310 311
311 if (notify_page_fault(regs, error_code)) 312 if (notify_page_fault(regs, error_code))
312 return; 313 return;
@@ -377,23 +378,22 @@ survive:
377 * make sure we exit gracefully rather than endlessly redo 378 * make sure we exit gracefully rather than endlessly redo
378 * the fault. 379 * the fault.
379 */ 380 */
380 switch (handle_mm_fault(mm, vma, address, write)) { 381 fault = handle_mm_fault(mm, vma, address, write);
381 case VM_FAULT_MINOR: 382 if (unlikely(fault & VM_FAULT_ERROR)) {
382 tsk->min_flt++; 383 if (fault & VM_FAULT_OOM) {
383 break; 384 if (do_out_of_memory(regs, error_code, address))
384 case VM_FAULT_MAJOR: 385 goto survive;
385 tsk->maj_flt++; 386 return;
386 break; 387 } else if (fault & VM_FAULT_SIGBUS) {
387 case VM_FAULT_SIGBUS: 388 do_sigbus(regs, error_code, address);
388 do_sigbus(regs, error_code, address); 389 return;
389 return; 390 }
390 case VM_FAULT_OOM:
391 if (do_out_of_memory(regs, error_code, address))
392 goto survive;
393 return;
394 default:
395 BUG(); 391 BUG();
396 } 392 }
393 if (fault & VM_FAULT_MAJOR)
394 tsk->maj_flt++;
395 else
396 tsk->min_flt++;
397 397
398 up_read(&mm->mmap_sem); 398 up_read(&mm->mmap_sem);
399 /* 399 /*
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 0b3eaf6fbb28..964c6767dc73 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -33,6 +33,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
33 struct mm_struct *mm; 33 struct mm_struct *mm;
34 struct vm_area_struct * vma; 34 struct vm_area_struct * vma;
35 int si_code; 35 int si_code;
36 int fault;
36 siginfo_t info; 37 siginfo_t info;
37 38
38 trace_hardirqs_on(); 39 trace_hardirqs_on();
@@ -124,20 +125,18 @@ good_area:
124 * the fault. 125 * the fault.
125 */ 126 */
126survive: 127survive:
127 switch (handle_mm_fault(mm, vma, address, writeaccess)) { 128 fault = handle_mm_fault(mm, vma, address, writeaccess);
128 case VM_FAULT_MINOR: 129 if (unlikely(fault & VM_FAULT_ERROR)) {
129 tsk->min_flt++; 130 if (fault & VM_FAULT_OOM)
130 break;
131 case VM_FAULT_MAJOR:
132 tsk->maj_flt++;
133 break;
134 case VM_FAULT_SIGBUS:
135 goto do_sigbus;
136 case VM_FAULT_OOM:
137 goto out_of_memory; 131 goto out_of_memory;
138 default: 132 else if (fault & VM_FAULT_SIGBUS)
139 BUG(); 133 goto do_sigbus;
134 BUG();
140 } 135 }
136 if (fault & VM_FAULT_MAJOR)
137 tsk->maj_flt++;
138 else
139 tsk->min_flt++;
141 140
142 up_read(&mm->mmap_sem); 141 up_read(&mm->mmap_sem);
143 return; 142 return;
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index 3cd93ba5d826..0d069d82141f 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -127,6 +127,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
127 struct vm_area_struct * vma; 127 struct vm_area_struct * vma;
128 const struct exception_table_entry *fixup; 128 const struct exception_table_entry *fixup;
129 pte_t *pte; 129 pte_t *pte;
130 int fault;
130 131
131#if defined(CONFIG_SH64_PROC_TLB) 132#if defined(CONFIG_SH64_PROC_TLB)
132 ++calls_to_do_slow_page_fault; 133 ++calls_to_do_slow_page_fault;
@@ -221,18 +222,19 @@ good_area:
221 * the fault. 222 * the fault.
222 */ 223 */
223survive: 224survive:
224 switch (handle_mm_fault(mm, vma, address, writeaccess)) { 225 fault = handle_mm_fault(mm, vma, address, writeaccess);
225 case VM_FAULT_MINOR: 226 if (unlikely(fault & VM_FAULT_ERROR)) {
226 tsk->min_flt++; 227 if (fault & VM_FAULT_OOM)
227 break; 228 goto out_of_memory;
228 case VM_FAULT_MAJOR: 229 else if (fault & VM_FAULT_SIGBUS)
229 tsk->maj_flt++; 230 goto do_sigbus;
230 break; 231 BUG();
231 case VM_FAULT_SIGBUS:
232 goto do_sigbus;
233 default:
234 goto out_of_memory;
235 } 232 }
233 if (fault & VM_FAULT_MAJOR)
234 tsk->maj_flt++;
235 else
236 tsk->min_flt++;
237
236 /* If we get here, the page fault has been handled. Do the TLB refill 238 /* If we get here, the page fault has been handled. Do the TLB refill
237 now from the newly-setup PTE, to avoid having to fault again right 239 now from the newly-setup PTE, to avoid having to fault again right
238 away on the same instruction. */ 240 away on the same instruction. */
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index c3483365db4b..50747fe44356 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -226,6 +226,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
226 unsigned long g2; 226 unsigned long g2;
227 siginfo_t info; 227 siginfo_t info;
228 int from_user = !(regs->psr & PSR_PS); 228 int from_user = !(regs->psr & PSR_PS);
229 int fault;
229 230
230 if(text_fault) 231 if(text_fault)
231 address = regs->pc; 232 address = regs->pc;
@@ -289,19 +290,18 @@ good_area:
289 * make sure we exit gracefully rather than endlessly redo 290 * make sure we exit gracefully rather than endlessly redo
290 * the fault. 291 * the fault.
291 */ 292 */
292 switch (handle_mm_fault(mm, vma, address, write)) { 293 fault = handle_mm_fault(mm, vma, address, write);
293 case VM_FAULT_SIGBUS: 294 if (unlikely(fault & VM_FAULT_ERROR)) {
294 goto do_sigbus; 295 if (fault & VM_FAULT_OOM)
295 case VM_FAULT_OOM: 296 goto out_of_memory;
296 goto out_of_memory; 297 else if (fault & VM_FAULT_SIGBUS)
297 case VM_FAULT_MAJOR: 298 goto do_sigbus;
299 BUG();
300 }
301 if (fault & VM_FAULT_MAJOR)
298 current->maj_flt++; 302 current->maj_flt++;
299 break; 303 else
300 case VM_FAULT_MINOR:
301 default:
302 current->min_flt++; 304 current->min_flt++;
303 break;
304 }
305 up_read(&mm->mmap_sem); 305 up_read(&mm->mmap_sem);
306 return; 306 return;
307 307
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index b582024d2199..17123e9ecf78 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -278,7 +278,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
278 struct mm_struct *mm = current->mm; 278 struct mm_struct *mm = current->mm;
279 struct vm_area_struct *vma; 279 struct vm_area_struct *vma;
280 unsigned int insn = 0; 280 unsigned int insn = 0;
281 int si_code, fault_code; 281 int si_code, fault_code, fault;
282 unsigned long address, mm_rss; 282 unsigned long address, mm_rss;
283 283
284 fault_code = get_thread_fault_code(); 284 fault_code = get_thread_fault_code();
@@ -415,20 +415,18 @@ good_area:
415 goto bad_area; 415 goto bad_area;
416 } 416 }
417 417
418 switch (handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE))) { 418 fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE));
419 case VM_FAULT_MINOR: 419 if (unlikely(fault & VM_FAULT_ERROR)) {
420 current->min_flt++; 420 if (fault & VM_FAULT_OOM)
421 break; 421 goto out_of_memory;
422 case VM_FAULT_MAJOR: 422 else if (fault & VM_FAULT_SIGBUS)
423 current->maj_flt++; 423 goto do_sigbus;
424 break;
425 case VM_FAULT_SIGBUS:
426 goto do_sigbus;
427 case VM_FAULT_OOM:
428 goto out_of_memory;
429 default:
430 BUG(); 424 BUG();
431 } 425 }
426 if (fault & VM_FAULT_MAJOR)
427 current->maj_flt++;
428 else
429 current->min_flt++;
432 430
433 up_read(&mm->mmap_sem); 431 up_read(&mm->mmap_sem);
434 432
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index abab90c3803f..3850d53f79fd 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -76,23 +76,24 @@ good_area:
76 goto out; 76 goto out;
77 77
78 do { 78 do {
79 int fault;
79survive: 80survive:
80 switch (handle_mm_fault(mm, vma, address, is_write)){ 81 fault = handle_mm_fault(mm, vma, address, is_write);
81 case VM_FAULT_MINOR: 82 if (unlikely(fault & VM_FAULT_ERROR)) {
82 current->min_flt++; 83 if (fault & VM_FAULT_OOM) {
83 break; 84 err = -ENOMEM;
84 case VM_FAULT_MAJOR: 85 goto out_of_memory;
85 current->maj_flt++; 86 } else if (fault & VM_FAULT_SIGBUS) {
86 break; 87 err = -EACCES;
87 case VM_FAULT_SIGBUS: 88 goto out;
88 err = -EACCES; 89 }
89 goto out;
90 case VM_FAULT_OOM:
91 err = -ENOMEM;
92 goto out_of_memory;
93 default:
94 BUG(); 90 BUG();
95 } 91 }
92 if (fault & VM_FAULT_MAJOR)
93 current->maj_flt++;
94 else
95 current->min_flt++;
96
96 pgd = pgd_offset(mm, address); 97 pgd = pgd_offset(mm, address);
97 pud = pud_offset(pgd, address); 98 pud = pud_offset(pgd, address);
98 pmd = pmd_offset(pud, address); 99 pmd = pmd_offset(pud, address);
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index 635e58d443d7..84f11728fc76 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -317,7 +317,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
317 struct vm_area_struct * vma; 317 struct vm_area_struct * vma;
318 unsigned long address; 318 unsigned long address;
319 const struct exception_table_entry *fixup; 319 const struct exception_table_entry *fixup;
320 int write; 320 int write, fault;
321 unsigned long flags; 321 unsigned long flags;
322 siginfo_t info; 322 siginfo_t info;
323 323
@@ -450,19 +450,18 @@ good_area:
450 * make sure we exit gracefully rather than endlessly redo 450 * make sure we exit gracefully rather than endlessly redo
451 * the fault. 451 * the fault.
452 */ 452 */
453 switch (handle_mm_fault(mm, vma, address, write)) { 453 fault = handle_mm_fault(mm, vma, address, write);
454 case VM_FAULT_MINOR: 454 if (unlikely(fault & VM_FAULT_ERROR)) {
455 tsk->min_flt++; 455 if (fault & VM_FAULT_OOM)
456 break; 456 goto out_of_memory;
457 case VM_FAULT_MAJOR: 457 else if (fault & VM_FAULT_SIGBUS)
458 tsk->maj_flt++; 458 goto do_sigbus;
459 break; 459 BUG();
460 case VM_FAULT_SIGBUS:
461 goto do_sigbus;
462 default:
463 goto out_of_memory;
464 } 460 }
465 461 if (fault & VM_FAULT_MAJOR)
462 tsk->maj_flt++;
463 else
464 tsk->min_flt++;
466 up_read(&mm->mmap_sem); 465 up_read(&mm->mmap_sem);
467 return; 466 return;
468 467
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 3dc6f2f07bbe..16004067add3 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -41,6 +41,7 @@ void do_page_fault(struct pt_regs *regs)
41 siginfo_t info; 41 siginfo_t info;
42 42
43 int is_write, is_exec; 43 int is_write, is_exec;
44 int fault;
44 45
45 info.si_code = SEGV_MAPERR; 46 info.si_code = SEGV_MAPERR;
46 47
@@ -102,20 +103,18 @@ good_area:
102 * the fault. 103 * the fault.
103 */ 104 */
104survive: 105survive:
105 switch (handle_mm_fault(mm, vma, address, is_write)) { 106 fault = handle_mm_fault(mm, vma, address, is_write);
106 case VM_FAULT_MINOR: 107 if (unlikely(fault & VM_FAULT_ERROR)) {
107 current->min_flt++; 108 if (fault & VM_FAULT_OOM)
108 break; 109 goto out_of_memory;
109 case VM_FAULT_MAJOR: 110 else if (fault & VM_FAULT_SIGBUS)
110 current->maj_flt++; 111 goto do_sigbus;
111 break;
112 case VM_FAULT_SIGBUS:
113 goto do_sigbus;
114 case VM_FAULT_OOM:
115 goto out_of_memory;
116 default:
117 BUG(); 112 BUG();
118 } 113 }
114 if (fault & VM_FAULT_MAJOR)
115 current->maj_flt++;
116 else
117 current->min_flt++;
119 118
120 up_read(&mm->mmap_sem); 119 up_read(&mm->mmap_sem);
121 return; 120 return;