Author: kib
Date: Sat Dec 12 20:06:25 2009
New Revision: 200443
URL: http://svn.freebsd.org/changeset/base/200443

Log:
  MFC r199135:
  Extract the code that records syscall results in the frame into MD
  function cpu_set_syscall_retval().

Modified:
  stable/8/sys/amd64/amd64/trap.c
  stable/8/sys/amd64/amd64/vm_machdep.c
  stable/8/sys/arm/arm/trap.c
  stable/8/sys/arm/arm/vm_machdep.c
  stable/8/sys/i386/i386/trap.c
  stable/8/sys/i386/i386/vm_machdep.c
  stable/8/sys/ia64/ia64/trap.c
  stable/8/sys/ia64/ia64/vm_machdep.c
  stable/8/sys/mips/include/pcb.h
  stable/8/sys/mips/mips/trap.c
  stable/8/sys/mips/mips/vm_machdep.c
  stable/8/sys/powerpc/aim/trap.c
  stable/8/sys/powerpc/aim/vm_machdep.c
  stable/8/sys/powerpc/booke/trap.c
  stable/8/sys/powerpc/booke/vm_machdep.c
  stable/8/sys/sparc64/include/pcb.h
  stable/8/sys/sparc64/sparc64/trap.c
  stable/8/sys/sparc64/sparc64/vm_machdep.c
  stable/8/sys/sun4v/sun4v/trap.c
  stable/8/sys/sun4v/sun4v/vm_machdep.c
  stable/8/sys/sys/proc.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/amd64/amd64/trap.c
==============================================================================
--- stable/8/sys/amd64/amd64/trap.c     Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/amd64/amd64/trap.c     Sat Dec 12 20:06:25 2009        
(r200443)
@@ -1004,39 +1004,7 @@ syscall(struct trapframe *frame)
 #endif
        }
 
-       switch (error) {
-       case 0:
-               frame->tf_rax = td->td_retval[0];
-               frame->tf_rdx = td->td_retval[1];
-               frame->tf_rflags &= ~PSL_C;
-               break;
-
-       case ERESTART:
-               /*
-                * Reconstruct pc, we know that 'syscall' is 2 bytes.
-                * We have to do a full context restore so that %r10
-                * (which was holding the value of %rcx) is restored for
-                * the next iteration.
-                */
-               frame->tf_rip -= frame->tf_err;
-               frame->tf_r10 = frame->tf_rcx;
-               td->td_pcb->pcb_flags |= PCB_FULLCTX;
-               break;
-
-       case EJUSTRETURN:
-               break;
-
-       default:
-               if (p->p_sysent->sv_errsize) {
-                       if (error >= p->p_sysent->sv_errsize)
-                               error = -1;     /* XXX */
-                       else
-                               error = p->p_sysent->sv_errtbl[error];
-               }
-               frame->tf_rax = error;
-               frame->tf_rflags |= PSL_C;
-               break;
-       }
+       cpu_set_syscall_retval(td, error);
 
        /*
         * Traced syscall.

Modified: stable/8/sys/amd64/amd64/vm_machdep.c
==============================================================================
--- stable/8/sys/amd64/amd64/vm_machdep.c       Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/amd64/amd64/vm_machdep.c       Sat Dec 12 20:06:25 2009        
(r200443)
@@ -317,6 +317,45 @@ cpu_thread_free(struct thread *td)
        cpu_thread_clean(td);
 }
 
+void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+
+       switch (error) {
+       case 0:
+               td->td_frame->tf_rax = td->td_retval[0];
+               td->td_frame->tf_rdx = td->td_retval[1];
+               td->td_frame->tf_rflags &= ~PSL_C;
+               break;
+
+       case ERESTART:
+               /*
+                * Reconstruct pc, we know that 'syscall' is 2 bytes.
+                * We have to do a full context restore so that %r10
+                * (which was holding the value of %rcx) is restored
+                * for the next iteration.
+                */
+               td->td_frame->tf_rip -= td->td_frame->tf_err;
+               td->td_frame->tf_r10 = td->td_frame->tf_rcx;
+               td->td_pcb->pcb_flags |= PCB_FULLCTX;
+               break;
+
+       case EJUSTRETURN:
+               break;
+
+       default:
+               if (td->td_proc->p_sysent->sv_errsize) {
+                       if (error >= td->td_proc->p_sysent->sv_errsize)
+                               error = -1;     /* XXX */
+                       else
+                               error = td->td_proc->p_sysent->sv_errtbl[error];
+               }
+               td->td_frame->tf_rax = error;
+               td->td_frame->tf_rflags |= PSL_C;
+               break;
+       }
+}
+
 /*
  * Initialize machine state (pcb and trap frame) for a new thread about to
  * upcall. Put enough state in the new thread's PCB to get it to go back 

Modified: stable/8/sys/arm/arm/trap.c
==============================================================================
--- stable/8/sys/arm/arm/trap.c Sat Dec 12 18:18:46 2009        (r200442)
+++ stable/8/sys/arm/arm/trap.c Sat Dec 12 20:06:25 2009        (r200443)
@@ -932,43 +932,8 @@ syscall(struct thread *td, trapframe_t *
                KASSERT(td->td_ar == NULL, 
                    ("returning from syscall with td_ar set!"));
        }
-       switch (error) {
-       case 0: 
-#ifdef __ARMEB__
-               if ((insn & 0x000fffff) == SYS___syscall &&
-                   code != SYS_freebsd6_lseek && code != SYS_lseek) {
-                       /*
-                        * 64-bit return, 32-bit syscall. Fixup byte order
-                        */ 
-                       frame->tf_r0 = 0;
-                       frame->tf_r1 = td->td_retval[0];
-               } else {
-                       frame->tf_r0 = td->td_retval[0];
-                       frame->tf_r1 = td->td_retval[1];
-               }
-#else
-               frame->tf_r0 = td->td_retval[0];
-               frame->tf_r1 = td->td_retval[1];
-#endif
-                                             
-               frame->tf_spsr &= ~PSR_C_bit;   /* carry bit */
-               break;
-               
-       case ERESTART:
-               /*
-                * Reconstruct the pc to point at the swi.
-                */
-               frame->tf_pc -= INSN_SIZE;
-               break;
-       case EJUSTRETURN:                                       
-               /* nothing to do */  
-               break;
-       default:
 bad:
