svn commit: r214755 - in stable/8/sys: amd64/amd64 amd64/conf amd64/ia32 amd64/include amd64/linux32 arm/arm cddl/dev/systrace compat/ia32 compat/svr4 conf i386/conf i386/i386 i386/ibcs2 i386/inclu...

Konstantin Belousov kib at FreeBSD.org
Wed Nov 3 21:21:13 UTC 2010


Author: kib
Date: Wed Nov  3 21:21:12 2010
New Revision: 214755
URL: http://svn.freebsd.org/changeset/base/214755

Log:
  MFC r208453:
  Reorganize syscall entry and leave handling.
  Implement ptrace_lwpinfo pl_flags PL_FLAG_SCE, PL_FLAG_SCX and
  PL_FLAG_EXEC.
  
  The i386, amd64, sparc64, sun4v, powerpc and ia64 syscall()s are
  changed to use syscallenter()/syscallret(). MIPS and arm are not
  converted and use the mostly unchanged syscall() implementation.
  
  MFC r208514:
  Change ia64' struct syscall_args definition so that args is a pointer to
  the arguments array instead of array itself.
  
  MFC r208566:
  Allow to use syscallname(9) outside subr_trap.c.
  
  MFC r209258 (by rpaulo):
  Make DTrace syscall provider work again by including opt_kdtrace.h here.
  
  MFC r209313:
  Only enable kdtrace hook in the LINT on the architectures that implement it.
  
  MFC r209697:
  Obey sv_syscallnames bounds in syscallname().
  
  NOTE: The KBI of the struct sysentvec is changed, new required members
  sv_set_syscall_retval, sv_fetch_syscall_args and sv_syscallnames are
  added. The sv_prepsyscall field is now ignored. Third-party modules
  using the struct sysentvec must be modified and recompiled, we believe
  that only ABI emulators are affected. No such out-of-tree modules are
  known. In-tree modules that are affected by the change were converted
  to depend on exact version of the kernel, see r214421.

Modified:
  stable/8/sys/amd64/amd64/elf_machdep.c
  stable/8/sys/amd64/amd64/trap.c
  stable/8/sys/amd64/conf/NOTES
  stable/8/sys/amd64/ia32/ia32_syscall.c
  stable/8/sys/amd64/include/proc.h
  stable/8/sys/amd64/linux32/linux32_sysvec.c
  stable/8/sys/arm/arm/elf_machdep.c
  stable/8/sys/arm/arm/trap.c
  stable/8/sys/cddl/dev/systrace/systrace.c
  stable/8/sys/compat/ia32/ia32_sysvec.c
  stable/8/sys/compat/ia32/ia32_util.h
  stable/8/sys/compat/svr4/svr4_sysvec.c
  stable/8/sys/conf/NOTES
  stable/8/sys/conf/files
  stable/8/sys/i386/conf/NOTES
  stable/8/sys/i386/i386/elf_machdep.c
  stable/8/sys/i386/i386/trap.c
  stable/8/sys/i386/ibcs2/ibcs2_sysvec.c
  stable/8/sys/i386/include/proc.h
  stable/8/sys/i386/linux/linux_sysvec.c
  stable/8/sys/ia64/ia32/ia32_trap.c
  stable/8/sys/ia64/ia64/elf_machdep.c
  stable/8/sys/ia64/ia64/trap.c
  stable/8/sys/ia64/include/proc.h
  stable/8/sys/kern/imgact_aout.c
  stable/8/sys/kern/init_main.c
  stable/8/sys/kern/kern_exec.c
  stable/8/sys/kern/kern_sig.c
  stable/8/sys/kern/subr_trap.c
  stable/8/sys/kern/sys_process.c
  stable/8/sys/mips/mips/elf64_machdep.c
  stable/8/sys/mips/mips/elf_machdep.c
  stable/8/sys/mips/mips/trap.c
  stable/8/sys/powerpc/aim/trap.c
  stable/8/sys/powerpc/booke/trap.c
  stable/8/sys/powerpc/include/proc.h
  stable/8/sys/powerpc/powerpc/elf_machdep.c
  stable/8/sys/sparc64/include/proc.h
  stable/8/sys/sparc64/sparc64/elf_machdep.c
  stable/8/sys/sparc64/sparc64/trap.c
  stable/8/sys/sun4v/include/proc.h
  stable/8/sys/sun4v/sun4v/trap.c
  stable/8/sys/sys/proc.h
  stable/8/sys/sys/ptrace.h
  stable/8/sys/sys/sysent.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/elf_machdep.c
==============================================================================
--- stable/8/sys/amd64/amd64/elf_machdep.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/amd64/amd64/elf_machdep.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/exec.h>
 #include <sys/imgact.h>
 #include <sys/linker.h>
+#include <sys/proc.h>
 #include <sys/sysent.h>
 #include <sys/imgact_elf.h>
 #include <sys/syscall.h>
