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 ***
_______________________________________________
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