Author: kib
Date: Thu Oct  6 17:34:43 2011
New Revision: 226065
URL: http://svn.freebsd.org/changeset/base/226065

Log:
  Convert MIPS to the syscallenter/syscallret system call sequence handlers.
  This was the last architecture used custom syscall entry sequence.
  
  Reviewed, debugged, tested and approved by:   jchandra
  MFC after:    1 month

Modified:
  head/sys/mips/include/proc.h
  head/sys/mips/mips/elf64_machdep.c
  head/sys/mips/mips/elf_machdep.c
  head/sys/mips/mips/trap.c

Modified: head/sys/mips/include/proc.h
==============================================================================
--- head/sys/mips/include/proc.h        Thu Oct  6 16:13:47 2011        
(r226064)
+++ head/sys/mips/include/proc.h        Thu Oct  6 17:34:43 2011        
(r226065)
@@ -67,11 +67,22 @@ struct mdproc {
        /* empty */
 };
 
+#ifdef _KERNEL
 struct thread;
 
 void   mips_cpu_switch(struct thread *, struct thread *, struct mtx *);
 void   mips_cpu_throw(struct thread *, struct thread *);
 
+struct syscall_args {
+       u_int code;
+       struct sysent *callp;
+       register_t args[8];
+       int narg;
+       struct trapframe *trapframe;
+};
+#define        HAVE_SYSCALL_ARGS_DEF 1
+#endif
+
 #ifdef __mips_n64
 #define        KINFO_PROC_SIZE 1088
 #else

Modified: head/sys/mips/mips/elf64_machdep.c
==============================================================================
--- head/sys/mips/mips/elf64_machdep.c  Thu Oct  6 16:13:47 2011        
(r226064)
+++ head/sys/mips/mips/elf64_machdep.c  Thu Oct  6 17:34:43 2011        
(r226065)
@@ -80,8 +80,8 @@ struct sysentvec elf64_freebsd_sysvec = 
        .sv_maxssiz     = NULL,
        .sv_flags       = SV_ABI_FREEBSD | SV_LP64,
        .sv_set_syscall_retval = cpu_set_syscall_retval,
-       .sv_fetch_syscall_args = NULL, /* XXXKIB */
-       .sv_syscallnames = NULL,
+       .sv_fetch_syscall_args = cpu_fetch_syscall_args,
+       .sv_syscallnames = syscallnames,
        .sv_schedtail   = NULL,
 };
 

Modified: head/sys/mips/mips/elf_machdep.c
==============================================================================
--- head/sys/mips/mips/elf_machdep.c    Thu Oct  6 16:13:47 2011        
(r226064)
+++ head/sys/mips/mips/elf_machdep.c    Thu Oct  6 17:34:43 2011        
(r226065)
@@ -80,7 +80,7 @@ struct sysentvec elf64_freebsd_sysvec = 
        .sv_maxssiz     = NULL,
        .sv_flags       = SV_ABI_FREEBSD | SV_LP64,
        .sv_set_syscall_retval = cpu_set_syscall_retval,
-       .sv_fetch_syscall_args = NULL, /* XXXKIB */
+       .sv_fetch_syscall_args = cpu_fetch_syscall_args,
        .sv_syscallnames = syscallnames,
        .sv_schedtail   = NULL,
 };
@@ -136,7 +136,7 @@ struct sysentvec elf32_freebsd_sysvec = 
        .sv_maxssiz     = NULL,
        .sv_flags       = SV_ABI_FREEBSD | SV_ILP32,
        .sv_set_syscall_retval = cpu_set_syscall_retval,
-       .sv_fetch_syscall_args = NULL, /* XXXKIB */
+       .sv_fetch_syscall_args = cpu_fetch_syscall_args,
        .sv_syscallnames = syscallnames,
        .sv_schedtail   = NULL,
 };