@@ -74,7 +75,10 @@ struct sysentvec elf64_freebsd_sysvec = 
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_LP64
+	.sv_flags	= SV_ABI_FREEBSD | SV_LP64,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = syscallnames,
 };
 
 static Elf64_Brandinfo freebsd_brand_info = {

Modified: stable/8/sys/amd64/amd64/trap.c
==============================================================================
--- stable/8/sys/amd64/amd64/trap.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/amd64/amd64/trap.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -76,7 +76,6 @@ __FBSDID("$FreeBSD$");
 #ifdef HWPMC_HOOKS
 #include <sys/pmckern.h>
 #endif
-#include <security/audit/audit.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -170,8 +169,6 @@ static int prot_fault_translation = 0;
 SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
 	&prot_fault_translation, 0, "Select signal to deliver on protection fault");
 
-extern char *syscallnames[];
-
 /*
  * Exception, fault, and trap interface to the FreeBSD kernel.
  * This common code is called from assembly language IDT gate entry
@@ -804,19 +801,12 @@ dblfault_handler(struct trapframe *frame
 	panic("double fault");
 }
 
-struct syscall_args {
-	u_int code;
-	struct sysent *callp;
-	register_t args[8];
-	register_t *argp;
-	int narg;
-};
-
-static int
-fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
 {
 	struct proc *p;
 	struct trapframe *frame;
+	register_t *argp;
 	caddr_t params;
 	int reg, regcnt, error;
 
@@ -828,15 +818,10 @@ fetch_syscall_args(struct thread *td, st
 	params = (caddr_t)frame->tf_rsp + sizeof(register_t);
 	sa->code = frame->tf_rax;
 
-	if (p->p_sysent->sv_prepsyscall) {
-		(*p->p_sysent->sv_prepsyscall)(frame, (int *)sa->args,
-		    &sa->code, &params);
-	} else {
-		if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
-			sa->code = frame->tf_rdi;
-			reg++;
-			regcnt--;
-		}
+	if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
+		sa->code = frame->tf_rdi;
+		reg++;
+		regcnt--;
 	}
  	if (p->p_sysent->sv_mask)
  		sa->code &= p->p_sysent->sv_mask;
@@ -850,24 +835,20 @@ fetch_syscall_args(struct thread *td, st
 	KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
 	    ("Too many syscall arguments!"));
 	error = 0;
-	sa->argp = &frame->tf_rdi;
-	sa->argp += reg;
-	bcopy(sa->argp, sa->args, sizeof(sa->args[0]) * regcnt);
+	argp = &frame->tf_rdi;
+	argp += reg;
+	bcopy(argp, sa->args, sizeof(sa->args[0]) * regcnt);
 	if (sa->narg > regcnt) {
 		KASSERT(params != NULL, ("copyin args with no params!"));
 		error = copyin(params, &sa->args[regcnt],
 	    	    (sa->narg - regcnt) * sizeof(sa->args[0]));
 	}
-	sa->argp = &sa->args[0];
 
-	/*
-	 * This may result in two records if debugger modified
-	 * registers or memory during sleep at stop/ptrace point.
-	 */
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_SYSCALL))
-		ktrsyscall(sa->code, sa->narg, sa->argp);
-#endif
+	if (error == 0) {
+		td->td_retval[0] = 0;
+		td->td_retval[1] = frame->tf_rdx;
+	}
+
 	return (error);
 }
 
