Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc Cast to register_t instead of int to be nic...



details:   https://anonhg.NetBSD.org/src/rev/4e90b0048864
branches:  trunk
changeset: 541844:4e90b0048864
user:      matt <matt%NetBSD.org@localhost>
date:      Sun Jan 19 02:43:11 2003 +0000

description:
Cast to register_t instead of int to be nicer for LP64.
Simplify copyin/copyout/copyinstr/copyoutstr.  Fix bug
where the user virtual address was not updated so that
if the user's buffer crossed a segment boundary, the
wrong data could be copied.  Localize USER_SR to the
ILP32 version of setusr/unsetusr.

diffstat:

 sys/arch/powerpc/include/pcb.h        |   10 +-
 sys/arch/powerpc/mpc6xx/genassym.cf   |    8 +-
 sys/arch/powerpc/powerpc/trap.c       |  217 +++++++++++++++++----------------
 sys/arch/powerpc/powerpc/vm_machdep.c |   26 ++-
 4 files changed, 138 insertions(+), 123 deletions(-)

diffs (truncated from 478 to 300 lines):

diff -r c539686de484 -r 4e90b0048864 sys/arch/powerpc/include/pcb.h
--- a/sys/arch/powerpc/include/pcb.h    Sun Jan 19 02:39:47 2003 +0000
+++ b/sys/arch/powerpc/include/pcb.h    Sun Jan 19 02:43:11 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcb.h,v 1.11 2002/11/03 22:36:23 matt Exp $    */
+/*     $NetBSD: pcb.h,v 1.12 2003/01/19 02:43:11 matt Exp $    */
 
 /*-
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -46,12 +46,14 @@
        struct pmap *pcb_pmreal; /* real address of above */
        register_t pcb_sp;      /* saved SP */
        int pcb_spl;            /* saved SPL */
+       int pcb_flags;
+#define        PCB_FPU         1       /* Process had FPU initialized */
+#define        PCB_ALTIVEC     2       /* Process had AltiVec initialized */
        struct cpu_info * __volatile pcb_fpcpu; /* CPU with our FP state */
        struct cpu_info * __volatile pcb_veccpu;/* CPU with our VECTOR state */
        faultbuf *pcb_onfault;  /* For use during copyin/copyout */
-       int pcb_flags;
-#define        PCB_FPU         1       /* Process had FPU initialized */
-#define PCB_ALTIVEC    2       /* Process had AltiVec initialized */
+       vaddr_t pcb_kmapsr;     /* where to map user segment in kernel */
+       vaddr_t pcb_umapsr;     /* the user segment mapped in kernel */
        struct fpu pcb_fpu;     /* Floating point processor */
        struct vreg *pcb_vr;
 };
diff -r c539686de484 -r 4e90b0048864 sys/arch/powerpc/mpc6xx/genassym.cf
--- a/sys/arch/powerpc/mpc6xx/genassym.cf       Sun Jan 19 02:39:47 2003 +0000
+++ b/sys/arch/powerpc/mpc6xx/genassym.cf       Sun Jan 19 02:43:11 2003 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: genassym.cf,v 1.7 2003/01/18 06:23:31 thorpej Exp $
+#      $NetBSD: genassym.cf,v 1.8 2003/01/19 02:43:12 matt Exp $
 
 #
 # Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -42,6 +42,8 @@
 
 include <powerpc/cpu.h>
 
+define CALLFRAMELEN    CALLFRAMELEN
+
 define FRAMELEN        FRAMELEN
 define FRAME_0         offsetof(struct trapframe, fixreg[0])
 define FRAME_1         offsetof(struct trapframe, fixreg[1])
@@ -95,7 +97,7 @@
 define SPFRAME_R3              offsetof(struct spillframe, r3)
 define SPFRAME_R0              offsetof(struct spillframe, r0)
 
-define SFRAMELEN       roundup(sizeof(struct switchframe), 16)
+define SFRAMELEN       roundup(sizeof(struct switchframe), CALLFRAMELEN)
 
 define PCB_PMR         offsetof(struct pcb, pcb_pmreal)
 define PCB_SP          offsetof(struct pcb, pcb_sp)