Modified: head/sys/mips/mips/trap.c
==============================================================================
--- head/sys/mips/mips/trap.c   Thu Oct  6 16:13:47 2011        (r226064)
+++ head/sys/mips/mips/trap.c   Thu Oct  6 17:34:43 2011        (r226065)
@@ -261,6 +261,133 @@ static int emulate_unaligned_access(stru
 
 extern void fswintrberr(void); /* XXX */
 
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+{
+       struct trapframe *locr0 = td->td_frame;
+       struct sysentvec *se;
+       int error, nsaved;
+
+       bzero(sa->args, sizeof(sa->args));
+
+       /* compute next PC after syscall instruction */
+       td->td_pcb->pcb_tpc = sa->trapframe->pc; /* Remember if restart */
+       if (DELAYBRANCH(sa->trapframe->cause))   /* Check BD bit */
+               locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0);
+       else
+               locr0->pc += sizeof(int);
+       sa->code = locr0->v0;
+
+       switch (sa->code) {
+#if defined(__mips_n32) || defined(__mips_n64)
+       case SYS___syscall:
+               /*
+                * Quads fit in a single register in
+                * new ABIs.
+                *
+                * XXX o64?
+                */
+#endif
+       case SYS_syscall:
+               /*
+                * Code is first argument, followed by
+                * actual args.
+                */
+               sa->code = locr0->a0;
+               sa->args[0] = locr0->a1;
+               sa->args[1] = locr0->a2;
+               sa->args[2] = locr0->a3;
+               nsaved = 3;
+#if defined(__mips_n32) || defined(__mips_n64)
+               sa->args[3] = locr0->t4;
+               sa->args[4] = locr0->t5;
+               sa->args[5] = locr0->t6;
+               sa->args[6] = locr0->t7;
+               nsaved += 4;
+#endif
+               break;
+
+#if defined(__mips_o32)
+       case SYS___syscall:
+               /*
+                * Like syscall, but code is a quad, so as
+                * to maintain quad alignment for the rest
+                * of the arguments.
+                */
+               if (_QUAD_LOWWORD == 0)
+                       sa->code = locr0->a0;
+               else
+                       sa->code = locr0->a1;
+               sa->args[0] = locr0->a2;
+               sa->args[1] = locr0->a3;
+               nsaved = 2;
+               break;
+#endif
+
+       default:
+               sa->args[0] = locr0->a0;
+               sa->args[1] = locr0->a1;
+               sa->args[2] = locr0->a2;
+               sa->args[3] = locr0->a3;
+               nsaved = 4;
+#if defined (__mips_n32) || defined(__mips_n64)
+               sa->args[4] = locr0->t4;
+               sa->args[5] = locr0->t5;
+               sa->args[6] = locr0->t6;
+               sa->args[7] = locr0->t7;
+               nsaved += 4;
+#endif
+               break;
+       }
+#ifdef TRAP_DEBUG
+       if (trap_debug)
+               printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
+#endif
+
+       se = td->td_proc->p_sysent;
+       if (se->sv_mask)
+               sa->code &= se->sv_mask;
+
+       if (sa->code >= se->sv_size)
+               sa->callp = &se->sv_table[0];
+       else
+               sa->callp = &se->sv_table[sa->code];
+
+       sa->narg = sa->callp->sy_narg;
+
+       if (sa->narg > nsaved) {
+#if defined(__mips_n32) || defined(__mips_n64)
+               /*
+                * XXX
+                * Is this right for new ABIs?  I think the 4 there
+                * should be 8, size there are 8 registers to skip,
+                * not 4, but I'm not certain.
+                */
+               printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", sa->code,
+                   td->td_proc->p_pid);
+#endif
+               error = copyin((caddr_t)(intptr_t)(locr0->sp +
+                   4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved],
+                  (u_int)(sa->narg - nsaved) * sizeof(register_t));
+               if (error != 0) {
+                       locr0->v0 = error;
+                       locr0->a3 = 1;
+               }
+       } else
+               error = 0;
+
+       if (error == 0) {
+               td->td_retval[0] = 0;
+               td->td_retval[1] = locr0->v1;
+       }
+
+       return (error);
+}
+
+#undef __FBSDID
+#define __FBSDID(x)
+#include "../../kern/subr_syscall.c"
+
 /*
  * Handle an exception.
  * Called from MipsKernGenException() or MipsUserGenException()
@@ -527,177 +654,19 @@ dofault:
 
        case T_SYSCALL + T_USER:
                {
-                       struct trapframe *locr0 = td->td_frame;
-                       struct sysent *callp;
-                       unsigned int code;
-                       int nargs, nsaved;
-                       register_t args[8];
+                       struct syscall_args sa;
+                       int error;
 
-                       bzero(args, sizeof args);
-
-                       /*
-                        * note: PCPU_LAZY_INC() can only be used if we can
-                        * afford occassional inaccuracy in the count.
-                        */
-                       PCPU_LAZY_INC(cnt.v_syscall);
-                       if (td->td_ucred != p->p_ucred)
-                               cred_update_thread(td);
-#ifdef KSE
-                       if (p->p_flag & P_SA)
-                               thread_user_enter(td);
-#endif
-                       /* compute next PC after syscall instruction */
-                       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);
-                       } else {
-                               locr0->pc += sizeof(int);
-                       }
-                       code = locr0->v0;
-
-                       switch (code) {
-#if defined(__mips_n32) || defined(__mips_n64)
-                       case SYS___syscall:
-                               /*
-                                * Quads fit in a single register in
-                                * new ABIs.
-                                *
-                                * XXX o64?
-                                */
-#endif
-                       case SYS_syscall:
-                               /*
-                                * Code is first argument, followed by
-                                * actual args.
-                                */
-                               code = locr0->a0;
-                               args[0] = locr0->a1;
-                               args[1] = locr0->a2;
-                               args[2] = locr0->a3;
-                               nsaved = 3;
-#if defined(__mips_n32) || defined(__mips_n64)
-                               args[3] = locr0->t4;
-                               args[4] = locr0->t5;
-                               args[5] = locr0->t6;
-                               args[6] = locr0->t7;
-                               nsaved += 4;
-#endif
-                               break;
-
-#if defined(__mips_o32)
-                       case SYS___syscall:
-                               /*
-                                * Like syscall, but code is a quad, so as
-                                * to maintain quad alignment for the rest
-                                * of the arguments.
-                                */
-                               if (_QUAD_LOWWORD == 0) {
-                                       code = locr0->a0;
-                               } else {
-                                       code = locr0->a1;
-                               }
-                               args[0] = locr0->a2;
-                               args[1] = locr0->a3;
-                               nsaved = 2;
-                               break;
-#endif
-
-                       default:
-                               args[0] = locr0->a0;
-                               args[1] = locr0->a1;
-                               args[2] = locr0->a2;
-                               args[3] = locr0->a3;
-                               nsaved = 4;
-#if defined (__mips_n32) || defined(__mips_n64)
-                               args[4] = locr0->t4;
-                               args[5] = locr0->t5;
-                               args[6] = locr0->t6;
-                               args[7] = locr0->t7;
-                               nsaved += 4;
-#endif
-                       }
-#ifdef TRAP_DEBUG
-                       if (trap_debug) {
-                               printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
-                       }
-#endif
-
-                       if (p->p_sysent->sv_mask)
-                               code &= p->p_sysent->sv_mask;
-
-                       if (code >= p->p_sysent->sv_size)
-                               callp = &p->p_sysent->sv_table[0];
-                       else
-                               callp = &p->p_sysent->sv_table[code];
-
-                       nargs = callp->sy_narg;
-
-                       if (nargs > nsaved) {
-#if defined(__mips_n32) || defined(__mips_n64)
-                               /*
-                                * XXX
-                                * Is this right for new ABIs?  I think the 4 
there
-                                * should be 8, size there are 8 registers to 
skip,
-                                * not 4, but I'm not certain.
-                                */
-                               printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", 
code, p->p_pid);
-#endif
-                               i = copyin((caddr_t)(intptr_t)(locr0->sp +
-                                   4 * sizeof(register_t)), 
(caddr_t)&args[nsaved],
-                                   (u_int)(nargs - nsaved) * 
sizeof(register_t));
-                               if (i) {
-                                       locr0->v0 = i;
-                                       locr0->a3 = 1;
-#ifdef KTRACE
-                                       if (KTRPOINT(td, KTR_SYSCALL))
-                                               ktrsyscall(code, nargs, args);
-#endif
-                                       goto done;
-                               }
-                       }
-#ifdef TRAP_DEBUG
-                       if (trap_debug) {
-                               for (i = 0; i < nargs; i++) {
-                                       printf("args[%d] = %#jx\n", i, 
(intmax_t)args[i]);
-                               }
-                       }
-#endif
-#ifdef SYSCALL_TRACING
-                       printf("%s(", syscallnames[code]);
-                       for (i = 0; i < nargs; i++) {
-                               printf("%s%#jx", i == 0 ? "" : ", ", 
(intmax_t)args[i]);
-                       }
-                       printf(")\n");
-#endif
-#ifdef KTRACE
-                       if (KTRPOINT(td, KTR_SYSCALL))
-                               ktrsyscall(code, nargs, args);
-#endif
-                       td->td_retval[0] = 0;
-                       td->td_retval[1] = locr0->v1;
+                       sa.trapframe = trapframe;
+                       error = syscallenter(td, &sa);
 
 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
                        if (trp == trapdebug)