@@ -880,87 +861,22 @@ void
 syscall(struct trapframe *frame)
 {
 	struct thread *td;
-	struct proc *p;
 	struct syscall_args sa;
 	register_t orig_tf_rflags;
 	int error;
 	ksiginfo_t ksi;
 
-	PCPU_INC(cnt.v_syscall);
-	td = curthread;
-	p = td->td_proc;
-	td->td_syscalls++;
-
 #ifdef DIAGNOSTIC
 	if (ISPL(frame->tf_cs) != SEL_UPL) {
 		panic("syscall");
 		/* NOT REACHED */
 	}
 #endif
-
-	td->td_pticks = 0;
-	td->td_frame = frame;
-	if (td->td_ucred != p->p_ucred) 
-		cred_update_thread(td);
 	orig_tf_rflags = frame->tf_rflags;
-	if (p->p_flag & P_TRACED) {
-		PROC_LOCK(p);
-		td->td_dbgflags &= ~TDB_USERWR;
-		PROC_UNLOCK(p);
-	}
-	error = fetch_syscall_args(td, &sa);
-
-	CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
-	    td->td_proc->p_pid, td->td_name, sa.code);
-
-	if (error == 0) {
-		td->td_retval[0] = 0;
-		td->td_retval[1] = frame->tf_rdx;
-
-		STOPEVENT(p, S_SCE, sa.narg);
-		PTRACESTOP_SC(p, td, S_PT_SCE);
-		if (td->td_dbgflags & TDB_USERWR) {
-			/*
-			 * Reread syscall number and arguments if
-			 * debugger modified registers or memory.
-			 */
-			error = fetch_syscall_args(td, &sa);
-			if (error != 0)
-				goto retval;
-			td->td_retval[1] = frame->tf_rdx;
-		}
-
-#ifdef KDTRACE_HOOKS
-		/*
-		 * If the systrace module has registered it's probe
-		 * callback and if there is a probe active for the
-		 * syscall 'entry', process the probe.
-		 */
-		if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
-			(*systrace_probe_func)(sa.callp->sy_entry, sa.code,
-			    sa.callp, sa.args);
-#endif
-
-		AUDIT_SYSCALL_ENTER(sa.code, td);
-		error = (*sa.callp->sy_call)(td, sa.argp);
-		AUDIT_SYSCALL_EXIT(error, td);
-
-		/* Save the latest error return value. */
-		td->td_errno = error;
+	td = curthread;
+	td->td_frame = frame;
 
-#ifdef KDTRACE_HOOKS
-		/*
-		 * If the systrace module has registered it's probe
-		 * callback and if there is a probe active for the
-		 * syscall 'return', process the probe.
-		 */
-		if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
-			(*systrace_probe_func)(sa.callp->sy_return, sa.code,
-			    sa.callp, sa.args);
-#endif
-	}
- retval:
-	cpu_set_syscall_retval(td, error);
+	error = syscallenter(td, &sa);
 
 	/*
 	 * Traced syscall.
@@ -974,40 +890,5 @@ syscall(struct trapframe *frame)
 		trapsignal(td, &ksi);
 	}
 
-	/*
-	 * Check for misbehavior.
-	 */
-	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     syscallnames[sa.code] : "???");
-	KASSERT(td->td_critnest == 0,
-	    ("System call %s returning in a critical section",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     syscallnames[sa.code] : "???"));
-	KASSERT(td->td_locks == 0,
-	    ("System call %s returning with %d locks held",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     syscallnames[sa.code] : "???", td->td_locks));
-
-	/*
-	 * Handle reschedule and other end-of-syscall issues
-	 */
-	userret(td, frame);
-
-	CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
-	    td->td_proc->p_pid, td->td_name, sa.code);
-
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_SYSRET))
-		ktrsysret(sa.code, error, 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, sa.code);
-
-	PTRACESTOP_SC(p, td, S_PT_SCX);
+	syscallret(td, error, &sa);
 }

Modified: stable/8/sys/amd64/conf/NOTES
==============================================================================
--- stable/8/sys/amd64/conf/NOTES	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/amd64/conf/NOTES	Wed Nov  3 21:21:12 2010	(r214755)
@@ -11,6 +11,12 @@
 # We want LINT to cover profiling as well.
 profile         2
 
+#
+# Enable the kernel DTrace hooks which are required to load the DTrace
+# kernel modules.
+#
+options 	KDTRACE_HOOKS
+
 
 #####################################################################
 # SMP OPTIONS:

Modified: stable/8/sys/amd64/ia32/ia32_syscall.c
==============================================================================
--- stable/8/sys/amd64/ia32/ia32_syscall.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/amd64/ia32/ia32_syscall.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/ktr.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
 #include <sys/ptrace.h>
 #include <sys/resourcevar.h>
 #include <sys/signalvar.h>
@@ -81,62 +82,54 @@ __FBSDID("$FreeBSD$");
 #include <machine/intr_machdep.h>
 #include <machine/md_var.h>
 
+#include <compat/freebsd32/freebsd32_util.h>
+
 #define	IDTVEC(name)	__CONCAT(X,name)
 
 extern inthand_t IDTVEC(int0x80_syscall), IDTVEC(rsvd);
-extern const char *freebsd32_syscallnames[];
 
 void ia32_syscall(struct trapframe *frame);	/* Called from asm code */
 
-struct ia32_syscall_args {
-	u_int code;
-	caddr_t params;
-	struct sysent *callp;
-	u_int64_t args64[8];
-	int narg;
-};
+void
+ia32_set_syscall_retval(struct thread *td, int error)
+{
 
-static int
-fetch_ia32_syscall_args(struct thread *td, struct ia32_syscall_args *sa)
+	cpu_set_syscall_retval(td, error);
+}
+
+int
+ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
 {
 	struct proc *p;
 	struct trapframe *frame;
+	caddr_t params;
 	u_int32_t args[8];
 	int error, i;
 
 	p = td->td_proc;
 	frame = td->td_frame;
 
-	sa->params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t);
+	params = (caddr_t)frame->tf_rsp + sizeof(u_int32_t);
 	sa->code = frame->tf_rax;
 