@@ -114,7 +116,7 @@
 define L_PRIORITY      offsetof(struct lwp, l_priority)
 define L_PROC          offsetof(struct lwp, l_proc)
 
-define LSONPROC                LSONPROC
+define LSONPROC        LSONPROC
 define P_MD_SYSCALL    offsetof(struct proc, p_md.md_syscall)
 
 define CI_SIZE         sizeof(struct cpu_info)
diff -r c539686de484 -r 4e90b0048864 sys/arch/powerpc/powerpc/trap.c
--- a/sys/arch/powerpc/powerpc/trap.c   Sun Jan 19 02:39:47 2003 +0000
+++ b/sys/arch/powerpc/powerpc/trap.c   Sun Jan 19 02:43:11 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.76 2003/01/18 21:28:12 matt Exp $   */
+/*     $NetBSD: trap.c,v 1.77 2003/01/19 02:43:12 matt Exp $   */
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -66,10 +66,11 @@
 #endif
 
 static int fix_unaligned __P((struct lwp *l, struct trapframe *frame));
-static inline void setusr __P((int));
+static inline vaddr_t setusr __P((vaddr_t, size_t *));
+static inline void unsetusr __P((void));
 
 void trap __P((struct trapframe *));   /* Called from locore / trap_subr */
-int setfault __P((faultbuf));  /* defined in locore.S */
+int setfault __P((faultbuf));          /* defined in locore.S */
 /* Why are these not defined in a header? */
 int badaddr __P((void *, size_t));
 int badaddr_read __P((void *, size_t, int *));
@@ -120,7 +121,7 @@
                 */
                if ((frame->dsisr & DSISR_NOTFOUND) &&
                    vm_map_pmap(kernel_map)->pm_evictions > 0 &&
-                   (va >> ADDR_SR_SHFT) != USER_SR &&
+                   (va >> ADDR_SR_SHFT) != pcb->pcb_kmapsr &&
                    pmap_pte_spill(vm_map_pmap(kernel_map), trunc_page(va)))
                        return;
 