-                               trapdebug[TRAPSIZE - 1].code = code;
+                               trapdebug[TRAPSIZE - 1].code = sa.code;
                        else
-                               trp[-1].code = code;
+                               trp[-1].code = sa.code;
 #endif
-                       STOPEVENT(p, S_SCE, nargs);
-
-                       PTRACESTOP_SC(p, td, S_PT_SCE);
-                       i = (*callp->sy_call) (td, args);
-#if 0
-                       /*
-                        * Reinitialize proc pointer `p' as it may be
-                        * different if this is a child returning from fork
-                        * syscall.
-                        */
-                       td = curthread;
-                       locr0 = td->td_frame;
-#endif
-                       trapdebug_enter(locr0, -code);
-                       cpu_set_syscall_retval(td, i);
+                       trapdebug_enter(td->td_frame, -sa.code);
 
                        /*
                         * The sync'ing of I & D caches for SYS_ptrace() is
@@ -705,38 +674,7 @@ dofault:
                         * instead of being done here under a special check
                         * for SYS_ptrace().
                         */
-       done:
-                       /*
-                        * Check for misbehavior.
-                        */
-                       WITNESS_WARN(WARN_PANIC, NULL, "System call %s 
returning",
-                           (code >= 0 && code < SYS_MAXSYSCALL) ?
-                           syscallnames[code] : "???");
-                       KASSERT(td->td_critnest == 0,
-                           ("System call %s returning in a critical section",
-                           (code >= 0 && code < SYS_MAXSYSCALL) ?
-                           syscallnames[code] : "???"));
-                       KASSERT(td->td_locks == 0,
-                           ("System call %s returning with %d locks held",
-                           (code >= 0 && code < SYS_MAXSYSCALL) ?
-                           syscallnames[code] : "???",
-                           td->td_locks));
-                       userret(td, trapframe);
-#ifdef KTRACE
-                       if (KTRPOINT(td, KTR_SYSRET))
-                               ktrsysret(code, i, td->td_retval[0]);
-#endif
-                       /*
-                        * This works because errno is findable through the
-                        * register set.  If we ever support an emulation
-                        * where this is not the case, this code will need
-                        * to be revisited.
-                        */
-                       STOPEVENT(p, S_SCX, code);
-
-                       PTRACESTOP_SC(p, td, S_PT_SCX);
-
-                       mtx_assert(&Giant, MA_NOTOWNED);
+                       syscallret(td, error, &sa);
                        return (trapframe->pc);
                }
 
_______________________________________________
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