-	if (p->p_sysent->sv_prepsyscall) {
+	/*
+	 * Need to check if this is a 32 bit or 64 bit syscall.
+	 */
+	if (sa->code == SYS_syscall) {
 		/*
-		 * The prep code is MP aware.
+		 * Code is first argument, followed by actual args.
 		 */
-		(*p->p_sysent->sv_prepsyscall)(frame, args, &sa->code,
-		    &sa->params);
-	} else {
+		sa->code = fuword32(params);
+		params += sizeof(int);
+	} else if (sa->code == SYS___syscall) {
 		/*
-		 * Need to check if this is a 32 bit or 64 bit syscall.
-		 * fuword is MP aware.
+		 * Like syscall, but code is a quad, so as to maintain
+		 * quad alignment for the rest of the arguments.
+		 * We use a 32-bit fetch in case params is not
+		 * aligned.
 		 */
-		if (sa->code == SYS_syscall) {
-			/*
-			 * Code is first argument, followed by actual args.
-			 */
-			sa->code = fuword32(sa->params);
-			sa->params += sizeof(int);
-		} else if (sa->code == SYS___syscall) {
-			/*
-			 * Like syscall, but code is a quad, so as to maintain
-			 * quad alignment for the rest of the arguments.
-			 * We use a 32-bit fetch in case params is not
-			 * aligned.
-			 */
-			sa->code = fuword32(sa->params);
-			sa->params += sizeof(quad_t);
-		}
+		sa->code = fuword32(params);
+		params += sizeof(quad_t);
 	}
  	if (p->p_sysent->sv_mask)
  		sa->code &= p->p_sysent->sv_mask;
@@ -146,19 +139,19 @@ fetch_ia32_syscall_args(struct thread *t
  		sa->callp = &p->p_sysent->sv_table[sa->code];
 	sa->narg = sa->callp->sy_narg;
 
-	if (sa->params != NULL && sa->narg != 0)
-		error = copyin(sa->params, (caddr_t)args,
+	if (params != NULL && sa->narg != 0)
+		error = copyin(params, (caddr_t)args,
 		    (u_int)(sa->narg * sizeof(int)));
 	else
 		error = 0;
 
 	for (i = 0; i < sa->narg; i++)
-		sa->args64[i] = args[i];
+		sa->args[i] = args[i];
 
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_SYSCALL))
-		ktrsyscall(sa->code, sa->narg, sa->args64);
-#endif
+	if (error == 0) {
+		td->td_retval[0] = 0;
+		td->td_retval[1] = frame->tf_rdx;
+	}
 
 	return (error);
 }
@@ -167,58 +160,16 @@ void
 ia32_syscall(struct trapframe *frame)
 {
 	struct thread *td;
-	struct proc *p;
-	struct ia32_syscall_args sa;
+	struct syscall_args sa;
 	register_t orig_tf_rflags;
 	int error;
 	ksiginfo_t ksi;
 
-	PCPU_INC(cnt.v_syscall);
+	orig_tf_rflags = frame->tf_rflags;
 	td = curthread;
-	p = td->td_proc;
-	td->td_syscalls++;
-
-	td->td_pticks = 0;
 	td->td_frame = frame;
-	if (td->td_ucred != p->p_ucred) 
-		cred_update_thread(td);
-	orig_tf_rflags = frame->tf_rflags;
-	if (p->p_flag & P_TRACED) {
-		PROC_LOCK(p);
-		td->td_dbgflags &= ~TDB_USERWR;
-		PROC_UNLOCK(p);
-	}
-	error = fetch_ia32_syscall_args(td, &sa);
-
-	CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
-	    td->td_proc->p_pid, td->td_name, sa.code);
-
-	if (error == 0) {
-		td->td_retval[0] = 0;
-		td->td_retval[1] = frame->tf_rdx;
 
-		STOPEVENT(p, S_SCE, sa.narg);
-		PTRACESTOP_SC(p, td, S_PT_SCE);
-		if (td->td_dbgflags & TDB_USERWR) {
-			/*
-			 * Reread syscall number and arguments if
-			 * debugger modified registers or memory.
-			 */
-			error = fetch_ia32_syscall_args(td, &sa);
-			if (error != 0)
-				goto retval;
-			td->td_retval[1] = frame->tf_rdx;
-		}
-
-		AUDIT_SYSCALL_ENTER(sa.code, td);
-		error = (*sa.callp->sy_call)(td, sa.args64);
-		AUDIT_SYSCALL_EXIT(error, td);
-
-		/* Save the latest error return value. */
-		td->td_errno = error;
-	}
- retval:
-	cpu_set_syscall_retval(td, error);
+	error = syscallenter(td, &sa);
 
 	/*
 	 * Traced syscall.
@@ -232,44 +183,9 @@ ia32_syscall(struct trapframe *frame)
 		trapsignal(td, &ksi);
 	}
 
-	/*
-	 * Check for misbehavior.
-	 */
-	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     freebsd32_syscallnames[sa.code] : "???");
-	KASSERT(td->td_critnest == 0,
-	    ("System call %s returning in a critical section",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     freebsd32_syscallnames[sa.code] : "???"));
-	KASSERT(td->td_locks == 0,
-	    ("System call %s returning with %d locks held",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     freebsd32_syscallnames[sa.code] : "???", td->td_locks));
-
-	/*
-	 * Handle reschedule and other end-of-syscall issues
-	 */
-	userret(td, frame);
-
-	CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
-	    td->td_proc->p_pid, td->td_proc->p_comm, sa.code);
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_SYSRET))
-		ktrsysret(sa.code, error, 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, sa.code);
- 
-	PTRACESTOP_SC(p, td, S_PT_SCX);
+	syscallret(td, error, &sa);
 }
 