-               frame->tf_r0 = error;
-               frame->tf_spsr |= PSR_C_bit;    /* carry bit */
-               break;
-       }
+       cpu_set_syscall_retval(td, error);
 
        WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
            (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???");

Modified: stable/8/sys/arm/arm/vm_machdep.c
==============================================================================
--- stable/8/sys/arm/arm/vm_machdep.c   Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/arm/arm/vm_machdep.c   Sat Dec 12 20:06:25 2009        
(r200443)
@@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/socketvar.h>
 #include <sys/sf_buf.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
 #include <sys/unistd.h>
 #include <machine/cpu.h>
 #include <machine/pcb.h>
@@ -261,6 +263,57 @@ done:
 #endif
 }
 
+void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+       trapframe_t *frame;
+       int fixup;
+#ifdef __ARMEB__
+       uint32_t insn;
+#endif
+
+       frame = td->td_frame;
+       fixup = 0;
+
+#ifdef __ARMEB__
+       insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
+       if ((insn & 0x000fffff) == SYS___syscall) {
+               register_t *ap = &frame->tf_r0;
+               register_t code = ap[_QUAD_LOWWORD];
+               if (td->td_proc->p_sysent->sv_mask)
+                       code &= td->td_proc->p_sysent->sv_mask;
+               fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek)
+                   ? 1 : 0;
+       }
+#endif
+
+       switch (error) {
+       case 0:
+               if (fixup) {
+                       frame->tf_r0 = 0;
+                       frame->tf_r1 = td->td_retval[0];
+               } else {
+                       frame->tf_r0 = td->td_retval[0];
+                       frame->tf_r1 = td->td_retval[1];
+               }
+               frame->tf_spsr &= ~PSR_C_bit;   /* carry bit */
+               break;
+       case ERESTART:
+               /*
+                * Reconstruct the pc to point at the swi.
+                */
+               frame->tf_pc -= INSN_SIZE;
+               break;
+       case EJUSTRETURN:
+               /* nothing to do */
+               break;
+       default:
+               frame->tf_r0 = error;
+               frame->tf_spsr |= PSR_C_bit;    /* carry bit */
+               break;
+       }
+}
+
 /*
  * Initialize machine state (pcb and trap frame) for a new thread about to
  * upcall. Put enough state in the new thread's PCB to get it to go back 

Modified: stable/8/sys/i386/i386/trap.c
==============================================================================
--- stable/8/sys/i386/i386/trap.c       Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/i386/i386/trap.c       Sat Dec 12 20:06:25 2009        
(r200443)
@@ -1093,35 +1093,7 @@ syscall(struct trapframe *frame)
 #endif
        }
 
-       switch (error) {
-       case 0:
-               frame->tf_eax = td->td_retval[0];
-               frame->tf_edx = td->td_retval[1];
-               frame->tf_eflags &= ~PSL_C;
-               break;
-
-       case ERESTART:
-               /*
-                * Reconstruct pc, assuming lcall $X,y is 7 bytes,
-                * int 0x80 is 2 bytes. We saved this in tf_err.
-                */
-               frame->tf_eip -= frame->tf_err;
-               break;
-
-       case EJUSTRETURN:
-               break;
-
-       default:
-               if (p->p_sysent->sv_errsize) {
-                       if (error >= p->p_sysent->sv_errsize)
-                               error = -1;     /* XXX */
-                       else
-                               error = p->p_sysent->sv_errtbl[error];
-               }
-               frame->tf_eax = error;
-               frame->tf_eflags |= PSL_C;
-               break;
-       }
+       cpu_set_syscall_retval(td, error);
 
        /*
         * Traced syscall.

Modified: stable/8/sys/i386/i386/vm_machdep.c
==============================================================================
--- stable/8/sys/i386/i386/vm_machdep.c Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/i386/i386/vm_machdep.c Sat Dec 12 20:06:25 2009        
(r200443)
@@ -381,6 +381,41 @@ cpu_thread_free(struct thread *td)
        cpu_thread_clean(td);
 }
 
+void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+
+       switch (error) {
+       case 0:
+               td->td_frame->tf_eax = td->td_retval[0];
+               td->td_frame->tf_edx = td->td_retval[1];
+               td->td_frame->tf_eflags &= ~PSL_C;
+               break;
+
+       case ERESTART:
+               /*
+                * Reconstruct pc, assuming lcall $X,y is 7 bytes, int
+                * 0x80 is 2 bytes. We saved this in tf_err.
+                */
+               td->td_frame->tf_eip -= td->td_frame->tf_err;
+               break;
+
+       case EJUSTRETURN:
+               break;
+
+       default:
+               if (td->td_proc->p_sysent->sv_errsize) {
+                       if (error >= td->td_proc->p_sysent->sv_errsize)
+                               error = -1;     /* XXX */
+                       else
+                               error = td->td_proc->p_sysent->sv_errtbl[error];
+               }
+               td->td_frame->tf_eax = error;
+               td->td_frame->tf_eflags |= PSL_C;
+               break;
+       }
+}
+
 /*
  * Initialize machine state (pcb and trap frame) for a new thread about to
  * upcall. Put enough state in the new thread's PCB to get it to go back 

Modified: stable/8/sys/ia64/ia64/trap.c
==============================================================================
--- stable/8/sys/ia64/ia64/trap.c       Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/ia64/ia64/trap.c       Sat Dec 12 20:06:25 2009        
(r200443)
@@ -976,26 +976,7 @@ syscall(struct trapframe *tf)
        error = (*callp->sy_call)(td, args);
        AUDIT_SYSCALL_EXIT(error, td);
 
-       if (error != EJUSTRETURN) {
-               /*
-                * Save the "raw" error code in r10. We use this to handle
-                * syscall restarts (see do_ast()).
-                */
-               tf->tf_scratch.gr10 = error;
-               if (error == 0) {
-                       tf->tf_scratch.gr8 = td->td_retval[0];
-                       tf->tf_scratch.gr9 = td->td_retval[1];
-               } else if (error != ERESTART) {
-                       if (error < p->p_sysent->sv_errsize)
-                               error = p->p_sysent->sv_errtbl[error];
-                       /*
-                        * Translated error codes are returned in r8. User
-                        * processes use the translated error code.
-                        */
-                       tf->tf_scratch.gr8 = error;
-               }
-       }
-
+       cpu_set_syscall_retval(td, error);
        td->td_syscalls++;
 
        /*

Modified: stable/8/sys/ia64/ia64/vm_machdep.c
==============================================================================
--- stable/8/sys/ia64/ia64/vm_machdep.c Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/ia64/ia64/vm_machdep.c Sat Dec 12 20:06:25 2009        
(r200443)
@@ -73,6 +73,7 @@
 #include <sys/malloc.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
+#include <sys/sysent.h>
 #include <sys/vnode.h>
 #include <sys/vmmeter.h>
 #include <sys/kernel.h>
@@ -140,6 +141,36 @@ cpu_thread_swapout(struct thread *td)
 }
 
 void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+       struct proc *p;
+       struct trapframe *tf;
+
+       if (error == EJUSTRETURN)
+               return;
+
+       tf = td->td_frame;
+
+       /*
+        * Save the "raw" error code in r10. We use this to handle
+        * syscall restarts (see do_ast()).
+        */
+       tf->tf_scratch.gr10 = error;
+       if (error == 0) {
+               tf->tf_scratch.gr8 = td->td_retval[0];
+               tf->tf_scratch.gr9 = td->td_retval[1];
+       } else if (error != ERESTART) {
+               p = td->td_proc;
+               if (error < p->p_sysent->sv_errsize)
+                       error = p->p_sysent->sv_errtbl[error];
+               /*
+                * Translated error codes are returned in r8. User
+                */
+               tf->tf_scratch.gr8 = error;
+       }
+}
+
+void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
        struct pcb *pcb;

