x86: i386-show-unhandled-signals-v3
[deliverable/linux.git] / arch / i386 / mm / fault.c
index 1ecb3e43b523387388a99e2ed7cccdf0a7cdd131..01ffdd4964f08e9bec86c5ae759da9f5cbe8270a 100644 (file)
@@ -283,6 +283,8 @@ static inline int vmalloc_fault(unsigned long address)
        return 0;
 }
 
+int show_unhandled_signals = 1;
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -303,6 +305,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
        struct vm_area_struct * vma;
        unsigned long address;
        int write, si_code;
+       int fault;
 
        /* get the address */
         address = read_cr2();
@@ -422,20 +425,18 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
-       switch (handle_mm_fault(mm, vma, address, write)) {
-               case VM_FAULT_MINOR:
-                       tsk->min_flt++;
-                       break;
-               case VM_FAULT_MAJOR:
-                       tsk->maj_flt++;
-                       break;
-               case VM_FAULT_SIGBUS:
-                       goto do_sigbus;
-               case VM_FAULT_OOM:
+       fault = handle_mm_fault(mm, vma, address, write);
+       if (unlikely(fault & VM_FAULT_ERROR)) {
+               if (fault & VM_FAULT_OOM)
                        goto out_of_memory;
-               default:
-                       BUG();
+               else if (fault & VM_FAULT_SIGBUS)
+                       goto do_sigbus;
+               BUG();
        }
+       if (fault & VM_FAULT_MAJOR)
+               tsk->maj_flt++;
+       else
+               tsk->min_flt++;
 
        /*
         * Did it hit the DOS screen memory VA from vm86 mode?
@@ -470,6 +471,14 @@ bad_area_nosemaphore:
                if (is_prefetch(regs, address, error_code))
                        return;
 
+               if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
+                   printk_ratelimit()) {
+                       printk("%s%s[%d]: segfault at %08lx eip %08lx "
+                           "esp %08lx error %lx\n",
+                           tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
+                           tsk->comm, tsk->pid, address, regs->eip,
+                           regs->esp, error_code);
+               }
                tsk->thread.cr2 = address;
                /* Kernel addresses are always protection faults */
                tsk->thread.error_code = error_code | (address >= TASK_SIZE);
This page took 0.024879 seconds and 5 git commands to generate.