xref: /titanic_44/usr/src/uts/common/sys/klwp.h (revision 9acbbeaf2a1ffe5c14b244867d427714fab43c5c)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*9acbbeafSnn35248  * Common Development and Distribution License (the "License").
6*9acbbeafSnn35248  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*9acbbeafSnn35248  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_KLWP_H
277c478bd9Sstevel@tonic-gate #define	_SYS_KLWP_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/types.h>
327c478bd9Sstevel@tonic-gate #include <sys/condvar.h>
337c478bd9Sstevel@tonic-gate #include <sys/thread.h>
347c478bd9Sstevel@tonic-gate #include <sys/signal.h>
357c478bd9Sstevel@tonic-gate #include <sys/siginfo.h>
367c478bd9Sstevel@tonic-gate #include <sys/pcb.h>
377c478bd9Sstevel@tonic-gate #include <sys/time.h>
387c478bd9Sstevel@tonic-gate #include <sys/msacct.h>
397c478bd9Sstevel@tonic-gate #include <sys/ucontext.h>
407c478bd9Sstevel@tonic-gate #include <sys/lwp.h>
417c478bd9Sstevel@tonic-gate #include <sys/contract.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
447c478bd9Sstevel@tonic-gate #include <sys/machparam.h>
457c478bd9Sstevel@tonic-gate #endif
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
487c478bd9Sstevel@tonic-gate extern "C" {
497c478bd9Sstevel@tonic-gate #endif
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate  * The light-weight process object and the methods by which it
537c478bd9Sstevel@tonic-gate  * is accessed.
547c478bd9Sstevel@tonic-gate  */
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #define	MAXSYSARGS	8	/* Maximum # of arguments passed to a syscall */
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /* lwp_eosys values */
597c478bd9Sstevel@tonic-gate #define	NORMALRETURN	0	/* normal return; adjusts PC, registers */
607c478bd9Sstevel@tonic-gate #define	JUSTRETURN	1	/* just return, leave registers alone */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate /*
637c478bd9Sstevel@tonic-gate  * Resource usage, per-lwp plus per-process (sum over defunct lwps).
647c478bd9Sstevel@tonic-gate  */
657c478bd9Sstevel@tonic-gate struct lrusage {
667c478bd9Sstevel@tonic-gate 	u_longlong_t	minflt;		/* minor page faults */
677c478bd9Sstevel@tonic-gate 	u_longlong_t	majflt;		/* major page faults */
687c478bd9Sstevel@tonic-gate 	u_longlong_t	nswap;		/* swaps */
697c478bd9Sstevel@tonic-gate 	u_longlong_t	inblock;	/* input blocks */
707c478bd9Sstevel@tonic-gate 	u_longlong_t	oublock;	/* output blocks */
717c478bd9Sstevel@tonic-gate 	u_longlong_t	msgsnd;		/* messages sent */
727c478bd9Sstevel@tonic-gate 	u_longlong_t	msgrcv;		/* messages received */
737c478bd9Sstevel@tonic-gate 	u_longlong_t	nsignals;	/* signals received */
747c478bd9Sstevel@tonic-gate 	u_longlong_t	nvcsw;		/* voluntary context switches */
757c478bd9Sstevel@tonic-gate 	u_longlong_t	nivcsw;		/* involuntary context switches */
767c478bd9Sstevel@tonic-gate 	u_longlong_t	sysc;		/* system calls */
777c478bd9Sstevel@tonic-gate 	u_longlong_t	ioch;		/* chars read and written */
787c478bd9Sstevel@tonic-gate };
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate typedef struct _klwp	*klwp_id_t;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate typedef struct _klwp {
837c478bd9Sstevel@tonic-gate 	/*
847c478bd9Sstevel@tonic-gate 	 * user-mode context
857c478bd9Sstevel@tonic-gate 	 */
867c478bd9Sstevel@tonic-gate 	struct pcb	lwp_pcb;		/* user regs save pcb */
877c478bd9Sstevel@tonic-gate 	uintptr_t	lwp_oldcontext;		/* previous user context */
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	/*
907c478bd9Sstevel@tonic-gate 	 * system-call interface
917c478bd9Sstevel@tonic-gate 	 */
927c478bd9Sstevel@tonic-gate 	long	*lwp_ap;	/* pointer to arglist */
937c478bd9Sstevel@tonic-gate 	int	lwp_errno;	/* error for current syscall (private) */
947c478bd9Sstevel@tonic-gate 	/*
957c478bd9Sstevel@tonic-gate 	 * support for I/O
967c478bd9Sstevel@tonic-gate 	 */
977c478bd9Sstevel@tonic-gate 	char	lwp_error;	/* return error code */
987c478bd9Sstevel@tonic-gate 	char	lwp_eosys;	/* special action on end of syscall */
997c478bd9Sstevel@tonic-gate 	char	lwp_argsaved;	/* are all args in lwp_arg */
1007c478bd9Sstevel@tonic-gate 	char	lwp_watchtrap;	/* lwp undergoing watchpoint single-step */
1017c478bd9Sstevel@tonic-gate 	long	lwp_arg[MAXSYSARGS];	/* args to current syscall */
1027c478bd9Sstevel@tonic-gate 	void	*lwp_regs;	/* pointer to saved regs on stack */
1037c478bd9Sstevel@tonic-gate 	void	*lwp_fpu;	/* pointer to fpu regs */
1047c478bd9Sstevel@tonic-gate 	label_t	lwp_qsav;	/* longjmp label for quits and interrupts */
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate 	/*
1077c478bd9Sstevel@tonic-gate 	 * signal handling and debugger (/proc) interface
1087c478bd9Sstevel@tonic-gate 	 */
1097c478bd9Sstevel@tonic-gate 	uchar_t	lwp_cursig;		/* current signal */
1107c478bd9Sstevel@tonic-gate 	uchar_t	lwp_curflt;		/* current fault */
1117c478bd9Sstevel@tonic-gate 	uchar_t	lwp_sysabort;		/* if set, abort syscall */
1127c478bd9Sstevel@tonic-gate 	uchar_t	lwp_asleep;		/* lwp asleep in syscall */
1137c478bd9Sstevel@tonic-gate 	uchar_t lwp_extsig;		/* cursig sent from another contract */
1147c478bd9Sstevel@tonic-gate 	stack_t lwp_sigaltstack;	/* alternate signal stack */
1157c478bd9Sstevel@tonic-gate 	struct sigqueue *lwp_curinfo;	/* siginfo for current signal */
1167c478bd9Sstevel@tonic-gate 	k_siginfo_t	lwp_siginfo;	/* siginfo for stop-on-fault */
1177c478bd9Sstevel@tonic-gate 	k_sigset_t	lwp_sigoldmask;	/* for sigsuspend */
1187c478bd9Sstevel@tonic-gate 	struct lwp_watch {		/* used in watchpoint single-stepping */
1197c478bd9Sstevel@tonic-gate 		caddr_t	wpaddr;
1207c478bd9Sstevel@tonic-gate 		size_t	wpsize;
1217c478bd9Sstevel@tonic-gate 		int	wpcode;
1227c478bd9Sstevel@tonic-gate 		int	wpmapped;
1237c478bd9Sstevel@tonic-gate 		greg_t	wppc;
1247c478bd9Sstevel@tonic-gate 	} lwp_watch[4];		/* one for each of exec/write/read/read */
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	uint32_t lwp_oweupc;		/* profil(2) ticks owed to this lwp */
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	/*
1297c478bd9Sstevel@tonic-gate 	 * Microstate accounting.  Timestamps are made at the start and the
1307c478bd9Sstevel@tonic-gate 	 * end of each microstate (see <sys/msacct.h> for state definitions)
1317c478bd9Sstevel@tonic-gate 	 * and the corresponding accounting info is updated.  The current
1327c478bd9Sstevel@tonic-gate 	 * microstate is kept in the thread struct, since there are cases
1337c478bd9Sstevel@tonic-gate 	 * when one thread must update another thread's state (a no-no
1347c478bd9Sstevel@tonic-gate 	 * for an lwp since it may be swapped/paged out).  The rest of the
1357c478bd9Sstevel@tonic-gate 	 * microstate stuff is kept here to avoid wasting space on things
1367c478bd9Sstevel@tonic-gate 	 * like kernel threads that don't have an associated lwp.
1377c478bd9Sstevel@tonic-gate 	 */
1387c478bd9Sstevel@tonic-gate 	struct mstate {
1397c478bd9Sstevel@tonic-gate 		int ms_prev;			/* previous running mstate */
1407c478bd9Sstevel@tonic-gate 		hrtime_t ms_start;		/* lwp creation time */
1417c478bd9Sstevel@tonic-gate 		hrtime_t ms_term;		/* lwp termination time */
1427c478bd9Sstevel@tonic-gate 		hrtime_t ms_state_start;	/* start time of this mstate */
1437c478bd9Sstevel@tonic-gate 		hrtime_t ms_acct[NMSTATES];	/* per mstate accounting */
1447c478bd9Sstevel@tonic-gate 	} lwp_mstate;
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	/*
1477c478bd9Sstevel@tonic-gate 	 * Per-lwp resource usage.
1487c478bd9Sstevel@tonic-gate 	 */
1497c478bd9Sstevel@tonic-gate 	struct lrusage lwp_ru;
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * Things to keep for real-time (SIGPROF) profiling.
1537c478bd9Sstevel@tonic-gate 	 */
1547c478bd9Sstevel@tonic-gate 	int	lwp_lastfault;
1557c478bd9Sstevel@tonic-gate 	caddr_t	lwp_lastfaddr;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	/*
1587c478bd9Sstevel@tonic-gate 	 * timers. Protected by lwp->procp->p_lock
1597c478bd9Sstevel@tonic-gate 	 */
1607c478bd9Sstevel@tonic-gate 	struct itimerval lwp_timer[3];
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 	/*
16316ade92dScwb 	 * There are a number of places where you do not wish an lwp to
16416ade92dScwb 	 * be stopped due to some interaction with other lwps in the process.
16516ade92dScwb 	 * In these cases the lwp_nostop value is incremented. At places where
16616ade92dScwb 	 * the lwp would normally be stopped the stop is allowed if lwp_nostop
16716ade92dScwb 	 * is zero. There are a very few cases where even if lwp_nostop is set
16816ade92dScwb 	 * we need to allow the lwp to stop. In those cases the lwp is
16916ade92dScwb 	 * stopped if lwp_nostop_r is not set regardless of the state of
17016ade92dScwb 	 * lwp_nostop. These conditions are:
17116ade92dScwb 	 *
17216ade92dScwb 	 * 1. In issig_forreal() when another lwp is undergoing fork1()
17316ade92dScwb 	 * or watchpoint activity (p_flag contains either SHOLDFORK1 or
17416ade92dScwb 	 * SHOLDWATCH or t_proc_flag contains TP_HOLDLWP)
17516ade92dScwb 	 *
17616ade92dScwb 	 * 2. In stop() when the why argument is not PR_SUSPENDED or the what
17716ade92dScwb 	 * argument is not SUSPEND_NORMAL.
17816ade92dScwb 	 *
17916ade92dScwb 	 * 3. In cv_wait_stop() when another lwp is undergoing fork1() or
18016ade92dScwb 	 * watchpoint activity (p_flag contains either SHOLDFORK1 or
18116ade92dScwb 	 * SHOLDWATCH or t_proc_flag contains TP_HOLDLWP)
18216ade92dScwb 	 *
18316ade92dScwb 	 * lwp_nostop_r is set in prstop(). ie we honour the presence of
18416ade92dScwb 	 * SHOLDFORK1 or SHOLDWATCH or TP_HOLDLWP in the case of
18516ade92dScwb 	 * stop(PR_SUSPENDED, SUSPEND_NORMAL)
1867c478bd9Sstevel@tonic-gate 	 */
1877c478bd9Sstevel@tonic-gate 	char	lwp_unused;
1887c478bd9Sstevel@tonic-gate 	char	lwp_state;	/* Running in User/Kernel mode (no lock req) */
18916ade92dScwb 	ushort_t lwp_nostop;	/* Don't stop this lwp except SUSPEND_NORMAL */
19016ade92dScwb 	ushort_t lwp_nostop_r;	/* Don't stop this lwp (avoid recursion) */
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate 	/*
1937c478bd9Sstevel@tonic-gate 	 * Last failed privilege.
1947c478bd9Sstevel@tonic-gate 	 */
1957c478bd9Sstevel@tonic-gate 	short	lwp_badpriv;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 	/*
1987c478bd9Sstevel@tonic-gate 	 * linkage
1997c478bd9Sstevel@tonic-gate 	 */
2007c478bd9Sstevel@tonic-gate 	struct _kthread	*lwp_thread;
2017c478bd9Sstevel@tonic-gate 	struct proc	*lwp_procp;
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	size_t lwp_childstksz;	/* kernel stksize for this lwp's descendants */
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 	uintptr_t	lwp_ustack;		/* current stack bounds */
2067c478bd9Sstevel@tonic-gate 	size_t		lwp_old_stk_ctl;	/* old stack limit */
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	/*
2097c478bd9Sstevel@tonic-gate 	 * Contracts
2107c478bd9Sstevel@tonic-gate 	 */
2117c478bd9Sstevel@tonic-gate 	struct ct_template *lwp_ct_active[CTT_MAXTYPE]; /* active templates */
2127c478bd9Sstevel@tonic-gate 	struct contract	*lwp_ct_latest[CTT_MAXTYPE]; /* last created contract */
213*9acbbeafSnn35248 
214*9acbbeafSnn35248 	void	*lwp_brand;		/* per-lwp brand data */
2157c478bd9Sstevel@tonic-gate } klwp_t;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate /* lwp states */
2187c478bd9Sstevel@tonic-gate #define	LWP_USER	0x01		/* Running in user mode */
2197c478bd9Sstevel@tonic-gate #define	LWP_SYS		0x02		/* Running in kernel mode */
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate #if	defined(_KERNEL)
2227c478bd9Sstevel@tonic-gate extern	int	lwp_default_stksize;
2237c478bd9Sstevel@tonic-gate extern	int	lwp_reapcnt;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate extern	struct _kthread *lwp_deathrow;
2267c478bd9Sstevel@tonic-gate extern	kmutex_t	reaplock;
2277c478bd9Sstevel@tonic-gate extern	struct kmem_cache *lwp_cache;
2287c478bd9Sstevel@tonic-gate extern	void		*segkp_lwp;
2297c478bd9Sstevel@tonic-gate extern	klwp_t		lwp0;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /* where newly-created lwps normally start */
2327c478bd9Sstevel@tonic-gate extern	void	lwp_rtt(void);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate #endif
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate #endif	/* _SYS_KLWP_H */
241