Modified: stable/8/sys/mips/include/pcb.h
==============================================================================
--- stable/8/sys/mips/include/pcb.h     Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/mips/include/pcb.h     Sat Dec 12 20:06:25 2009        
(r200443)
@@ -52,6 +52,7 @@ struct pcb
        struct trapframe pcb_regs;      /* saved CPU and registers */
        label_t pcb_context;            /* kernel context for resume */
        int     pcb_onfault;            /* for copyin/copyout faults */
+       register_t pcb_tpc;
 };
 
 /* these match the regnum's in regnum.h

Modified: stable/8/sys/mips/mips/trap.c
==============================================================================
--- stable/8/sys/mips/mips/trap.c       Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/mips/mips/trap.c       Sat Dec 12 20:06:25 2009        
(r200443)
@@ -644,7 +644,6 @@ dofault:
                        struct trapframe *locr0 = td->td_frame;
                        struct sysent *callp;
                        unsigned int code;
-                       unsigned int tpc;
                        int nargs, nsaved;
                        register_t args[8];
 
@@ -660,7 +659,7 @@ dofault:
                                thread_user_enter(td);
 #endif
                        /* compute next PC after syscall instruction */
-                       tpc = trapframe->pc;    /* Remember if restart */
+                       td->td_pcb->pcb_tpc = trapframe->pc;    /* Remember if 
restart */
                        if (DELAYBRANCH(trapframe->cause)) {    /* Check BD bit 
*/
                                locr0->pc = MipsEmulateBranch(locr0, 
trapframe->pc, 0,
                                    0);
@@ -761,44 +760,7 @@ dofault:
                        locr0 = td->td_frame;
 #endif
                        trapdebug_enter(locr0, -code);
-                       switch (i) {
-                       case 0:
-                               if (quad_syscall && code != SYS_lseek) {
-                                       /*
-                                        * System call invoked through the
-                                        * SYS___syscall interface but the
-                                        * return value is really just 32
-                                        * bits.
-                                        */
-                                       locr0->v0 = td->td_retval[0];
-                                       if (_QUAD_LOWWORD)
-                                               locr0->v1 = td->td_retval[0];
-                                       locr0->a3 = 0;
-                               } else {
-                                       locr0->v0 = td->td_retval[0];
-                                       locr0->v1 = td->td_retval[1];
-                                       locr0->a3 = 0;
-                               }
-                               break;
-
-                       case ERESTART:
-                               locr0->pc = tpc;
-                               break;
-
-                       case EJUSTRETURN:
-                               break;  /* nothing to do */
-
-                       default:
-                               if (quad_syscall && code != SYS_lseek) {
-                                       locr0->v0 = i;
-                                       if (_QUAD_LOWWORD)
-                                               locr0->v1 = i;
-                                       locr0->a3 = 1;
-                               } else {
-                                       locr0->v0 = i;
-                                       locr0->a3 = 1;
-                               }
-                       }
+                       cpu_set_syscall_retval(td, i);
 
                        /*
                         * The sync'ing of I & D caches for SYS_ptrace() is

Modified: stable/8/sys/mips/mips/vm_machdep.c
==============================================================================
--- stable/8/sys/mips/mips/vm_machdep.c Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/mips/mips/vm_machdep.c Sat Dec 12 20:06:25 2009        
(r200443)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
+#include <sys/syscall.h>
 #include <sys/buf.h>
 #include <sys/vnode.h>
 #include <sys/vmmeter.h>
@@ -256,6 +257,62 @@ cpu_thread_alloc(struct thread *td)
        }
 }
 
+void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+       struct trapframe *locr0 = td->td_frame;
+       unsigned int code;
+       int quad_syscall;
+
+       code = locr0->v0;
+       quad_syscall = 0;
+       if (code == SYS_syscall)
+               code = locr0->a0;
+       else if (code == SYS___syscall) {
+               code = _QUAD_LOWWORD ? locr0->a1 : locr0->a0;
+               quad_syscall = 1;
+       }
+
+       switch (error) {
+       case 0:
+               if (quad_syscall && code != SYS_lseek) {
+                       /*
+                        * System call invoked through the
+                        * SYS___syscall interface but the
+                        * return value is really just 32
+                        * bits.
+                        */
+                       locr0->v0 = td->td_retval[0];
+                       if (_QUAD_LOWWORD)
+                               locr0->v1 = td->td_retval[0];
+                       locr0->a3 = 0;
+               } else {
+                       locr0->v0 = td->td_retval[0];
+                       locr0->v1 = td->td_retval[1];
+                       locr0->a3 = 0;
+               }
+               break;
+
+       case ERESTART:
+               locr0->pc = td->td_pcb->pcb_tpc;
+               break;
+
+       case EJUSTRETURN:
+               break;  /* nothing to do */
+
+       default:
+               if (quad_syscall && code != SYS_lseek) {
+                       locr0->v0 = error;
+                       if (_QUAD_LOWWORD)
+                               locr0->v1 = error;
+                       locr0->a3 = 1;
+               } else {
+                       locr0->v0 = error;
+                       locr0->a3 = 1;
+               }
+       }
+}
+
 /*
  * Initialize machine state (pcb and trap frame) for a new thread about to
  * upcall. Put enough state in the new thread's PCB to get it to go back

Modified: stable/8/sys/powerpc/aim/trap.c
==============================================================================
--- stable/8/sys/powerpc/aim/trap.c     Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/powerpc/aim/trap.c     Sat Dec 12 20:06:25 2009        
(r200443)
@@ -417,43 +417,8 @@ syscall(struct trapframe *frame)
                CTR3(KTR_SYSC, "syscall: p=%s %s ret=%x", td->td_name,
                     syscallnames[code], td->td_retval[0]);
        }
-       switch (error) {
-       case 0:
-               if (frame->fixreg[0] == SYS___syscall &&
-                   code != SYS_freebsd6_lseek && code != SYS_lseek) {
-                       /*
-                        * 64-bit return, 32-bit syscall. Fixup byte order
-                        */
-                       frame->fixreg[FIRSTARG] = 0;
-                       frame->fixreg[FIRSTARG + 1] = td->td_retval[0];
-               } else {
-                       frame->fixreg[FIRSTARG] = td->td_retval[0];
-                       frame->fixreg[FIRSTARG + 1] = td->td_retval[1];
-               }
-               /* XXX: Magic number */
-               frame->cr &= ~0x10000000;
-               break;
-       case ERESTART:
-               /*
-                * Set user's pc back to redo the system call.
-                */
-               frame->srr0 -= 4;
-               break;
-       case EJUSTRETURN:
-               /* nothing to do */
-               break;
-       default:
-               if (p->p_sysent->sv_errsize) {
-                       if (error >= p->p_sysent->sv_errsize)
-                               error = -1;     /* XXX */
-                       else
-                               error = p->p_sysent->sv_errtbl[error];
-               }
-               frame->fixreg[FIRSTARG] = error;
-               /* XXX: Magic number: Carry Flag Equivalent? */
-               frame->cr |= 0x10000000;
-               break;
-       }
+
+       cpu_set_syscall_retval(td, error);
 
        /*
         * Check for misbehavior.

Modified: stable/8/sys/powerpc/aim/vm_machdep.c
==============================================================================
--- stable/8/sys/powerpc/aim/vm_machdep.c       Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/powerpc/aim/vm_machdep.c       Sat Dec 12 20:06:25 2009        
(r200443)
@@ -81,7 +81,9 @@
 #include <sys/kernel.h>
 #include <sys/mbuf.h>
 #include <sys/sf_buf.h>
+#include <sys/syscall.h>
 #include <sys/sysctl.h>
+#include <sys/sysent.h>
 #include <sys/unistd.h>
 
 #include <machine/cpu.h>
@@ -422,6 +424,59 @@ cpu_thread_swapout(struct thread *td)
 }
 
 void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+       struct proc *p;
+       struct trapframe *tf;
+       int fixup;
+
+       if (error == EJUSTRETURN)
+               return;
+
+       p = td->td_proc;
+       tf = td->td_frame;
+
+       if (tf->fixreg[0] == SYS___syscall) {
+               int code = tf->fixreg[FIRSTARG + 1];
+               if (p->p_sysent->sv_mask)
+                       code &= p->p_sysent->sv_mask;
+               fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) ?
+                   1 : 0;
+       } else
+               fixup = 0;
+
+       switch (error) {
+       case 0:
+               if (fixup) {
+                       /*
+                        * 64-bit return, 32-bit syscall. Fixup byte order
+                        */
+                       tf->fixreg[FIRSTARG] = 0;
+                       tf->fixreg[FIRSTARG + 1] = td->td_retval[0];
+               } else {
+                       tf->fixreg[FIRSTARG] = td->td_retval[0];
+                       tf->fixreg[FIRSTARG + 1] = td->td_retval[1];
+               }
+               tf->cr &= ~0x10000000;          /* XXX: Magic number */
+               break;
+       case ERESTART:
+               /*
+                * Set user's pc back to redo the system call.
+                */
+               tf->srr0 -= 4;
+               break;
+       default:
+               if (p->p_sysent->sv_errsize) {
+                       error = (error < p->p_sysent->sv_errsize) ?
+                           p->p_sysent->sv_errtbl[error] : -1;
+               }
+               tf->fixreg[FIRSTARG] = error;
+               tf->cr |= 0x10000000;           /* XXX: Magic number */
+               break;
+       }
+}
+
+void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
        struct pcb *pcb2;

