fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / parisc / mm / fault.c
index d52b3a0..a041b43 100644 (file)
@@ -36,6 +36,9 @@
 
 #define BITSSET                0x1c0   /* for identifying LDCW */
 
+
+DEFINE_PER_CPU(struct exception_data, exception_data);
+
 /*
  * parisc_acctyp(unsigned int inst) --
  *    Given a PA-RISC memory access instruction, determine if the
@@ -149,7 +152,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
        const struct exception_table_entry *fix;
        unsigned long acc_type;
 
-       if (in_interrupt() || !mm)
+       if (in_atomic() || !mm)
                goto no_context;
 
        down_read(&mm->mmap_sem);
@@ -175,17 +178,17 @@ good_area:
         */
 
        switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) {
-             case 1:
+             case VM_FAULT_MINOR:
                ++current->min_flt;
                break;
-             case 2:
+             case VM_FAULT_MAJOR:
                ++current->maj_flt;
                break;
-             case 0:
+             case VM_FAULT_SIGBUS:
                /*
-                * We ran out of memory, or some other thing happened
-                * to us that made us unable to handle the page fault
-                * gracefully.
+                * We hit a shared mapping outside of the file, or some
+                * other thing happened to us that made us unable to
+                * handle the page fault gracefully.
                 */
                goto bad_area;
              default:
@@ -210,8 +213,9 @@ bad_area:
 
 #ifdef PRINT_USER_FAULTS
                printk(KERN_DEBUG "\n");
-               printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
-                   tsk->pid, tsk->comm, code, address);
+               printk(KERN_DEBUG "do_page_fault() pid=%d:#%u "
+                   "command='%s' type=%lu address=0x%08lx\n",
+                   tsk->pid, tsk->xid, tsk->comm, code, address);
                if (vma) {
                        printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
                                        vma->vm_start, vma->vm_end);
@@ -222,7 +226,7 @@ bad_area:
                si.si_signo = SIGSEGV;
                si.si_errno = 0;
                si.si_code = SEGV_MAPERR;
-               si.si_addr = (void *) address;
+               si.si_addr = (void __user *) address;
                force_sig_info(SIGSEGV, &si, current);
                return;
        }
@@ -230,17 +234,17 @@ bad_area:
 no_context:
 
        if (!user_mode(regs)) {
-
                fix = search_exception_tables(regs->iaoq[0]);
 
                if (fix) {
+                       struct exception_data *d;
 
-                       if (fix->skip & 1) 
-                               regs->gr[8] = -EFAULT;
-                       if (fix->skip & 2)
-                               regs->gr[9] = 0;
+                       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->skip) & ~3);
+                       regs->iaoq[0] = ((fix->fixup) & ~3);
 
                        /*
                         * NOTE: In some cases the faulting instruction
@@ -261,7 +265,8 @@ no_context:
 
   out_of_memory:
        up_read(&mm->mmap_sem);
-       printk(KERN_CRIT "VM: killing process %s\n", current->comm);
+       printk(KERN_CRIT "VM: killing process %s(%d:#%u)\n",
+               current->comm, current->pid, current->xid);
        if (user_mode(regs))
                do_exit(SIGKILL);
        goto no_context;