-
 static void
 ia32_syscall_enable(void *dummy)
 {

Modified: stable/8/sys/amd64/include/proc.h
==============================================================================
--- stable/8/sys/amd64/include/proc.h	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/amd64/include/proc.h	Wed Nov  3 21:21:12 2010	(r214755)
@@ -79,6 +79,14 @@ int amd64_set_ldt_data(struct thread *td
 extern struct mtx dt_lock;
 extern int max_ldt_segment;
 
+struct syscall_args {
+	u_int code;
+	struct sysent *callp;
+	register_t args[8];
+	int narg;
+};
+#define	HAVE_SYSCALL_ARGS_DEF 1
+
 #endif  /* _KERNEL */
 
 #endif /* !_MACHINE_PROC_H_ */

Modified: stable/8/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- stable/8/sys/amd64/linux32/linux32_sysvec.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/amd64/linux32/linux32_sysvec.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -121,8 +121,6 @@ SET_DECLARE(linux_device_handler_set, st
 static int	elf_linux_fixup(register_t **stack_base,
 		    struct image_params *iparams);
 static register_t *linux_copyout_strings(struct image_params *imgp);
-static void	linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
-		    caddr_t *params);
 static void     linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask);
 static void	exec_linux_setregs(struct thread *td, u_long entry,
 				   u_long stack, u_long ps_strings);
@@ -764,19 +762,33 @@ linux_rt_sigreturn(struct thread *td, st
 	return (EJUSTRETURN);
 }
 
-/*
- * MPSAFE
- */
-static void
-linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
+static int
+linux32_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
 {
-	args[0] = tf->tf_rbx;
-	args[1] = tf->tf_rcx;
-	args[2] = tf->tf_rdx;
-	args[3] = tf->tf_rsi;
-	args[4] = tf->tf_rdi;
-	args[5] = tf->tf_rbp;	/* Unconfirmed */
-	*params = NULL;		/* no copyin */
+	struct proc *p;
+	struct trapframe *frame;
+
+	p = td->td_proc;
+	frame = td->td_frame;
+
+	sa->args[0] = frame->tf_rbx;
+	sa->args[1] = frame->tf_rcx;
+	sa->args[2] = frame->tf_rdx;
+	sa->args[3] = frame->tf_rsi;
+	sa->args[4] = frame->tf_rdi;
+	sa->args[5] = frame->tf_rbp;	/* Unconfirmed */
+	sa->code = frame->tf_rax;
+
+	if (sa->code >= p->p_sysent->sv_size)
+		sa->callp = &p->p_sysent->sv_table[0];
+	else
+		sa->callp = &p->p_sysent->sv_table[sa->code];
+	sa->narg = sa->callp->sy_narg;
+
+	td->td_retval[0] = 0;
+	td->td_retval[1] = frame->tf_rdx;
+
+	return (0);
 }
 
 /*
@@ -1043,7 +1055,7 @@ struct sysentvec elf_linux_sysvec = {
 	.sv_sendsig	= linux_sendsig,
 	.sv_sigcode	= linux_sigcode,
 	.sv_szsigcode	= &linux_szsigcode,
-	.sv_prepsyscall	= linux_prepsyscall,
+	.sv_prepsyscall	= NULL,
 	.sv_name	= "Linux ELF32",
 	.sv_coredump	= elf32_coredump,
 	.sv_imgact_try	= exec_linux_imgact_try,
@@ -1058,7 +1070,10 @@ struct sysentvec elf_linux_sysvec = {
 	.sv_setregs	= exec_linux_setregs,
 	.sv_fixlimit	= linux32_fixlimit,
 	.sv_maxssiz	= &linux32_maxssiz,
-	.sv_flags	= SV_ABI_LINUX | SV_ILP32 | SV_IA32
+	.sv_flags	= SV_ABI_LINUX | SV_ILP32 | SV_IA32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = linux32_fetch_syscall_args,
+	.sv_syscallnames = NULL,
 };
 
 static char GNU_ABI_VENDOR[] = "GNU";

Modified: stable/8/sys/arm/arm/elf_machdep.c
==============================================================================
--- stable/8/sys/arm/arm/elf_machdep.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/arm/arm/elf_machdep.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/linker.h>
 #include <sys/sysent.h>
 #include <sys/imgact_elf.h>
+#include <sys/proc.h>
 #include <sys/syscall.h>
 #include <sys/signalvar.h>
 #include <sys/vnode.h>
@@ -73,7 +74,10 @@ struct sysentvec elf32_freebsd_sysvec = 
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32
+	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = NULL, /* XXXKIB */
+	.sv_syscallnames = syscallnames,
 };
 
 static Elf32_Brandinfo freebsd_brand_info = {

Modified: stable/8/sys/arm/arm/trap.c
==============================================================================
--- stable/8/sys/arm/arm/trap.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/arm/arm/trap.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -130,7 +130,6 @@ void undefinedinstruction(trapframe_t *)
 #include <machine/machdep.h>
  
 extern char fusubailout[];
-extern char *syscallnames[];
 
 #ifdef DEBUG
 int last_fault_code;	/* For the benefit of pmap_fault_fixup() */

Modified: stable/8/sys/cddl/dev/systrace/systrace.c
==============================================================================
--- stable/8/sys/cddl/dev/systrace/systrace.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/cddl/dev/systrace/systrace.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -77,7 +77,6 @@ extern struct sysent linux_sysent[];
  */
 #include <sys/syscall.h>
 #include <kern/systrace_args.c>
-extern const char	*syscallnames[];
 #define	DEVNAME		"dtrace/systrace"
 #define	PROVNAME	"syscall"
 #define	MAXSYSCALL	SYS_MAXSYSCALL

Modified: stable/8/sys/compat/ia32/ia32_sysvec.c
==============================================================================
--- stable/8/sys/compat/ia32/ia32_sysvec.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/compat/ia32/ia32_sysvec.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -93,6 +93,8 @@ CTASSERT(sizeof(struct ia32_ucontext4) =
 CTASSERT(sizeof(struct ia32_sigframe4) == 408);
 #endif
 
+extern const char *freebsd32_syscallnames[];
+
 static void ia32_fixlimit(struct rlimit *rl, int which);
 
 SYSCTL_NODE(_compat, OID_AUTO, ia32, CTLFLAG_RW, 0, "ia32 mode");
@@ -135,7 +137,10 @@ struct sysentvec ia32_freebsd_sysvec = {
 	.sv_setregs	= ia32_setregs,
 	.sv_fixlimit	= ia32_fixlimit,
 	.sv_maxssiz	= &ia32_maxssiz,
-	.sv_flags	= SV_ABI_FREEBSD | SV_IA32 | SV_ILP32
+	.sv_flags	= SV_ABI_FREEBSD | SV_IA32 | SV_ILP32,
+	.sv_set_syscall_retval = ia32_set_syscall_retval,
+	.sv_fetch_syscall_args = ia32_fetch_syscall_args,
+	.sv_syscallnames = freebsd32_syscallnames,
 };
 
 

Modified: stable/8/sys/compat/ia32/ia32_util.h
==============================================================================
--- stable/8/sys/compat/ia32/ia32_util.h	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/compat/ia32/ia32_util.h	Wed Nov  3 21:21:12 2010	(r214755)
@@ -47,3 +47,7 @@
 #define	IA32_MAXDSIZ	(512*1024*1024)		/* 512MB */
 #define	IA32_MAXSSIZ	(64*1024*1024)		/* 64MB */
 #define IA32_MAXVMEM	0			/* Unlimited */
+
+struct syscall_args;
+int ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
+void ia32_set_syscall_retval(struct thread *, int);

Modified: stable/8/sys/compat/svr4/svr4_sysvec.c
==============================================================================
--- stable/8/sys/compat/svr4/svr4_sysvec.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/compat/svr4/svr4_sysvec.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -191,7 +191,10 @@ struct sysentvec svr4_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz     = NULL,
-	.sv_flags	= SV_ABI_UNDEF | SV_IA32 | SV_ILP32
+	.sv_flags	= SV_ABI_UNDEF | SV_IA32 | SV_ILP32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = NULL,
 };
 
 const char      svr4_emul_path[] = "/compat/svr4";

Modified: stable/8/sys/conf/NOTES
==============================================================================
--- stable/8/sys/conf/NOTES	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/conf/NOTES	Wed Nov  3 21:21:12 2010	(r214755)
@@ -363,12 +363,6 @@ options 	DDB_NUMSYM
 options 	GDB
 
 #
-# Enable the kernel DTrace hooks which are required to load the DTrace
-# kernel modules.
-#
-options 	KDTRACE_HOOKS
-
-#
 # SYSCTL_DEBUG enables a 'sysctl' debug tree that can be used to dump the
 # contents of the registered sysctl nodes on the console.  It is disabled by
 # default because it generates excessively verbose console output that can

Modified: stable/8/sys/conf/files
==============================================================================
--- stable/8/sys/conf/files	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/conf/files	Wed Nov  3 21:21:12 2010	(r214755)
@@ -2171,7 +2171,7 @@ kern/sys_generic.c		standard
 kern/sys_pipe.c			standard
 kern/sys_process.c		standard
 kern/sys_socket.c		standard
-kern/syscalls.c			optional witness | invariants | kdtrace_hooks
+kern/syscalls.c			standard
 kern/sysv_ipc.c			standard
 kern/sysv_msg.c			optional sysvmsg
 kern/sysv_sem.c			optional sysvsem

Modified: stable/8/sys/i386/conf/NOTES
==============================================================================
--- stable/8/sys/i386/conf/NOTES	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/i386/conf/NOTES	Wed Nov  3 21:21:12 2010	(r214755)
@@ -11,6 +11,12 @@
 # We want LINT to cover profiling as well.
 profile         2
 
+#
+# Enable the kernel DTrace hooks which are required to load the DTrace
+# kernel modules.
+#
+options 	KDTRACE_HOOKS
+
 
 #####################################################################
 # SMP OPTIONS:

Modified: stable/8/sys/i386/i386/elf_machdep.c
==============================================================================
--- stable/8/sys/i386/i386/elf_machdep.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/i386/i386/elf_machdep.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/exec.h>
 #include <sys/imgact.h>
 #include <sys/linker.h>
+#include <sys/proc.h>
 #include <sys/sysent.h>
 #include <sys/imgact_elf.h>
 #include <sys/syscall.h>
@@ -73,7 +74,10 @@ struct sysentvec elf32_freebsd_sysvec = 
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_FREEBSD | SV_IA32 | SV_ILP32
+	.sv_flags	= SV_ABI_FREEBSD | SV_IA32 | SV_ILP32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = syscallnames,
 };
 
 static Elf32_Brandinfo freebsd_brand_info = {

Modified: stable/8/sys/i386/i386/trap.c
==============================================================================
--- stable/8/sys/i386/i386/trap.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/i386/i386/trap.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -184,8 +184,6 @@ static int prot_fault_translation = 0;
 SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
 	&prot_fault_translation, 0, "Select signal to deliver on protection fault");
 
