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, ¶ms);
- } 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,
- ¶ms);
- } 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-stable
mailing list