Modified: stable/8/sys/powerpc/booke/trap.c
==============================================================================
--- stable/8/sys/powerpc/booke/trap.c   Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/powerpc/booke/trap.c   Sat Dec 12 20:06:25 2009        
(r200443)
@@ -417,42 +417,7 @@ syscall(struct trapframe *frame)
                     syscallnames[code], td->td_retval[0]);
        }
 
-       switch (error) {
-       case 0:
-               if (frame->fixreg[0] == SYS___syscall && SYS_lseek) {
-                       /*
-                        * 64-bit return, 32-bit syscall. Fixup byte order
-                        */
-                       frame->fixreg[FIRSTARG] = 0;
-                       frame->fixreg[FIRSTARG + 1] = td->td_retval[0];
-               } else {
-                       frame->fixreg[FIRSTARG] = td->td_retval[0];
-                       frame->fixreg[FIRSTARG + 1] = td->td_retval[1];
-               }
-               /* XXX: Magic number */
-               frame->cr &= ~0x10000000;
-               break;
-       case ERESTART:
-               /*
-                * Set user's pc back to redo the system call.
-                */
-               frame->srr0 -= 4;
-               break;
-       case EJUSTRETURN:
-               /* nothing to do */
-               break;
-       default:
-               if (p->p_sysent->sv_errsize) {
-                       if (error >= p->p_sysent->sv_errsize)
-                               error = -1;     /* XXX */
-                       else
-                               error = p->p_sysent->sv_errtbl[error];
-               }
-               frame->fixreg[FIRSTARG] = error;
-               /* XXX: Magic number: Carry Flag Equivalent? */
-               frame->cr |= 0x10000000;
-               break;
-       }
+       cpu_set_syscall_retval(td, error);
 
        /*
         * Check for misbehavior.

Modified: stable/8/sys/powerpc/booke/vm_machdep.c
==============================================================================
--- stable/8/sys/powerpc/booke/vm_machdep.c     Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/powerpc/booke/vm_machdep.c     Sat Dec 12 20:06:25 2009        
(r200443)
@@ -113,7 +113,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/mbuf.h>
 #include <sys/sf_buf.h>
+#include <sys/syscall.h>
 #include <sys/sysctl.h>
+#include <sys/sysent.h>
 #include <sys/unistd.h>
 
 #include <machine/clock.h>
@@ -423,6 +425,59 @@ cpu_thread_swapout(struct thread *td)
 }
 
 void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+       struct proc *p;
+       struct trapframe *tf;
+       int fixup;
+
+       p = td->td_proc;
+       tf = td->td_frame;
+
+       if (tf->fixreg[0] == SYS___syscall) {
+               int code = tf->fixreg[FIRSTARG + 1];
+               if (p->p_sysent->sv_mask)
+                       code &= p->p_sysent->sv_mask;
+               fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) ?
+                   1 : 0;
+       } else
+               fixup = 0;
+
+       switch (error) {
+       case 0:
+               if (fixup) {
+                       /*
+                        * 64-bit return, 32-bit syscall. Fixup byte order
+                        */
+                       tf->fixreg[FIRSTARG] = 0;
+                       tf->fixreg[FIRSTARG + 1] = td->td_retval[0];
+               } else {
+                       tf->fixreg[FIRSTARG] = td->td_retval[0];
+                       tf->fixreg[FIRSTARG + 1] = td->td_retval[1];
+               }
+               tf->cr &= ~0x10000000;          /* XXX: Magic number */
+               break;
+       case ERESTART:
+               /*
+                * Set user's pc back to redo the system call.
+                */
+               tf->srr0 -= 4;
+               break;
+       case EJUSTRETURN:
+               /* nothing to do */
+               break;
+       default:
+               if (p->p_sysent->sv_errsize) {
+                       error = (error < p->p_sysent->sv_errsize) ?
+                           p->p_sysent->sv_errtbl[error] : -1;
+               }
+               tf->fixreg[FIRSTARG] = error;
+               tf->cr |= 0x10000000;           /* XXX: Magic number */
+               break;
+       }
+}
+
+void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
        struct pcb *pcb2;