@@ -129,13 +130,9 @@
                 */
                if (intr_depth < 0) {
                        KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
-                       if ((va >> ADDR_SR_SHFT) == USER_SR) {
-                               sr_t user_sr;
-
-                               asm ("mfsr %0, %1"
-                                    : "=r"(user_sr) : "K"(USER_SR));
+                       if ((va >> ADDR_SR_SHFT) == pcb->pcb_kmapsr) {
                                va &= ADDR_PIDX | ADDR_POFF;
-                               va |= user_sr << ADDR_SR_SHFT;
+                               va |= pcb->pcb_umapsr << ADDR_SR_SHFT;
                                map = &p->p_vmspace->vm_map;
                                /* KERNEL_PROC_LOCK(l); */
 
@@ -400,44 +397,72 @@
        userret(l, frame);
 }
 
-static inline void
-setusr(content)
-       int content;
+#ifdef _LP64
+static inline vaddr_t
+setusr(vaddr_t uva, size_t *len_p)
+{
+       *len_p = SEGMENT_LENGTH - (uva & ~SEGMENT_MASK);
+       return pmap_setusr(uva) + (uva & ~SEGMENT_MASK);
+}
+static void
+unsetusr(void)
+{
+       pmap_unsetusr();
+}
+#else
+static inline vaddr_t
+setusr(vaddr_t uva, size_t *len_p)
 {
-       asm volatile ("isync; mtsr %0,%1; isync"
-                     :: "n"(USER_SR), "r"(content));
+       struct pcb *pcb = curpcb;
+       vaddr_t p;
+       KASSERT(pcb->pcb_kmapsr == 0);
+       pcb->pcb_kmapsr = USER_SR;
+       pcb->pcb_umapsr = uva >> ADDR_SR_SHFT;
+       *len_p = SEGMENT_LENGTH - (uva & ~SEGMENT_MASK);
+       p = (USER_SR << ADDR_SR_SHFT) + (uva & ~SEGMENT_MASK);
+       __asm __volatile ("isync; mtsr %0,%1; isync"
+           ::  "n"(USER_SR), "r"(pcb->pcb_pm->pm_sr[pcb->pcb_umapsr]));
+       return p;
 }
 
+static void
+unsetusr(void)
+{
+       curpcb->pcb_kmapsr = 0;
+       __asm __volatile ("isync; mtsr %0,%1; isync"
+           ::  "n"(USER_SR), "r"(EMPTY_SEGMENT));
+}
+#endif
+
 int
 copyin(udaddr, kaddr, len)
        const void *udaddr;
        void *kaddr;
        size_t len;
 {
-       const char *up = udaddr;
+       vaddr_t uva = (vaddr_t) udaddr;
        char *kp = kaddr;
-       char *p;
-       int rv;
-       size_t l;
        faultbuf env;
+       int rv;
 
-       if ((rv = setfault(env)) != 0) {
-               curpcb->pcb_onfault = 0;
-               return rv;
-       }
+       if ((rv = setfault(env)) != 0)
+               goto out;
+
        while (len > 0) {
-               p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
-               l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
-               if (l > len)
-                       l = len;
-               setusr(curpcb->pcb_pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
-               memcpy(kp, p, l);
-               up += l;
-               kp += l;
-               len -= l;
+               size_t seglen;
+               vaddr_t p = setusr(uva, &seglen);
+               if (seglen > len)
+                       seglen = len;
+               memcpy(kp, (const char *) p, seglen);
+               uva += seglen;
+               kp += seglen;
+               len -= seglen;
        }
+
+  out:
+       unsetusr();
        curpcb->pcb_onfault = 0;
-       return 0;
+       return rv;
 }
 
 int
@@ -447,29 +472,28 @@
        size_t len;
 {
        const char *kp = kaddr;
-       char *up = udaddr;
-       char *p;
-       int rv;
-       size_t l;
+       vaddr_t uva = (vaddr_t) udaddr;
        faultbuf env;
+       int rv;
 
-       if ((rv = setfault(env)) != 0) {
-               curpcb->pcb_onfault = 0;
-               return rv;
-       }
+       if ((rv = setfault(env)) != 0)
+               goto out;
+
        while (len > 0) {
-               p = (char *)USER_ADDR + ((u_int)up & ~SEGMENT_MASK);
-               l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p;
-               if (l > len)
-                       l = len;
-               setusr(curpcb->pcb_pm->pm_sr[(u_int)up >> ADDR_SR_SHFT]);
-               memcpy(p, kp, l);
-               up += l;
-               kp += l;
-               len -= l;
+               size_t seglen;
+               vaddr_t p = setusr(uva, &seglen);
+               if (seglen > len)
+                       seglen = len;
+               memcpy((char *)p, kp, seglen);
+               uva += seglen;
+               kp += seglen;
+               len -= seglen;
        }
+
+  out:
+       unsetusr();
        curpcb->pcb_onfault = 0;
-       return 0;
+       return rv;
 }
 
 /*
@@ -492,15 +516,12 @@
        int rv;
 
        oldfault = curpcb->pcb_onfault;
-       if ((rv = setfault(env)) != 0) {
-               curpcb->pcb_onfault = oldfault;
-               return rv;
-       }
 
-       memcpy(dst, src, len);
+       if ((rv = setfault(env)) == 0)
+               memcpy(dst, src, len);
 
        curpcb->pcb_onfault = oldfault;
-       return 0;
+       return rv;
 }
 
 int
@@ -542,7 +563,7 @@
                x = *(volatile int32_t *)addr;
                break;
        default:
-               panic("badaddr: invalid size (%d)", size);
+               panic("badaddr: invalid size (%lu)", (u_long) size);
        }
 
        /* Make sure we took the machine check, if we caused one. */
@@ -631,41 +652,34 @@
        size_t len;
        size_t *done;
 {
-       const char *up = udaddr;
+       vaddr_t uva = (vaddr_t) udaddr;
        char *kp = kaddr;
-       char *p;
-       size_t l, ls, d;
        faultbuf env;
        int rv;
 
-       if ((rv = setfault(env)) != 0) {
-               curpcb->pcb_onfault = 0;
-               return rv;
-       }
-       d = 0;
+       if ((rv = setfault(env)) != 0)



Home | Main Index | Thread Index | Old Index