xref: /illumos-gate/usr/src/uts/common/sys/user.h (revision 3d4e20a23e1894c03df6b83e39a88625f74ee0e4)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved	*/
28 /*
29  * Copyright (c) 2018, Joyent, Inc.
30  * Copyright 2026 Oxide Computer Company
31  */
32 
33 
34 #ifndef _SYS_USER_H
35 #define	_SYS_USER_H
36 
37 #include <sys/types.h>
38 #include <sys/signal.h>
39 
40 #ifdef	__cplusplus
41 extern "C" {
42 #endif
43 
44 /*
45  * struct exdata is visible in and out of the kernel. This is because it
46  * is referenced in <sys/core.h> which doesn't have this kind of magic.
47  */
48 struct exdata {
49 	struct vnode	*vp;
50 	size_t	ux_tsize;	/* text size */
51 	size_t	ux_dsize;	/* data size */
52 	size_t	ux_bsize;	/* bss size */
53 	size_t	ux_lsize;	/* lib size */
54 	long	ux_nshlibs;	/* number of shared libs needed */
55 	short	ux_mach;	/* machine type */
56 	short	ux_mag;		/* magic number MUST be here */
57 	off_t	ux_toffset;	/* file offset to raw text */
58 	off_t	ux_doffset;	/* file offset to raw data */
59 	off_t	ux_loffset;	/* file offset to lib sctn */
60 	caddr_t	ux_txtorg;	/* start addr of text in mem */
61 	caddr_t	ux_datorg;	/* start addr of data in mem */
62 	caddr_t	ux_entloc;	/* entry location */
63 };
64 
65 #ifdef	__cplusplus
66 }
67 #endif
68 
69 #if defined(_KERNEL) || defined(_KMEMUSER)
70 
71 #include <sys/param.h>
72 #include <sys/pcb.h>
73 #include <sys/siginfo.h>
74 #include <sys/resource.h>
75 #include <sys/time.h>
76 #include <sys/auxv.h>
77 #include <sys/errno.h>
78 #include <sys/t_lock.h>
79 #include <sys/refstr.h>
80 
81 #ifdef	__cplusplus
82 extern "C" {
83 #endif
84 
85 /*
86  * File Descriptor assignment generation.
87  *
88  * Certain file descriptor consumers (namely epoll) need to be able to detect
89  * when the resource underlying an fd change due to (re)assignment.  Checks
90  * comparing old and new file_t pointers work OK, but could easily be fooled by
91  * an entry freed-to and reused-from the cache.  To better detect such
92  * assingments, a generation number is kept in the uf_entry.  Whenever a
93  * non-NULL file_t is assigned to the entry, the generation is incremented,
94  * indicating the change.  There is a minute possibility that a rollover of the
95  * value could cause assigments to evade detection by consumers, but it is
96  * considered acceptably small.
97  */
98 typedef uint_t uf_entry_gen_t;
99 
100 /*
101  * Entry in the per-process list of open files.
102  * Note: only certain fields are copied in flist_grow() and flist_fork().
103  * This is indicated in brackets in the structure member comments.
104  * flist_spawn() copies uf_file, uf_flag and uf_gen, and rebuilds uf_busy
105  * and uf_alloc through fd_reserve().
106  */
107 typedef struct uf_entry {
108 	kmutex_t	uf_lock;	/* per-fd lock [never copied] */
109 	struct file	*uf_file;	/* file pointer [grow, fork] */
110 	struct fpollinfo *uf_fpollinfo;	/* poll state [grow] */
111 	int		uf_refcnt;	/* LWPs accessing this file [grow] */
112 	int		uf_alloc;	/* right subtree allocs [grow, fork] */
113 	short		uf_flag;	/* fcntl F_GETFD flags [grow, fork] */
114 	short		uf_busy;	/* file is allocated [grow, fork] */
115 	kcondvar_t	uf_wanted_cv;	/* waiting for setf() [never copied] */
116 	kcondvar_t	uf_closing_cv;	/* waiting for close() [never copied] */
117 	struct portfd	*uf_portfd;	/* associated with port [grow] */
118 	uf_entry_gen_t	uf_gen;		/* assigned fd generation [grow,fork] */
119 	/* Avoid false sharing - pad to coherency granularity (64 bytes) */
120 	char		uf_pad[64 - sizeof (kmutex_t) - 2 * sizeof (void*) -
121 		2 * sizeof (int) - 2 * sizeof (short) -
122 		2 * sizeof (kcondvar_t) - sizeof (struct portfd *) -
123 		sizeof (uf_entry_gen_t)];
124 } uf_entry_t;
125 
126 /*
127  * Retired file lists -- see flist_grow() for details.
128  */
129 typedef struct uf_rlist {
130 	struct uf_rlist	*ur_next;
131 	uf_entry_t	*ur_list;
132 	int		ur_nfiles;
133 } uf_rlist_t;
134 
135 /*
136  * Per-process file information.
137  */
138 typedef struct uf_info {
139 	kmutex_t	fi_lock;	/* see below */
140 	int		fi_badfd;	/* bad file descriptor # */
141 	int		fi_action;	/* action to take on bad fd use */
142 	int		fi_nfiles;	/* number of entries in fi_list[] */
143 	uf_entry_t *volatile fi_list;	/* current file list */
144 	uf_rlist_t	*fi_rlist;	/* retired file lists */
145 } uf_info_t;
146 
147 /*
148  * File list locking.
149  *
150  * Each process has a list of open files, fi_list, indexed by fd.
151  * fi_list is an array of uf_entry_t structures, each with its own lock.
152  * One might think that the correct way to lock a file descriptor would be:
153  *
154  *	ufp = fip->fi_list[fd];
155  *	mutex_enter(&ufp->uf_lock);
156  *
157  * However, that construct is only safe if fi_lock is already held.  If not,
158  * fi_list can change in the window between loading ufp and entering uf_lock.
159  * The UF_ENTER() macro deals with this possibility.  UF_ENTER(ufp, fip, fd)
160  * locks fd and sets ufp to fd's uf_entry.  The locking rules are as follows:
161  *
162  * (1) fi_lock protects fi_list and fi_nfiles.  It also protects the
163  *     uf_alloc and uf_busy fields of every fd's ufp; see fd_find() for
164  *     details on file descriptor allocation.
165  *
166  * (2) UF_ENTER(ufp, fip, fd) locks descriptor fd and sets ufp to point
167  *     to the uf_entry_t for fd.  UF_ENTER() protects all fields in ufp
168  *     except uf_alloc and uf_busy.  UF_ENTER(ufp, fip, fd) also prevents
169  *     ufp->uf_alloc, ufp->uf_busy, fip->fi_list and fip->fi_nfiles from
170  *     changing.
171  *
172  * (3) The lock ordering is (1), (2).
173  *
174  * (4) Note that fip->fi_list and fip->fi_nfiles cannot change while *any*
175  *     file list lock is held.  Thus flist_grow() must acquire all such
176  *     locks -- fi_lock and every fd's uf_lock -- to install a new file list.
177  */
178 #define	UF_ENTER(ufp, fip, fd)					\
179 	for (;;) {						\
180 		uf_entry_t *_flist = (fip)->fi_list;		\
181 		ufp = &_flist[fd];				\
182 		ASSERT((fd) < (fip)->fi_nfiles);		\
183 		mutex_enter(&ufp->uf_lock);			\
184 		if (_flist == (fip)->fi_list)			\
185 			break;					\
186 		mutex_exit(&ufp->uf_lock);			\
187 	}
188 
189 #define	UF_EXIT(ufp)	mutex_exit(&ufp->uf_lock)
190 
191 #define	PSARGSZ		80	/* Space for exec arguments (used by ps(1)) */
192 #define	MAXCOMLEN	16	/* <= MAXNAMLEN, >= sizeof (ac_comm) */
193 
194 typedef struct {		/* kernel syscall set type */
195 	uint_t	word[9];	/* space for syscall numbers [1..288] */
196 } k_sysset_t;
197 
198 /*
199  * __KERN_NAUXV_IMPL is defined as a convenience sizing mechanism
200  * for the portions of the kernel that care about aux vectors.
201  *
202  * Applications that need to know how many aux vectors the kernel
203  * supplies should use the proc(5) interface to read /proc/PID/auxv.
204  *
205  * This value should not be changed in a patch.
206  */
207 #if defined(__sparc)
208 #define	__KERN_NAUXV_IMPL 20
209 #elif defined(__i386) || defined(__amd64)
210 #define	__KERN_NAUXV_IMPL 26
211 #endif
212 
213 struct execsw;
214 
215 /*
216  * The user structure; one allocated per process.  Contains all the
217  * per-process data that doesn't need to be referenced while the
218  * process is swapped.
219  */
220 typedef	struct	user {
221 	/*
222 	 * These fields are initialized at process creation time and never
223 	 * modified.  They can be accessed without acquiring locks.
224 	 */
225 	struct execsw *u_execsw;	/* pointer to exec switch entry */
226 	auxv_t  u_auxv[__KERN_NAUXV_IMPL]; /* aux vector from exec */
227 	timestruc_t u_start;		/* hrestime at process start */
228 	clock_t	u_ticks;		/* lbolt at process start */
229 	char	u_comm[MAXCOMLEN + 1];	/* executable file name from exec */
230 	char	u_psargs[PSARGSZ];	/* arguments from exec */
231 	int	u_argc;			/* value of argc passed to main() */
232 	uintptr_t u_argv;		/* value of argv passed to main() */
233 	uintptr_t u_envp;		/* value of envp passed to main() */
234 	uintptr_t u_commpagep;		/* address of mapped comm page */
235 
236 	/*
237 	 * These fields are protected by p_lock:
238 	 */
239 	struct vnode *u_cdir;		/* current directory */
240 	struct vnode *u_rdir;		/* root directory */
241 	uint64_t u_mem;			/* accumulated memory usage */
242 	size_t	u_mem_max;		/* peak RSS (K) */
243 	mode_t	u_cmask;		/* mask for file creation */
244 	char	u_acflag;		/* accounting flag */
245 	char	u_systrap;		/* /proc: any syscall mask bits set? */
246 	refstr_t *u_cwd;		/* cached string for cwd */
247 
248 	k_sysset_t u_entrymask;		/* /proc syscall stop-on-entry mask */
249 	k_sysset_t u_exitmask;		/* /proc syscall stop-on-exit mask */
250 	k_sigset_t u_signodefer;	/* signals defered when caught */
251 	k_sigset_t u_sigonstack;	/* signals taken on alternate stack */
252 	k_sigset_t u_sigresethand;	/* signals reset when caught */
253 	k_sigset_t u_sigrestart;	/* signals that restart system calls */
254 	k_sigset_t u_sigmask[MAXSIG];	/* signals held while in catcher */
255 	void	(*u_signal[MAXSIG])();	/* Disposition of signals */
256 
257 	/*
258 	 * Resource controls provide the backend for process resource limits,
259 	 * the interfaces for which are maintained for compatibility.  To
260 	 * preserve the behaviour associated with the RLIM_SAVED_CUR and
261 	 * RLIM_SAVED_MAX tokens, we retain the "saved" rlimits.
262 	 */
263 	struct rlimit64	u_saved_rlimit[RLIM_NSAVED];
264 
265 	uf_info_t	u_finfo;	/* open file information */
266 } user_t;
267 
268 #include <sys/proc.h>			/* cannot include before user defined */
269 
270 #ifdef	_KERNEL
271 #define	P_FINFO(p)	(&(p)->p_user.u_finfo)
272 #endif	/* _KERNEL */
273 
274 #ifdef	__cplusplus
275 }
276 #endif
277 
278 #else	/* defined(_KERNEL) || defined(_KMEMUSER) */
279 
280 /*
281  * Here, we define a fake version of struct user for programs
282  * (debuggers) that use ptrace() to read and modify the saved
283  * registers directly in the u-area.  ptrace() has been removed
284  * from the operating system and now exists as a library function
285  * in libc, built on the /proc process filesystem.  The ptrace()
286  * library function provides access only to the members of the
287  * fake struct user defined here.
288  *
289  * User-level programs that must know the real contents of struct
290  * user will have to define _KMEMUSER before including <sys/user.h>.
291  * Such programs also become machine specific. Carefully consider
292  * the consequences of your actions.
293  */
294 
295 #include <sys/regset.h>
296 
297 #ifdef	__cplusplus
298 extern "C" {
299 #endif
300 
301 #define	PSARGSZ		80	/* Space for exec arguments (used by ps(1)) */
302 
303 typedef	struct	user {
304 	gregset_t	u_reg;		/* user's saved registers */
305 	greg_t		*u_ar0;		/* address of user's saved R0 */
306 	char	u_psargs[PSARGSZ];	/* arguments from exec */
307 	void	(*u_signal[MAXSIG])();	/* Disposition of signals */
308 	int		u_code;		/* fault code on trap */
309 	caddr_t		u_addr;		/* fault PC on trap */
310 } user_t;
311 
312 #ifdef	__cplusplus
313 }
314 #endif
315 
316 #endif	/* defined(_KERNEL) || defined(_KMEMUSER) */
317 
318 #endif	/* _SYS_USER_H */
319