[S390] appldata/extmem/kvm: add missing GFP_KERNEL flag
[linux-2.6.git] / arch / parisc / mm / fault.c
index b2e3e9a..18162ce 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: fault.c,v 1.5 2000/01/26 16:20:29 jsm Exp $
- *
+/*
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
@@ -139,13 +138,41 @@ parisc_acctyp(unsigned long code, unsigned int inst)
                        }
 #endif
 
+int fixup_exception(struct pt_regs *regs)
+{
+       const struct exception_table_entry *fix;
+
+       fix = search_exception_tables(regs->iaoq[0]);
+       if (fix) {
+               struct exception_data *d;
+               d = &__get_cpu_var(exception_data);
+               d->fault_ip = regs->iaoq[0];
+               d->fault_space = regs->isr;
+               d->fault_addr = regs->ior;
+
+               regs->iaoq[0] = ((fix->fixup) & ~3);
+               /*
+                * NOTE: In some cases the faulting instruction
+                * may be in the delay slot of a branch. We
+                * don't want to take the branch, so we don't
+                * increment iaoq[1], instead we set it to be
+                * iaoq[0]+4, and clear the B bit in the PSW
+                */
+               regs->iaoq[1] = regs->iaoq[0] + 4;
+               regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */
+
+               return 1;
+       }
+
+       return 0;
+}
+
 void do_page_fault(struct pt_regs *regs, unsigned long code,
                              unsigned long address)
 {
        struct vm_area_struct *vma, *prev_vma;
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
-       const struct exception_table_entry *fix;
        unsigned long acc_type;
        int fault;
 
@@ -174,7 +201,7 @@ good_area:
         * fault.
         */
 
-       fault = handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0);
+       fault = handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) ? FAULT_FLAG_WRITE : 0);
        if (unlikely(fault & VM_FAULT_ERROR)) {
                /*
                 * We hit a shared mapping outside of the file, or some
@@ -229,40 +256,15 @@ bad_area:
 
 no_context:
 
-       if (!user_mode(regs)) {
-               fix = search_exception_tables(regs->iaoq[0]);
-
-               if (fix) {
-                       struct exception_data *d;
-
-                       d = &__get_cpu_var(exception_data);
-                       d->fault_ip = regs->iaoq[0];
-                       d->fault_space = regs->isr;
-                       d->fault_addr = regs->ior;
-
-                       regs->iaoq[0] = ((fix->fixup) & ~3);
-
-                       /*
-                        * NOTE: In some cases the faulting instruction
-                        * may be in the delay slot of a branch. We
-                        * don't want to take the branch, so we don't
-                        * increment iaoq[1], instead we set it to be
-                        * iaoq[0]+4, and clear the B bit in the PSW
-                        */
-
-                       regs->iaoq[1] = regs->iaoq[0] + 4;
-                       regs->gr[0] &= ~PSW_B; /* IPSW in gr[0] */
-
-                       return;
-               }
+       if (!user_mode(regs) && fixup_exception(regs)) {
+               return;
        }
 
        parisc_terminate("Bad Address (null pointer deref?)", regs, code, address);
 
   out_of_memory:
        up_read(&mm->mmap_sem);
-       printk(KERN_CRIT "VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
-       goto no_context;
+       if (!user_mode(regs))
+               goto no_context;
+       pagefault_out_of_memory();
 }