Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jan 2012 09:42:08 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r229374 - in stable/9/sys/mips: include mips
Message-ID:  <201201030942.q039g8kH015205@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Jan  3 09:42:08 2012
New Revision: 229374
URL: http://svn.freebsd.org/changeset/base/229374

Log:
  MFC r226065:
  Convert MIPS to the syscallenter/syscallret system call sequence handlers.

Modified:
  stable/9/sys/mips/include/proc.h
  stable/9/sys/mips/mips/elf64_machdep.c
  stable/9/sys/mips/mips/elf_machdep.c
  stable/9/sys/mips/mips/trap.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/mips/include/proc.h
==============================================================================
--- stable/9/sys/mips/include/proc.h	Tue Jan  3 09:40:31 2012	(r229373)
+++ stable/9/sys/mips/include/proc.h	Tue Jan  3 09:42:08 2012	(r229374)
@@ -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: stable/9/sys/mips/mips/elf64_machdep.c
==============================================================================
--- stable/9/sys/mips/mips/elf64_machdep.c	Tue Jan  3 09:40:31 2012	(r229373)
+++ stable/9/sys/mips/mips/elf64_machdep.c	Tue Jan  3 09:42:08 2012	(r229374)
@@ -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: stable/9/sys/mips/mips/elf_machdep.c
==============================================================================
--- stable/9/sys/mips/mips/elf_machdep.c	Tue Jan  3 09:40:31 2012	(r229373)
+++ stable/9/sys/mips/mips/elf_machdep.c	Tue Jan  3 09:42:08 2012	(r229374)
@@ -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: stable/9/sys/mips/mips/trap.c
==============================================================================
--- stable/9/sys/mips/mips/trap.c	Tue Jan  3 09:40:31 2012	(r229373)
+++ stable/9/sys/mips/mips/trap.c	Tue Jan  3 09:42:08 2012	(r229374)
@@ -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);
 		}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201030942.q039g8kH015205>