-extern char *syscallnames[];
-
 /*
  * Exception, fault, and trap interface to the FreeBSD kernel.
  * This common code is called from assembly language IDT gate entry
@@ -971,16 +969,8 @@ dblfault_handler()
 	panic("double fault");
 }
 
-struct syscall_args {
-	u_int code;
-	struct sysent *callp;
-	int args[8];
-	register_t *argp;
-	int narg;
-};
-
-static int
-fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
 {
 	struct proc *p;
 	struct trapframe *frame;
@@ -993,27 +983,22 @@ fetch_syscall_args(struct thread *td, st
 	params = (caddr_t)frame->tf_esp + sizeof(int);
 	sa->code = frame->tf_eax;
 
-	if (p->p_sysent->sv_prepsyscall) {
-		(*p->p_sysent->sv_prepsyscall)(frame, sa->args, &sa->code,
-		    &params);
-	} else {
+	/*
+	 * Need to check if this is a 32 bit or 64 bit syscall.
+	 */
+	if (sa->code == SYS_syscall) {
 		/*
-		 * Need to check if this is a 32 bit or 64 bit syscall.
+		 * Code is first argument, followed by actual args.
 		 */
-		if (sa->code == SYS_syscall) {
-			/*
-			 * Code is first argument, followed by actual args.
-			 */
-			sa->code = fuword(params);
-			params += sizeof(int);
-		} else if (sa->code == SYS___syscall) {
-			/*
-			 * Like syscall, but code is a quad, so as to maintain
-			 * quad alignment for the rest of the arguments.
-			 */
-			sa->code = fuword(params);
-			params += sizeof(quad_t);
-		}
+		sa->code = fuword(params);
+		params += sizeof(int);
+	} else if (sa->code == SYS___syscall) {
+		/*
+		 * Like syscall, but code is a quad, so as to maintain
+		 * quad alignment for the rest of the arguments.
+		 */
+		sa->code = fuword(params);
+		params += sizeof(quad_t);
 	}
 
  	if (p->p_sysent->sv_mask)
