xref: /illumos-gate/usr/src/uts/common/sys/klwp.h (revision 60405de4d8688d96dd05157c28db3ade5c9bc234)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_SYS_KLWP_H
27 #define	_SYS_KLWP_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #include <sys/types.h>
32 #include <sys/condvar.h>
33 #include <sys/thread.h>
34 #include <sys/signal.h>
35 #include <sys/siginfo.h>
36 #include <sys/pcb.h>
37 #include <sys/time.h>
38 #include <sys/msacct.h>
39 #include <sys/ucontext.h>
40 #include <sys/lwp.h>
41 #include <sys/contract.h>
42 
43 #if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
44 #include <sys/machparam.h>
45 #endif
46 
47 #ifdef	__cplusplus
48 extern "C" {
49 #endif
50 
51 /*
52  * The light-weight process object and the methods by which it
53  * is accessed.
54  */
55 
56 #define	MAXSYSARGS	8	/* Maximum # of arguments passed to a syscall */
57 
58 /* lwp_eosys values */
59 #define	NORMALRETURN	0	/* normal return; adjusts PC, registers */
60 #define	JUSTRETURN	1	/* just return, leave registers alone */
61 
62 /*
63  * Resource usage, per-lwp plus per-process (sum over defunct lwps).
64  */
65 struct lrusage {
66 	u_longlong_t	minflt;		/* minor page faults */
67 	u_longlong_t	majflt;		/* major page faults */
68 	u_longlong_t	nswap;		/* swaps */
69 	u_longlong_t	inblock;	/* input blocks */
70 	u_longlong_t	oublock;	/* output blocks */
71 	u_longlong_t	msgsnd;		/* messages sent */
72 	u_longlong_t	msgrcv;		/* messages received */
73 	u_longlong_t	nsignals;	/* signals received */
74 	u_longlong_t	nvcsw;		/* voluntary context switches */
75 	u_longlong_t	nivcsw;		/* involuntary context switches */
76 	u_longlong_t	sysc;		/* system calls */
77 	u_longlong_t	ioch;		/* chars read and written */
78 };
79 
80 typedef struct _klwp	*klwp_id_t;
81 
82 typedef struct _klwp {
83 	/*
84 	 * user-mode context
85 	 */
86 	struct pcb	lwp_pcb;		/* user regs save pcb */
87 	uintptr_t	lwp_oldcontext;		/* previous user context */
88 
89 	/*
90 	 * system-call interface
91 	 */
92 	long	*lwp_ap;	/* pointer to arglist */
93 	int	lwp_errno;	/* error for current syscall (private) */
94 	/*
95 	 * support for I/O
96 	 */
97 	char	lwp_error;	/* return error code */
98 	char	lwp_eosys;	/* special action on end of syscall */
99 	char	lwp_argsaved;	/* are all args in lwp_arg */
100 	char	lwp_watchtrap;	/* lwp undergoing watchpoint single-step */
101 	long	lwp_arg[MAXSYSARGS];	/* args to current syscall */
102 	void	*lwp_regs;	/* pointer to saved regs on stack */
103 	void	*lwp_fpu;	/* pointer to fpu regs */
104 	label_t	lwp_qsav;	/* longjmp label for quits and interrupts */
105 
106 	/*
107 	 * signal handling and debugger (/proc) interface
108 	 */
109 	uchar_t	lwp_cursig;		/* current signal */
110 	uchar_t	lwp_curflt;		/* current fault */
111 	uchar_t	lwp_sysabort;		/* if set, abort syscall */
112 	uchar_t	lwp_asleep;		/* lwp asleep in syscall */
113 	uchar_t lwp_extsig;		/* cursig sent from another contract */
114 	stack_t lwp_sigaltstack;	/* alternate signal stack */
115 	struct sigqueue *lwp_curinfo;	/* siginfo for current signal */
116 	k_siginfo_t	lwp_siginfo;	/* siginfo for stop-on-fault */
117 	k_sigset_t	lwp_sigoldmask;	/* for sigsuspend */
118 	struct lwp_watch {		/* used in watchpoint single-stepping */
119 		caddr_t	wpaddr;
120 		size_t	wpsize;
121 		int	wpcode;
122 		int	wpmapped;
123 		greg_t	wppc;
124 	} lwp_watch[4];		/* one for each of exec/write/read/read */
125 
126 	uint32_t lwp_oweupc;		/* profil(2) ticks owed to this lwp */
127 
128 	/*
129 	 * Microstate accounting.  Timestamps are made at the start and the
130 	 * end of each microstate (see <sys/msacct.h> for state definitions)
131 	 * and the corresponding accounting info is updated.  The current
132 	 * microstate is kept in the thread struct, since there are cases
133 	 * when one thread must update another thread's state (a no-no
134 	 * for an lwp since it may be swapped/paged out).  The rest of the
135 	 * microstate stuff is kept here to avoid wasting space on things
136 	 * like kernel threads that don't have an associated lwp.
137 	 */
138 	struct mstate {
139 		int ms_prev;			/* previous running mstate */
140 		hrtime_t ms_start;		/* lwp creation time */
141 		hrtime_t ms_term;		/* lwp termination time */
142 		hrtime_t ms_state_start;	/* start time of this mstate */
143 		hrtime_t ms_acct[NMSTATES];	/* per mstate accounting */
144 	} lwp_mstate;
145 
146 	/*
147 	 * Per-lwp resource usage.
148 	 */
149 	struct lrusage lwp_ru;
150 
151 	/*
152 	 * Things to keep for real-time (SIGPROF) profiling.
153 	 */
154 	int	lwp_lastfault;
155 	caddr_t	lwp_lastfaddr;
156 
157 	/*
158 	 * timers. Protected by lwp->procp->p_lock
159 	 */
160 	struct itimerval lwp_timer[3];
161 
162 	/*
163 	 * There are a number of places where you do not wish an lwp to
164 	 * be stopped due to some interaction with other lwps in the process.
165 	 * In these cases the lwp_nostop value is incremented. At places where
166 	 * the lwp would normally be stopped the stop is allowed if lwp_nostop
167 	 * is zero. There are a very few cases where even if lwp_nostop is set
168 	 * we need to allow the lwp to stop. In those cases the lwp is
169 	 * stopped if lwp_nostop_r is not set regardless of the state of
170 	 * lwp_nostop. These conditions are:
171 	 *
172 	 * 1. In issig_forreal() when another lwp is undergoing fork1()
173 	 * or watchpoint activity (p_flag contains either SHOLDFORK1 or
174 	 * SHOLDWATCH or t_proc_flag contains TP_HOLDLWP)
175 	 *
176 	 * 2. In stop() when the why argument is not PR_SUSPENDED or the what
177 	 * argument is not SUSPEND_NORMAL.
178 	 *
179 	 * 3. In cv_wait_stop() when another lwp is undergoing fork1() or
180 	 * watchpoint activity (p_flag contains either SHOLDFORK1 or
181 	 * SHOLDWATCH or t_proc_flag contains TP_HOLDLWP)
182 	 *
183 	 * lwp_nostop_r is set in prstop(). ie we honour the presence of
184 	 * SHOLDFORK1 or SHOLDWATCH or TP_HOLDLWP in the case of
185 	 * stop(PR_SUSPENDED, SUSPEND_NORMAL)
186 	 */
187 	char	lwp_unused;
188 	char	lwp_state;	/* Running in User/Kernel mode (no lock req) */
189 	ushort_t lwp_nostop;	/* Don't stop this lwp except SUSPEND_NORMAL */
190 	ushort_t lwp_nostop_r;	/* Don't stop this lwp (avoid recursion) */
191 
192 	/*
193 	 * Last failed privilege.
194 	 */
195 	short	lwp_badpriv;
196 
197 	/*
198 	 * linkage
199 	 */
200 	struct _kthread	*lwp_thread;
201 	struct proc	*lwp_procp;
202 
203 	size_t lwp_childstksz;	/* kernel stksize for this lwp's descendants */
204 
205 	uintptr_t	lwp_ustack;		/* current stack bounds */
206 	size_t		lwp_old_stk_ctl;	/* old stack limit */
207 
208 	/*
209 	 * Contracts
210 	 */
211 	struct ct_template *lwp_ct_active[CTT_MAXTYPE]; /* active templates */
212 	struct contract	*lwp_ct_latest[CTT_MAXTYPE]; /* last created contract */
213 
214 	void	*lwp_brand;		/* per-lwp brand data */
215 } klwp_t;
216 
217 /* lwp states */
218 #define	LWP_USER	0x01		/* Running in user mode */
219 #define	LWP_SYS		0x02		/* Running in kernel mode */
220 
221 #if	defined(_KERNEL)
222 extern	int	lwp_default_stksize;
223 extern	int	lwp_reapcnt;
224 
225 extern	struct _kthread *lwp_deathrow;
226 extern	kmutex_t	reaplock;
227 extern	struct kmem_cache *lwp_cache;
228 extern	void		*segkp_lwp;
229 extern	klwp_t		lwp0;
230 
231 /* where newly-created lwps normally start */
232 extern	void	lwp_rtt(void);
233 
234 #endif	/* _KERNEL */
235 
236 #ifdef	__cplusplus
237 }
238 #endif
239 
240 #endif	/* _SYS_KLWP_H */
241