Modified: stable/8/sys/sparc64/include/pcb.h
==============================================================================
--- stable/8/sys/sparc64/include/pcb.h  Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/sparc64/include/pcb.h  Sat Dec 12 20:06:25 2009        
(r200443)
@@ -49,7 +49,8 @@ struct pcb {
        uint64_t pcb_nsaved;
        uint64_t pcb_pc;
        uint64_t pcb_sp;
-       uint64_t pcb_pad[4];
+       uint64_t pcb_tpc;
+       uint64_t pcb_pad[3];
 } __aligned(64);
 
 #ifdef _KERNEL

Modified: stable/8/sys/sparc64/sparc64/trap.c
==============================================================================
--- stable/8/sys/sparc64/sparc64/trap.c Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/sparc64/sparc64/trap.c Sat Dec 12 20:06:25 2009        
(r200443)
@@ -538,7 +538,6 @@ syscall(struct trapframe *tf)
        register_t *argp;
        struct proc *p;
        u_long code;
-       u_long tpc;
        int reg;
        int regcnt;
        int narg;
@@ -562,7 +561,7 @@ syscall(struct trapframe *tf)
         * For syscalls, we don't want to retry the faulting instruction
         * (usually), instead we need to advance one instruction.
         */
-       tpc = tf->tf_tpc;
+       td->td_pcb->pcb_tpc = tf->tf_tpc;
        TF_DONE(tf);
 
        reg = 0;