@@ -1029,11 +1014,12 @@ fetch_syscall_args(struct thread *td, st
 		    (u_int)(sa->narg * sizeof(int)));
 	else
 		error = 0;
+
+	if (error == 0) {
+		td->td_retval[0] = 0;
+		td->td_retval[1] = frame->tf_edx;
+	}
 		
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_SYSCALL))
-		ktrsyscall(sa->code, sa->narg, sa->args);
-#endif
 	return (error);
 }
 
@@ -1046,87 +1032,23 @@ void
 syscall(struct trapframe *frame)
 {
 	struct thread *td;
-	struct proc *p;
 	struct syscall_args sa;
 	register_t orig_tf_eflags;
 	int error;
 	ksiginfo_t ksi;
 
-	PCPU_INC(cnt.v_syscall);
-	td = curthread;
-	p = td->td_proc;
-	td->td_syscalls++;
-
 #ifdef DIAGNOSTIC
 	if (ISPL(frame->tf_cs) != SEL_UPL) {
 		panic("syscall");
 		/* NOT REACHED */
 	}
 #endif
-
-	td->td_pticks = 0;
-	td->td_frame = frame;
-	if (td->td_ucred != p->p_ucred) 
-		cred_update_thread(td);
 	orig_tf_eflags = frame->tf_eflags;
-	if (p->p_flag & P_TRACED) {
-		PROC_LOCK(p);
-		td->td_dbgflags &= ~TDB_USERWR;
-		PROC_UNLOCK(p);
-	}
-	error = fetch_syscall_args(td, &sa);
-
-	CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
-	    td->td_proc->p_pid, td->td_name, sa.code);
-
-	if (error == 0) {
-		td->td_retval[0] = 0;
-		td->td_retval[1] = frame->tf_edx;
-
-		STOPEVENT(p, S_SCE, sa.narg);
-		PTRACESTOP_SC(p, td, S_PT_SCE);
-		if (td->td_dbgflags & TDB_USERWR) {
-			/*
-			 * Reread syscall number and arguments if
-			 * debugger modified registers or memory.
-			 */
-			error = fetch_syscall_args(td, &sa);
-			if (error != 0)
-				goto retval;
-			td->td_retval[1] = frame->tf_edx;
-		}
-
-#ifdef KDTRACE_HOOKS
-		/*
-		 * If the systrace module has registered it's probe
-		 * callback and if there is a probe active for the
-		 * syscall 'entry', process the probe.
-		 */
-		if (systrace_probe_func != NULL && sa.callp->sy_entry != 0)
-			(*systrace_probe_func)(sa.callp->sy_entry, sa.code,
-			    sa.callp, sa.args);
-#endif
 
-		AUDIT_SYSCALL_ENTER(sa.code, td);
-		error = (*sa.callp->sy_call)(td, sa.args);
-		AUDIT_SYSCALL_EXIT(error, td);
+	td = curthread;
+	td->td_frame = frame;
 
-		/* Save the latest error return value. */
-		td->td_errno = error;
-
-#ifdef KDTRACE_HOOKS
-		/*
-		 * If the systrace module has registered it's probe
-		 * callback and if there is a probe active for the
-		 * syscall 'return', process the probe.
-		 */
-		if (systrace_probe_func != NULL && sa.callp->sy_return != 0)
-			(*systrace_probe_func)(sa.callp->sy_return, sa.code,
-			    sa.callp, sa.args);
-#endif
-	}
- retval:
-	cpu_set_syscall_retval(td, error);
+	error = syscallenter(td, &sa);
 
 	/*
 	 * Traced syscall.
@@ -1140,41 +1062,5 @@ syscall(struct trapframe *frame)
 		trapsignal(td, &ksi);
 	}
 
-	/*
-	 * Check for misbehavior.
-	 */
-	WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     syscallnames[sa.code] : "???");
-	KASSERT(td->td_critnest == 0,
-	    ("System call %s returning in a critical section",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     syscallnames[sa.code] : "???"));
-	KASSERT(td->td_locks == 0,
-	    ("System call %s returning with %d locks held",
-	    (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
-	     syscallnames[sa.code] : "???", td->td_locks));
-
-	/*
-	 * Handle reschedule and other end-of-syscall issues
-	 */
-	userret(td, frame);
-
-	CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
-	    td->td_proc->p_pid, td->td_name, sa.code);
-
-#ifdef KTRACE
-	if (KTRPOINT(td, KTR_SYSRET))
-		ktrsysret(sa.code, error, 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, sa.code);
-
-	PTRACESTOP_SC(p, td, S_PT_SCX);
+	syscallret(td, error, &sa);
 }
