Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys fix copy{in, out}{, str}() to return the error returned by...



details:   https://anonhg.NetBSD.org/src/rev/75ca5f27b777
branches:  trunk
changeset: 753223:75ca5f27b777
user:      chs <chs%NetBSD.org@localhost>
date:      Sat Mar 20 23:31:27 2010 +0000

description:
fix copy{in,out}{,str}() to return the error returned by uvm_fault().
fixes PR 41813.

diffstat:

 sys/arch/acorn26/acorn26/except.c    |   20 ++++--
 sys/arch/alpha/alpha/trap.c          |   31 ++++-----
 sys/arch/amiga/amiga/trap.c          |   48 +++++++++-----
 sys/arch/atari/atari/trap.c          |   45 +++++++------
 sys/arch/cesfic/cesfic/trap.c        |   34 ++++++----
 sys/arch/hp300/hp300/trap.c          |   34 ++++++----
 sys/arch/hp700/hp700/machdep.c       |   18 +-----
 sys/arch/hppa/hppa/copy.S            |   43 ++++++------
 sys/arch/hppa/hppa/trap.c            |   16 ++--
 sys/arch/luna68k/luna68k/trap.c      |   29 +++++---
 sys/arch/m68k/m68k/copy.s            |    7 +-
 sys/arch/mac68k/mac68k/trap.c        |   34 ++++++----
 sys/arch/mips/mips/copy.S            |   11 +--
 sys/arch/mips/mips/trap.c            |   39 ++++++-----
 sys/arch/mvme68k/mvme68k/trap.c      |   26 ++++---
 sys/arch/news68k/news68k/trap.c      |   34 ++++++----
 sys/arch/next68k/next68k/trap.c      |   34 ++++++----
 sys/arch/powerpc/ibm4xx/copyinstr.c  |   14 ++--
 sys/arch/powerpc/ibm4xx/copyoutstr.c |   14 ++--
 sys/arch/powerpc/ibm4xx/genassym.cf  |    4 +-
 sys/arch/powerpc/ibm4xx/trap.c       |   81 ++++++++++++++-----------
 sys/arch/powerpc/oea/genassym.cf     |    4 +-
 sys/arch/powerpc/powerpc/setfault.S  |    4 +-
 sys/arch/sh3/sh3/exception.c         |   38 +++++++----
 sys/arch/sh3/sh3/locore_subr.S       |   84 +++++++++++++-------------
 sys/arch/sparc/sparc/trap.c          |   62 ++++++++++++------
 sys/arch/sparc64/sparc64/locore.s    |   29 +-------
 sys/arch/sparc64/sparc64/trap.c      |  112 +++++++---------------------------
 sys/arch/sun2/sun2/trap.c            |   30 +++++----
 sys/arch/sun3/sun3/trap.c            |   30 ++++-----
 sys/arch/vax/include/pcb.h           |    4 +-
 sys/arch/vax/vax/genassym.cf         |    4 +-
 sys/arch/vax/vax/subr.S              |   72 ++++++++++------------
 sys/arch/vax/vax/trap.c              |   28 ++++----
 sys/arch/vax/vax/vm_machdep.c        |    9 +-
 sys/arch/x68k/x68k/trap.c            |   35 ++++++----
 sys/lib/libkern/arch/hppa/bcopy.S    |    8 +-
 37 files changed, 592 insertions(+), 577 deletions(-)

diffs (truncated from 3710 to 300 lines):