@@ -626,39 +625,7 @@ syscall(struct trapframe *tf)
                    td->td_retval[1]);
        }
 
-       /*
-        * MP SAFE (we may or may not have the MP lock at this point)
-        */
-       switch (error) {
-       case 0:
-               tf->tf_out[0] = td->td_retval[0];
-               tf->tf_out[1] = td->td_retval[1];
-               tf->tf_tstate &= ~TSTATE_XCC_C;
-               break;
-
-       case ERESTART:
-               /*
-                * Undo the tpc advancement we have done above, we want to
-                * reexecute the system call.
-                */
-               tf->tf_tpc = tpc;
-               tf->tf_tnpc -= 4;
-               break;
-
-       case EJUSTRETURN:
-               break;
-
-       default:
-               if (p->p_sysent->sv_errsize) {
-                       if (error >= p->p_sysent->sv_errsize)
-                               error = -1;     /* XXX */
-                       else
-                               error = p->p_sysent->sv_errtbl[error];
-               }
-               tf->tf_out[0] = error;
-               tf->tf_tstate |= TSTATE_XCC_C;
-               break;
-       }
+       cpu_set_syscall_retval(td, error);
 
        /*
         * Check for misbehavior.

Modified: stable/8/sys/sparc64/sparc64/vm_machdep.c
==============================================================================
--- stable/8/sys/sparc64/sparc64/vm_machdep.c   Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/sparc64/sparc64/vm_machdep.c   Sat Dec 12 20:06:25 2009        
(r200443)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mbuf.h>
 #include <sys/mutex.h>
 #include <sys/proc.h>
+#include <sys/sysent.h>
 #include <sys/sf_buf.h>
 #include <sys/sched.h>
 #include <sys/sysctl.h>
@@ -166,6 +167,42 @@ cpu_thread_swapout(struct thread *td)
 }
 
 void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+
+       switch (error) {
+       case 0:
+               td->td_frame->tf_out[0] = td->td_retval[0];
+               td->td_frame->tf_out[1] = td->td_retval[1];
+               td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
+               break;
+
+       case ERESTART:
+               /*
+                * Undo the tpc advancement we have done on syscall
+                * enter, we want to reexecute the system call.
+                */
+               td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
+               td->td_frame->tf_tnpc -= 4;
+               break;
+
+       case EJUSTRETURN:
+               break;
+
+       default:
+               if (td->td_proc->p_sysent->sv_errsize) {
+                       if (error >= td->td_proc->p_sysent->sv_errsize)
+                               error = -1;     /* XXX */
+                       else
+                               error = td->td_proc->p_sysent->sv_errtbl[error];
+               }
+               td->td_frame->tf_out[0] = error;
+               td->td_frame->tf_tstate |= TSTATE_XCC_C;
+               break;
+       }
+}
+
+void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
        struct trapframe *tf;