-

Modified: stable/8/sys/i386/ibcs2/ibcs2_sysvec.c
==============================================================================
--- stable/8/sys/i386/ibcs2/ibcs2_sysvec.c	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/i386/ibcs2/ibcs2_sysvec.c	Wed Nov  3 21:21:12 2010	(r214755)
@@ -86,7 +86,10 @@ struct sysentvec ibcs2_svr3_sysvec = {
 	.sv_setregs	= exec_setregs,
 	.sv_fixlimit	= NULL,
 	.sv_maxssiz	= NULL,
-	.sv_flags	= SV_ABI_UNDEF | SV_IA32 | SV_ILP32
+	.sv_flags	= SV_ABI_UNDEF | SV_IA32 | SV_ILP32,
+	.sv_set_syscall_retval = cpu_set_syscall_retval,
+	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
+	.sv_syscallnames = NULL,
 };
 
 static int

Modified: stable/8/sys/i386/include/proc.h
==============================================================================
--- stable/8/sys/i386/include/proc.h	Wed Nov  3 21:10:12 2010	(r214754)
+++ stable/8/sys/i386/include/proc.h	Wed Nov  3 21:21:12 2010	(r214755)
@@ -77,6 +77,14 @@ void	user_ldt_deref(struct proc_ldt *pld
 
 extern struct mtx dt_lock;
 
+struct syscall_args {
+	u_int code;
+	struct sysent *callp;
+	register_t args[8];
+	int narg;
+};
+#define	HAVE_SYSCALL_ARGS_DEF 1
+
 #endif	/* _KERNEL */
 
 #endif /* !_MACHINE_PROC_H_ */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list