diff -r 1aebc475675f -r 75ca5f27b777 sys/arch/acorn26/acorn26/except.c
--- a/sys/arch/acorn26/acorn26/except.c Sat Mar 20 20:58:06 2010 +0000
+++ b/sys/arch/acorn26/acorn26/except.c Sat Mar 20 23:31:27 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: except.c,v 1.23 2009/11/21 20:32:17 rmind Exp $ */
+/* $NetBSD: except.c,v 1.24 2010/03/20 23:31:27 chs Exp $ */
 /*-
  * Copyright (c) 1998, 1999, 2000 Ben Harris
  * All rights reserved.
@@ -31,7 +31,7 @@
 
 #include <sys/param.h>
 
-__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.23 2009/11/21 20:32:17 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.24 2010/03/20 23:31:27 chs Exp $");
 
 #include "opt_ddb.h"
 
@@ -200,25 +200,31 @@
     struct vm_map *map, vaddr_t va, vm_prot_t atype)
 {
        int error;
-       struct pcb *cur_pcb;
+       struct pcb *pcb;
+       void *onfault;
 
        if (pmap_fault(map->pmap, va, atype))
                return;
 
+       pcb = lwp_getpcb(l);
+       onfault = pcb->pcb_onfault;
+
        if (cpu_intr_p()) {
                KASSERT((tf->tf_r15 & R15_MODE) != R15_MODE_USR);
                error = EFAULT;
-       } else
+       } else {
+               pcb->pcb_onfault = NULL;
                error = uvm_fault(map, va, atype);
+               pcb->pcb_onfault = onfault;
+       }
 
        if (error != 0) {
                ksiginfo_t ksi;
 
-               cur_pcb = lwp_getpcb(l);
-               if (cur_pcb->pcb_onfault != NULL) {
+               if (onfault != NULL) {
                        tf->tf_r0 = error;
                        tf->tf_r15 = (tf->tf_r15 & ~R15_PC) |
-                           (register_t)cur_pcb->pcb_onfault;
+                           (register_t)onfault;
                        return;
                }
 #ifdef DDB
diff -r 1aebc475675f -r 75ca5f27b777 sys/arch/alpha/alpha/trap.c
--- a/sys/arch/alpha/alpha/trap.c       Sat Mar 20 20:58:06 2010 +0000
+++ b/sys/arch/alpha/alpha/trap.c       Sat Mar 20 23:31:27 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.121 2009/11/21 05:35:41 rmind Exp $ */
+/* $NetBSD: trap.c,v 1.122 2010/03/20 23:31:27 chs Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc.
@@ -93,7 +93,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.121 2009/11/21 05:35:41 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.122 2010/03/20 23:31:27 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -228,6 +228,8 @@
 {
        struct lwp *l;
        struct proc *p;
+       struct pcb *pcb;
+       vaddr_t onfault;
        ksiginfo_t ksi;
        vm_prot_t ftype;
        u_int64_t ucode;
@@ -379,6 +381,9 @@
                break;
 
        case ALPHA_KENTRY_MM:
+               pcb = lwp_getpcb(l);
+               onfault = pcb->pcb_onfault;
+
                switch (a1) {
                case ALPHA_MMCSR_FOR:
                case ALPHA_MMCSR_FOE:
@@ -395,7 +400,6 @@
                        vaddr_t va;
                        struct vmspace *vm = NULL;
                        struct vm_map *map;
-                       struct pcb *pcb;
                        int rv;
 
                        switch (a2) {
@@ -442,11 +446,10 @@
                                 * [fs]uswintr, in case another fault happens
                                 * when they are running.
                                 */
-                               pcb = lwp_getpcb(l);
-                               if (pcb->pcb_onfault == (u_long)fswintrberr &&
+
+                               if (onfault == (vaddr_t)fswintrberr &&
                                    pcb->pcb_accessaddr == a0) {
-                                       framep->tf_regs[FRAME_PC] =
-                                           pcb->pcb_onfault;
+                                       framep->tf_regs[FRAME_PC] = onfault;
                                        pcb->pcb_onfault = 0;
                                        goto out;
                                }
@@ -470,7 +473,7 @@
 do_fault:
                        pcb = lwp_getpcb(l);
                        if (user == 0 && (a0 >= VM_MIN_KERNEL_ADDRESS ||
-                           pcb->pcb_onfault == 0))
+                                         onfault == 0))
                                map = kernel_map;
                        else {
                                vm = l->l_proc->p_vmspace;
@@ -478,7 +481,9 @@
                        }
 
                        va = trunc_page((vaddr_t)a0);
+                       pcb->pcb_onfault = 0;
                        rv = uvm_fault(map, va, ftype);
+                       pcb->pcb_onfault = onfault;
 
                        /*
                         * If this was a stack access we keep track of the
@@ -504,15 +509,9 @@
 
                        if (user == 0) {
                                /* Check for copyin/copyout fault */
