X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fparisc%2Fmm%2Ffault.c;h=a041b43e796adcb94e50b4dacfffa9fde926ba56;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=d52b3a06ac5dd7a8152bac621d1cc0848dd8540d;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index d52b3a06a..a041b43e7 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -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;