summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/os/exec.c7
-rw-r--r--usr/src/uts/common/os/lwp.c3
-rw-r--r--usr/src/uts/common/os/sig.c46
-rw-r--r--usr/src/uts/common/os/timers.c61
-rw-r--r--usr/src/uts/common/sys/proc.h1
-rw-r--r--usr/src/uts/common/sys/timer.h5
-rw-r--r--usr/src/uts/i86pc/os/trap.c2
-rw-r--r--usr/src/uts/intel/ia32/os/syscall.c49
-rw-r--r--usr/src/uts/intel/sys/archsystm.h5
-rw-r--r--usr/src/uts/sparc/os/syscall.c50
-rw-r--r--usr/src/uts/sparc/sys/archsystm.h1
-rw-r--r--usr/src/uts/sun4/os/trap.c2
12 files changed, 129 insertions, 103 deletions
diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c
index 2ca011f17b..7bd4273c1d 100644
--- a/usr/src/uts/common/os/exec.c
+++ b/usr/src/uts/common/os/exec.c
@@ -1801,6 +1801,13 @@ exec_args(execa_t *uap, uarg_t *args, intpdata_t *intp, void **auxvpp)
if (p->p_itimer != NULL)
timer_exit();
+ /*
+ * Delete the ITIMER_REALPROF interval timer.
+ * The other ITIMER_* interval timers are specified
+ * to be inherited across exec().
+ */
+ delete_itimer_realprof();
+
if (audit_active)
audit_exec(args->stk_base, args->stk_base + args->arglen,
args->na - args->ne, args->ne);
diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c
index a4bc1bffd2..bf827dd106 100644
--- a/usr/src/uts/common/os/lwp.c
+++ b/usr/src/uts/common/os/lwp.c
@@ -57,6 +57,7 @@
#include <sys/sdt.h>
#include <sys/cmn_err.h>
#include <sys/brand.h>
+#include <sys/cyclic.h>
/* hash function for the lwpid hash table, p->p_tidhash[] */
#define TIDHASH(tid, hash_sz) ((tid) & ((hash_sz) - 1))
@@ -205,7 +206,7 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p,
/*
* Allocate the SIGPROF buffer if ITIMER_REALPROF is in effect.
*/
- if (timerisset(&p->p_rprof_timer.it_value))
+ if (p->p_rprof_cyclic != CYCLIC_NONE)
t->t_rprof = kmem_zalloc(sizeof (struct rprof), KM_SLEEP);
if (cid != NOCLASS)
diff --git a/usr/src/uts/common/os/sig.c b/usr/src/uts/common/os/sig.c
index 454b9e600f..481d6575af 100644
--- a/usr/src/uts/common/os/sig.c
+++ b/usr/src/uts/common/os/sig.c
@@ -56,6 +56,7 @@
#include <sys/core.h>
#include <sys/schedctl.h>
#include <sys/contract/process_impl.h>
+#include <sys/cyclic.h>
#include <sys/dtrace.h>
#include <sys/sdt.h>
@@ -2550,6 +2551,51 @@ trapsig(k_siginfo_t *ip, int restartable)
mutex_exit(&p->p_lock);
}
+/*
+ * Arrange for the real time profiling signal to be dispatched.
+ */
+void
+realsigprof(int sysnum, int nsysarg, int error)
+{
+ proc_t *p;
+ klwp_t *lwp;
+
+ if (curthread->t_rprof->rp_anystate == 0)
+ return;
+ p = ttoproc(curthread);
+ lwp = ttolwp(curthread);
+ mutex_enter(&p->p_lock);
+ if (p->p_rprof_cyclic == CYCLIC_NONE) {
+ bzero(curthread->t_rprof, sizeof (*curthread->t_rprof));
+ mutex_exit(&p->p_lock);
+ return;
+ }
+ if (sigismember(&p->p_ignore, SIGPROF) ||
+ signal_is_blocked(curthread, SIGPROF)) {
+ mutex_exit(&p->p_lock);
+ return;
+ }
+ lwp->lwp_siginfo.si_signo = SIGPROF;
+ lwp->lwp_siginfo.si_code = PROF_SIG;
+ lwp->lwp_siginfo.si_errno = error;
+ hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp);
+ lwp->lwp_siginfo.si_syscall = sysnum;
+ lwp->lwp_siginfo.si_nsysarg = nsysarg;
+ lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault;
+ lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr;
+ lwp->lwp_lastfault = 0;
+ lwp->lwp_lastfaddr = NULL;
+ sigtoproc(p, curthread, SIGPROF);
+ mutex_exit(&p->p_lock);
+ ASSERT(lwp->lwp_cursig == 0);
+ if (issig(FORREAL))
+ psig();
+ mutex_enter(&p->p_lock);
+ lwp->lwp_siginfo.si_signo = 0;
+ bzero(curthread->t_rprof, sizeof (*curthread->t_rprof));
+ mutex_exit(&p->p_lock);
+}
+
#ifdef _SYSCALL32_IMPL
/*
diff --git a/usr/src/uts/common/os/timers.c b/usr/src/uts/common/os/timers.c
index fbc204e526..2fc7b7bff2 100644
--- a/usr/src/uts/common/os/timers.c
+++ b/usr/src/uts/common/os/timers.c
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -519,6 +520,61 @@ xsetitimer(uint_t which, struct itimerval *itv, int iskaddr)
}
/*
+ * Delete the ITIMER_REALPROF interval timer.
+ * Called only from exec_args() when exec occurs.
+ * The other ITIMER_* interval timers are specified
+ * to be inherited across exec(), so leave them alone.
+ */
+void
+delete_itimer_realprof(void)
+{
+ kthread_t *t = curthread;
+ struct proc *p = ttoproc(t);
+ klwp_t *lwp = ttolwp(t);
+ cyclic_id_t cyclic;
+
+ mutex_enter(&p->p_lock);
+
+ /* we are performing execve(); assert we are single-threaded */
+ ASSERT(t == p->p_tlist && t == t->t_forw);
+
+ if ((cyclic = p->p_rprof_cyclic) == CYCLIC_NONE) {
+ mutex_exit(&p->p_lock);
+ } else {
+ p->p_rprof_cyclic = CYCLIC_NONE;
+ /*
+ * Delete any current instance of SIGPROF.
+ */
+ if (lwp->lwp_cursig == SIGPROF) {
+ lwp->lwp_cursig = 0;
+ lwp->lwp_extsig = 0;
+ if (lwp->lwp_curinfo) {
+ siginfofree(lwp->lwp_curinfo);
+ lwp->lwp_curinfo = NULL;
+ }
+ }
+ /*
+ * Delete any pending instances of SIGPROF.
+ */
+ sigdelset(&p->p_sig, SIGPROF);
+ sigdelset(&p->p_extsig, SIGPROF);
+ sigdelq(p, NULL, SIGPROF);
+ sigdelset(&t->t_sig, SIGPROF);
+ sigdelset(&t->t_extsig, SIGPROF);
+ sigdelq(p, t, SIGPROF);
+
+ mutex_exit(&p->p_lock);
+
+ /*
+ * Remove the ITIMER_REALPROF cyclic.
+ */
+ mutex_enter(&cpu_lock);
+ cyclic_remove(cyclic);
+ mutex_exit(&cpu_lock);
+ }
+}
+
+/*
* Real interval timer expired:
* send process whose timer expired an alarm signal.
* If time is not set up to reload, then just return.
@@ -578,7 +634,8 @@ realprofexpire(void *arg)
kthread_t *t;
mutex_enter(&p->p_lock);
- if ((t = p->p_tlist) == NULL) {
+ if (p->p_rprof_cyclic == CYCLIC_NONE ||
+ (t = p->p_tlist) == NULL) {
mutex_exit(&p->p_lock);
return;
}
diff --git a/usr/src/uts/common/sys/proc.h b/usr/src/uts/common/sys/proc.h
index 43407bab38..daacb058f7 100644
--- a/usr/src/uts/common/sys/proc.h
+++ b/usr/src/uts/common/sys/proc.h
@@ -613,6 +613,7 @@ extern void psignal(proc_t *, int);
extern void tsignal(kthread_t *, int);
extern void sigtoproc(proc_t *, kthread_t *, int);
extern void trapsig(k_siginfo_t *, int);
+extern void realsigprof(int, int, int);
extern int eat_signal(kthread_t *, int);
extern int signal_is_blocked(kthread_t *, int);
extern int sigcheck(proc_t *, kthread_t *);
diff --git a/usr/src/uts/common/sys/timer.h b/usr/src/uts/common/sys/timer.h
index 05d08bb489..604ddf5d83 100644
--- a/usr/src/uts/common/sys/timer.h
+++ b/usr/src/uts/common/sys/timer.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_TIMER_H
#define _SYS_TIMER_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/proc.h>
#include <sys/thread.h>
@@ -106,6 +104,7 @@ extern void timespecsub(timespec_t *, timespec_t *);
extern void timespecfix(timespec_t *);
extern int xgetitimer(uint_t, struct itimerval *, int);
extern int xsetitimer(uint_t, struct itimerval *, int);
+extern void delete_itimer_realprof(void);
#define timerspecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec)
#define timerspeccmp(tvp, uvp) (((tvp)->tv_sec - (uvp)->tv_sec) ? \
diff --git a/usr/src/uts/i86pc/os/trap.c b/usr/src/uts/i86pc/os/trap.c
index fe6c2ca66b..cebc1d064a 100644
--- a/usr/src/uts/i86pc/os/trap.c
+++ b/usr/src/uts/i86pc/os/trap.c
@@ -1473,7 +1473,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
}
if (ct->t_rprof != NULL) {
- realsigprof(0, 0);
+ realsigprof(0, 0, 0);
ct->t_sig_check = 1;
}
diff --git a/usr/src/uts/intel/ia32/os/syscall.c b/usr/src/uts/intel/ia32/os/syscall.c
index ea01b28e7e..1ec901e231 100644
--- a/usr/src/uts/intel/ia32/os/syscall.c
+++ b/usr/src/uts/intel/ia32/os/syscall.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/vmparam.h>
#include <sys/types.h>
@@ -83,47 +81,6 @@ void deferred_singlestep_trap(caddr_t);
#endif
/*
- * Arrange for the real time profiling signal to be dispatched.
- */
-void
-realsigprof(int sysnum, int error)
-{
- proc_t *p;
- klwp_t *lwp;
-
- if (curthread->t_rprof->rp_anystate == 0)
- return;
- p = ttoproc(curthread);
- lwp = ttolwp(curthread);
- mutex_enter(&p->p_lock);
- if (sigismember(&p->p_ignore, SIGPROF) ||
- signal_is_blocked(curthread, SIGPROF)) {
- mutex_exit(&p->p_lock);
- return;
- }
- lwp->lwp_siginfo.si_signo = SIGPROF;
- lwp->lwp_siginfo.si_code = PROF_SIG;
- lwp->lwp_siginfo.si_errno = error;
- hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp);
- lwp->lwp_siginfo.si_syscall = sysnum;
- lwp->lwp_siginfo.si_nsysarg = (sysnum > 0 && sysnum < NSYSCALL) ?
- LWP_GETSYSENT(lwp)[sysnum].sy_narg : 0;
- lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault;
- lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr;
- lwp->lwp_lastfault = 0;
- lwp->lwp_lastfaddr = NULL;
- sigtoproc(p, curthread, SIGPROF);
- mutex_exit(&p->p_lock);
- ASSERT(lwp->lwp_cursig == 0);
- if (issig(FORREAL))
- psig();
- mutex_enter(&p->p_lock);
- lwp->lwp_siginfo.si_signo = 0;
- bzero(curthread->t_rprof, sizeof (*curthread->t_rprof));
- mutex_exit(&p->p_lock);
-}
-
-/*
* If watchpoints are active, don't make copying in of
* system call arguments take a read watchpoint trap.
*/
@@ -696,7 +653,9 @@ sig_check:
}
if (sigprof) {
- realsigprof(code, error);
+ int nargs = (code > 0 && code < NSYSCALL)?
+ LWP_GETSYSENT(lwp)[code].sy_narg : 0;
+ realsigprof(code, nargs, error);
t->t_sig_check = 1; /* recheck next time */
}
diff --git a/usr/src/uts/intel/sys/archsystm.h b/usr/src/uts/intel/sys/archsystm.h
index 44f8958723..fdd4f00478 100644
--- a/usr/src/uts/intel/sys/archsystm.h
+++ b/usr/src/uts/intel/sys/archsystm.h
@@ -18,8 +18,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -136,8 +137,6 @@ struct regs;
extern int instr_size(struct regs *, caddr_t *, enum seg_rw);
-extern void realsigprof(int, int);
-
extern int enable_cbcp; /* patchable in /etc/system */
extern uint_t cpu_hwcap_flags;
diff --git a/usr/src/uts/sparc/os/syscall.c b/usr/src/uts/sparc/os/syscall.c
index bc5b2824f9..ea6b4bdf38 100644
--- a/usr/src/uts/sparc/os/syscall.c
+++ b/usr/src/uts/sparc/os/syscall.c
@@ -20,12 +20,10 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/vmparam.h>
#include <sys/types.h>
@@ -84,48 +82,6 @@ lwp_getsysent(klwp_t *lwp)
#endif
/*
- * Arrange for the real time profiling signal to be dispatched.
- */
-void
-realsigprof(int sysnum, int error)
-{
- proc_t *p;
- klwp_t *lwp;
-
- if (curthread->t_rprof->rp_anystate == 0)
- return;
- p = ttoproc(curthread);
- lwp = ttolwp(curthread);
- mutex_enter(&p->p_lock);
- if (sigismember(&p->p_ignore, SIGPROF) ||
- signal_is_blocked(curthread, SIGPROF)) {
- mutex_exit(&p->p_lock);
- return;
- }
- lwp->lwp_siginfo.si_signo = SIGPROF;
- lwp->lwp_siginfo.si_code = PROF_SIG;
- lwp->lwp_siginfo.si_errno = error;
- hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp);
- lwp->lwp_siginfo.si_syscall = sysnum;
- lwp->lwp_siginfo.si_nsysarg = (sysnum > 0 && sysnum < NSYSCALL) ?
- LWP_GETSYSENT(lwp)[sysnum].sy_narg : 0;
- lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault;
- lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr;
- lwp->lwp_lastfault = 0;
- lwp->lwp_lastfaddr = NULL;
- sigtoproc(p, curthread, SIGPROF);
- mutex_exit(&p->p_lock);
- ASSERT(lwp->lwp_cursig == 0);
- if (issig(FORREAL)) {
- psig();
- }
- mutex_enter(&p->p_lock);
- lwp->lwp_siginfo.si_signo = 0;
- bzero(curthread->t_rprof, sizeof (*curthread->t_rprof));
- mutex_exit(&p->p_lock);
-}
-
-/*
* Called to restore the lwp's register window just before
* returning to user level (only if the registers have been
* fetched or modified through /proc).
@@ -793,7 +749,9 @@ sig_check:
}
if (sigprof) {
- realsigprof(code, error);
+ int nargs = (code > 0 && code < NSYSCALL)?
+ LWP_GETSYSENT(lwp)[code].sy_narg : 0;
+ realsigprof(code, nargs, error);
t->t_sig_check = 1; /* recheck next time */
}
diff --git a/usr/src/uts/sparc/sys/archsystm.h b/usr/src/uts/sparc/sys/archsystm.h
index 3d13f987bc..bdd3ea66b1 100644
--- a/usr/src/uts/sparc/sys/archsystm.h
+++ b/usr/src/uts/sparc/sys/archsystm.h
@@ -49,7 +49,6 @@ extern greg_t getpsr(void);
extern uint_t getpil(void);
extern void setpil(uint_t);
extern greg_t gettbr(void);
-extern void realsigprof(int, int);
extern uintptr_t shm_alignment;
diff --git a/usr/src/uts/sun4/os/trap.c b/usr/src/uts/sun4/os/trap.c
index 1bef1b475e..0d80f1e8d6 100644
--- a/usr/src/uts/sun4/os/trap.c
+++ b/usr/src/uts/sun4/os/trap.c
@@ -1312,7 +1312,7 @@ trap_cleanup(
}
if (curthread->t_rprof != NULL) {
- realsigprof(0, 0);
+ realsigprof(0, 0, 0);
curthread->t_sig_check = 1;
}
}