-                               if (l == NULL) {
-                                       goto dopanic;
-                               }
-                               pcb = lwp_getpcb(l);
-                               if (pcb->pcb_onfault != 0) {
-                                       framep->tf_regs[FRAME_PC] =
-                                           pcb->pcb_onfault;
+                               if (onfault != 0) {
+                                       framep->tf_regs[FRAME_PC] = onfault;
                                        framep->tf_regs[FRAME_V0] = rv;
-                                       pcb->pcb_onfault = 0;
                                        goto out;
                                }
                                goto dopanic;
diff -r 1aebc475675f -r 75ca5f27b777 sys/arch/amiga/amiga/trap.c
--- a/sys/arch/amiga/amiga/trap.c       Sat Mar 20 20:58:06 2010 +0000
+++ b/sys/arch/amiga/amiga/trap.c       Sat Mar 20 23:31:27 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.127 2009/11/23 00:11:43 rmind Exp $ */
+/*     $NetBSD: trap.c,v 1.128 2010/03/20 23:31:27 chs Exp $   */
 
 /*
  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@@ -83,7 +83,7 @@
 #include "opt_fpu_emulate.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.127 2009/11/23 00:11:43 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.128 2010/03/20 23:31:27 chs Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -223,7 +223,7 @@
 int _write_back(u_int, u_int, u_int, u_int, struct vm_map *);
 static void userret(struct lwp *, int, u_quad_t);
 void panictrap(int, u_int, u_int, struct frame *);
-void trapcpfault(struct lwp *, struct frame *);
+void trapcpfault(struct lwp *, struct frame *, int);
 void trapmmufault(int, u_int, u_int, struct frame *, struct lwp *,
                        u_quad_t);
 void trap(struct frame *, int, u_int, u_int);
@@ -287,7 +287,7 @@
  * return to fault handler
  */
 void
-trapcpfault(struct lwp *l, struct frame *fp)
+trapcpfault(struct lwp *l, struct frame *fp, int error)
 {
        struct pcb *pcb = lwp_getpcb(l);
 
@@ -300,6 +300,7 @@
        fp->f_stackadj = exframesize[fp->f_format];
        fp->f_format = fp->f_vector = 0;
        fp->f_pc = (int)pcb->pcb_onfault;
+       fp->f_regs[D0] = error;
 }
 
 int donomore = 0;
@@ -314,13 +315,17 @@
        extern struct vm_map *kernel_map;
        struct proc *p = l->l_proc;
        struct vmspace *vm = NULL;
+       struct vm_map *map;
        struct pcb *pcb;
+       void *onfault;
        vm_prot_t ftype;
        vaddr_t va;
-       struct vm_map *map;
        ksiginfo_t ksi;
        int rv;
 
+       pcb = lwp_getpcb(l);
+       onfault = pcb->pcb_onfault;
+
        KSI_INIT_TRAP(&ksi);
        ksi.ksi_trap = type & ~T_USER;
 
@@ -377,8 +382,7 @@
        if (p)
                vm = p->p_vmspace;
 
-       pcb = lwp_getpcb(l);
-       if (type == T_MMUFLT && (l == &lwp0 || !pcb|| pcb->pcb_onfault == 0 || (
+       if (type == T_MMUFLT && (l == &lwp0 || onfault == 0 || (
 #ifdef M68060
             machineid & AMIGA_68060 ? code & FSLW_TM_SV :
 #endif
@@ -414,7 +418,9 @@
                printf("vm_fault(%p,%lx,%d)\n", map, va, ftype);
 #endif
 
+       pcb->pcb_onfault = NULL;
        rv = uvm_fault(map, va, ftype);
+       pcb->pcb_onfault = onfault;
 
 #ifdef DEBUG
        if (mmudebug)
@@ -503,8 +509,8 @@
        } else
                ksi.ksi_code = SEGV_MAPERR;
        if (type == T_MMUFLT) {
-               if (pcb->pcb_onfault) {
-                       trapcpfault(l, fp);
+               if (onfault) {
+                       trapcpfault(l, fp, rv);
                        return;
                }
                printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
@@ -540,18 +546,19 @@
        struct lwp *l;
        struct proc *p;
        struct pcb *pcb;
+       void *onfault;
        ksiginfo_t ksi;
        u_quad_t sticks = 0;
 
        l = curlwp;
+       p = l->l_proc;
+       pcb = lwp_getpcb(l);
+
        uvmexp.traps++;
 
        KSI_INIT_TRAP(&ksi);
        ksi.ksi_trap = type & ~T_USER;
 
-       p = l->l_proc;
-       pcb = lwp_getpcb(l);
-
        if (USERMODE(fp->f_sr)) {
                type |= T_USER;
                sticks = p->p_sticks;
@@ -578,9 +585,9 @@
         * Kernel Bus error
         */
        case T_BUSERR:
-               if (!l || !pcb || !pcb->pcb_onfault)
+               if (!pcb->pcb_onfault)
                        panictrap(type, code, v, fp);
-               trapcpfault(l, fp);
+               trapcpfault(l, fp, EFAULT);
                return;
        /*
         * User Bus/Addr error.
@@ -734,9 +741,9 @@
         * Kernel/User page fault
         */
        case T_MMUFLT:
-               if (l && pcb && (pcb->pcb_onfault == (void *)fubail ||
-                   pcb->pcb_onfault == (void *)subail)) {
-                       trapcpfault(l, fp);
+               onfault = pcb->pcb_onfault;
+               if (onfault == (void *)fubail || onfault == (void *)subail) {
+                       trapcpfault(l, fp, EFAULT);
                        return;
                }
                /*FALLTHROUGH*/
@@ -769,6 +776,7 @@
 {
        u_int wb_extra_page = 0;
        u_int wb_rc, mmusr;
+       void *onfault;
 



Home | Main Index | Thread Index | Old Index