Modified: stable/8/sys/sun4v/sun4v/trap.c
==============================================================================
--- stable/8/sys/sun4v/sun4v/trap.c     Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/sun4v/sun4v/trap.c     Sat Dec 12 20:06:25 2009        
(r200443)
@@ -81,6 +81,7 @@
 #include <machine/cpu.h>
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
+#include <machine/pcb.h>
 #include <machine/smp.h>
 #include <machine/trap.h>
 #include <machine/tstate.h>
@@ -582,7 +583,6 @@ syscall(struct trapframe *tf)
        register_t *argp;
        struct proc *p;
        u_long code;
-       u_long tpc;
        int reg;
        int regcnt;
        int narg;
@@ -606,7 +606,7 @@ syscall(struct trapframe *tf)
         * For syscalls, we don't want to retry the faulting instruction
         * (usually), instead we need to advance one instruction.
         */
-       tpc = tf->tf_tpc;
+       td->td_pcb->pcb_tpc = tf->tf_tpc;
        TF_DONE(tf);
 
        reg = 0;
@@ -673,40 +673,8 @@ syscall(struct trapframe *tf)
                    error, syscallnames[code], td->td_retval[0],
                    td->td_retval[1]);
        }
-       
-       /*
-        * MP SAFE (we may or may not have the MP lock at this point)
-        */
-       switch (error) {
-       case 0:
-               tf->tf_out[0] = td->td_retval[0];
-               tf->tf_out[1] = td->td_retval[1];
-               tf->tf_tstate &= ~TSTATE_XCC_C;
-               break;
 
-       case ERESTART:
-               /*
-                * Undo the tpc advancement we have done above, we want to
-                * reexecute the system call.
-                */
-               tf->tf_tpc = tpc;
-               tf->tf_tnpc -= 4;
-               break;
-
-       case EJUSTRETURN:
-               break;
-
-       default:
-               if (p->p_sysent->sv_errsize) {
-                       if (error >= p->p_sysent->sv_errsize)
-                               error = -1;     /* XXX */
-                       else
-                               error = p->p_sysent->sv_errtbl[error];
-               }
-               tf->tf_out[0] = error;
-               tf->tf_tstate |= TSTATE_XCC_C;
-               break;
-       }
+       cpu_set_syscall_retval(td, error);
 
        /*
         * Handle reschedule and other end-of-syscall issues

Modified: stable/8/sys/sun4v/sun4v/vm_machdep.c
==============================================================================
--- stable/8/sys/sun4v/sun4v/vm_machdep.c       Sat Dec 12 18:18:46 2009        
(r200442)
+++ stable/8/sys/sun4v/sun4v/vm_machdep.c       Sat Dec 12 20:06:25 2009        
(r200443)
@@ -57,6 +57,7 @@
 #include <sys/mutex.h>
 #include <sys/sf_buf.h>
 #include <sys/sysctl.h>
+#include <sys/sysent.h>
 #include <sys/unistd.h>
 #include <sys/vmmeter.h>
 
@@ -142,6 +143,42 @@ cpu_thread_swapout(struct thread *td)
 }
 
 void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+
+       switch (error) {
+       case 0:
+               td->td_frame->tf_out[0] = td->td_retval[0];
+               td->td_frame->tf_out[1] = td->td_retval[1];
+               td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
+               break;
+
+       case ERESTART:
+               /*
+                * Undo the tpc advancement we have done on syscall
+                * enter, we want to reexecute the system call.
+                */
+               td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
+               td->td_frame->tf_tnpc -= 4;
+               break;
+
+       case EJUSTRETURN:
+               break;
+
+       default:
+               if (td->td_proc->p_sysent->sv_errsize) {
+                       if (error >= td->td_proc->p_sysent->sv_errsize)
+                               error = -1;     /* XXX */
+                       else
+                               error = td->td_proc->p_sysent->sv_errtbl[error];
+               }
+               td->td_frame->tf_out[0] = error;
+               td->td_frame->tf_tstate |= TSTATE_XCC_C;
+               break;
+       }
+}
+
+void
 cpu_set_upcall(struct thread *td, struct thread *td0)
 {
        struct trapframe *tf;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to