]> err.no Git - linux-2.6/blobdiff - arch/sparc64/mm/fault.c
Merge branch 'audit.b50' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit...
[linux-2.6] / arch / sparc64 / mm / fault.c
index b582024d21994498b7959270d5c265e7eac65cdf..2650d0d33ac25cbc656baa97adec4c29e1a65a93 100644 (file)
@@ -112,15 +112,12 @@ static void __kprobes unhandled_fault(unsigned long address,
 
 static void bad_kernel_pc(struct pt_regs *regs, unsigned long vaddr)
 {
-       unsigned long *ksp;
-
        printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
               regs->tpc);
        printk(KERN_CRIT "OOPS: RPC [%016lx]\n", regs->u_regs[15]);
        print_symbol("RPC: <%s>\n", regs->u_regs[15]);
        printk(KERN_CRIT "OOPS: Fault was to vaddr[%lx]\n", vaddr);
-       __asm__("mov %%sp, %0" : "=r" (ksp));
-       show_stack(current, ksp);
+       dump_stack();
        unhandled_fault(regs->tpc, current, regs);
 }
 
@@ -247,16 +244,8 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
        if (regs->tstate & TSTATE_PRIV) {
                const struct exception_table_entry *entry;
 
-               if (asi == ASI_P && (insn & 0xc0800000) == 0xc0800000) {
-                       if (insn & 0x2000)
-                               asi = (regs->tstate >> 24);
-                       else
-                               asi = (insn >> 5);
-               }
-       
-               /* Look in asi.h: All _S asis have LS bit set */
-               if ((asi & 0x1) &&
-                   (entry = search_exception_tables(regs->tpc))) {
+               entry = search_exception_tables(regs->tpc);
+               if (entry) {
                        regs->tpc = entry->fixup;
                        regs->tnpc = regs->tpc + 4;
                        return;
@@ -278,7 +267,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        unsigned int insn = 0;
-       int si_code, fault_code;
+       int si_code, fault_code, fault;
        unsigned long address, mm_rss;
 
        fault_code = get_thread_fault_code();
@@ -297,7 +286,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
                unsigned long tpc = regs->tpc;
 
                /* Sanity check the PC. */
-               if ((tpc >= KERNBASE && tpc < (unsigned long) _etext) ||
+               if ((tpc >= KERNBASE && tpc < (unsigned long) __init_end) ||
                    (tpc >= MODULES_VADDR && tpc < MODULES_END)) {
                        /* Valid, no problems... */
                } else {
@@ -415,20 +404,18 @@ good_area:
                        goto bad_area;
        }
 
-       switch (handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE))) {
-       case VM_FAULT_MINOR:
-               current->min_flt++;
-               break;
-       case VM_FAULT_MAJOR:
-               current->maj_flt++;
-               break;
-       case VM_FAULT_SIGBUS:
-               goto do_sigbus;
-       case VM_FAULT_OOM:
-               goto out_of_memory;
-       default:
+       fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE));
+       if (unlikely(fault & VM_FAULT_ERROR)) {
+               if (fault & VM_FAULT_OOM)
+                       goto out_of_memory;
+               else if (fault & VM_FAULT_SIGBUS)
+                       goto do_sigbus;
                BUG();
        }
+       if (fault & VM_FAULT_MAJOR)
+               current->maj_flt++;
+       else
+               current->min_flt++;
 
        up_read(&mm->mmap_sem);
 
@@ -468,7 +455,7 @@ out_of_memory:
        up_read(&mm->mmap_sem);
        printk("VM: killing process %s\n", current->comm);
        if (!(regs->tstate & TSTATE_PRIV))
-               do_exit(SIGKILL);
+               do_group_exit(SIGKILL);
        goto handle_kernel_fault;
 
 intr_or_no_mm: