--- a/usr/src/uts/common/os/fork.c Thu Oct 27 09:08:47 2005 -0700
+++ b/usr/src/uts/common/os/fork.c Thu Oct 27 13:18:49 2005 -0700
@@ -334,6 +334,7 @@
/* for each entry in the parent's lwp directory... */
for (i = 0, ldp = p->p_lwpdir; i < p->p_lwpdir_sz; i++, ldp++) {
klwp_t *clwp;
+ kthread_t *ct;
if ((lep = ldp->ld_entry) == NULL)
continue;
@@ -342,17 +343,22 @@
clwp = forklwp(ttolwp(t), cp, t->t_tid);
if (clwp == NULL)
goto forklwperr;
+ ct = lwptot(clwp);
/*
* Inherit lwp_wait()able and daemon flags.
*/
- lwptot(clwp)->t_proc_flag |=
+ ct->t_proc_flag |=
(t->t_proc_flag & (TP_TWAIT|TP_DAEMON));
/*
* Keep track of the clone of curthread to
* post return values through lwp_setrval().
+ * Mark other threads for special treatment
+ * by lwp_rtt() / post_syscall().
*/
if (t == curthread)
clone = clwp;
+ else
+ ct->t_flag |= T_FORKALL;
} else {
/*
* Replicate zombie lwps in the child.
--- a/usr/src/uts/common/sys/thread.h Thu Oct 27 09:08:47 2005 -0700
+++ b/usr/src/uts/common/sys/thread.h Thu Oct 27 13:18:49 2005 -0700
@@ -350,6 +350,7 @@
#define T_WAKEABLE 0x0002 /* thread is blocked, signals enabled */
#define T_TOMASK 0x0004 /* use lwp_sigoldmask on return from signal */
#define T_TALLOCSTK 0x0008 /* thread structure allocated from stk */
+#define T_FORKALL 0x0010 /* thread was cloned by forkall() */
#define T_WOULDBLOCK 0x0020 /* for lockfs */
#define T_DONTBLOCK 0x0040 /* for lockfs */
#define T_DONTPEND 0x0080 /* for lockfs */
--- a/usr/src/uts/intel/ia32/os/syscall.c Thu Oct 27 09:08:47 2005 -0700
+++ b/usr/src/uts/intel/ia32/os/syscall.c Thu Oct 27 13:18:49 2005 -0700
@@ -19,8 +19,9 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -589,6 +590,7 @@
*/
lwp->lwp_eosys = NORMALRETURN;
clear_stale_fd();
+ t->t_flag &= ~T_FORKALL;
/*
* If a single-step trap occurred on a syscall (see trap())
--- a/usr/src/uts/sparc/os/syscall.c Thu Oct 27 09:08:47 2005 -0700
+++ b/usr/src/uts/sparc/os/syscall.c Thu Oct 27 13:18:49 2005 -0700
@@ -677,11 +677,14 @@
* The default action is to redo the trap instruction.
* We increment the pc and npc past it for NORMALRETURN.
* JUSTRETURN has set up a new pc and npc already.
- * RESTARTSYS automatically restarts by leaving pc and npc
- * alone.
+ * If we are a cloned thread of forkall(), don't
+ * adjust here because we have already inherited
+ * the adjusted values from our clone.
*/
- rp->r_pc = rp->r_npc;
- rp->r_npc += 4;
+ if (!(t->t_flag & T_FORKALL)) {
+ rp->r_pc = rp->r_npc;
+ rp->r_npc += 4;
+ }
}
/*
@@ -726,6 +729,7 @@
*/
lwp->lwp_eosys = NORMALRETURN;
clear_stale_fd();
+ t->t_flag &= ~T_FORKALL;
if (t->t_astflag | t->t_sig_check) {
/*
--- a/usr/src/uts/sparc/v9/ml/syscall_trap.s Thu Oct 27 09:08:47 2005 -0700
+++ b/usr/src/uts/sparc/v9/ml/syscall_trap.s Thu Oct 27 13:18:49 2005 -0700
@@ -578,7 +578,7 @@
ldn [THREAD_REG + T_STACK], %l7
call __dtrace_probe___proc_start
sub %l7, STACK_BIAS, %sp
- ba 0f
+ ba,a,pt %xcc, 0f
ENTRY_NP(lwp_rtt)
ldn [THREAD_REG + T_STACK], %l7
@@ -593,5 +593,6 @@
ldx [%l7 + O1_OFF], %o1
ba,a,pt %xcc, user_rtt
SET_SIZE(lwp_rtt)
+ SET_SIZE(lwp_rtt_initial)
#endif /* lint */