27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
5a5f6978craigm * Common Development and Distribution License (the "License").
6a5f6978craigm * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
22ae115bcmrj * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bdstevel@tonic-gate * Use is subject to license terms.
247c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
277c478bdstevel@tonic-gate/*	  All Rights Reserved	*/
28ebb8ac0Robert Mustacchi/*
29d015822Robert Mustacchi * Copyright (c) 2018, Joyent, Inc.
30ebb8ac0Robert Mustacchi */
337c478bdstevel@tonic-gate#ifndef _SYS_USER_H
347c478bdstevel@tonic-gate#define	_SYS_USER_H
367c478bdstevel@tonic-gate#include <sys/types.h>
377c478bdstevel@tonic-gate#include <sys/signal.h>
397c478bdstevel@tonic-gate#ifdef	__cplusplus
407c478bdstevel@tonic-gateextern "C" {
447c478bdstevel@tonic-gate * struct exdata is visible in and out of the kernel. This is because it
457c478bdstevel@tonic-gate * is referenced in <sys/core.h> which doesn't have this kind of magic.
467c478bdstevel@tonic-gate */
477c478bdstevel@tonic-gatestruct exdata {
487c478bdstevel@tonic-gate	struct vnode	*vp;
497c478bdstevel@tonic-gate	size_t	ux_tsize;	/* text size */
507c478bdstevel@tonic-gate	size_t	ux_dsize;	/* data size */
517c478bdstevel@tonic-gate	size_t	ux_bsize;	/* bss size */
527c478bdstevel@tonic-gate	size_t	ux_lsize;	/* lib size */
537c478bdstevel@tonic-gate	long	ux_nshlibs;	/* number of shared libs needed */
547c478bdstevel@tonic-gate	short	ux_mach;	/* machine type */
557c478bdstevel@tonic-gate	short	ux_mag;		/* magic number MUST be here */
567c478bdstevel@tonic-gate	off_t	ux_toffset;	/* file offset to raw text */
577c478bdstevel@tonic-gate	off_t	ux_doffset;	/* file offset to raw data */
587c478bdstevel@tonic-gate	off_t	ux_loffset;	/* file offset to lib sctn */
597c478bdstevel@tonic-gate	caddr_t	ux_txtorg;	/* start addr of text in mem */
607c478bdstevel@tonic-gate	caddr_t	ux_datorg;	/* start addr of data in mem */
617c478bdstevel@tonic-gate	caddr_t	ux_entloc;	/* entry location */
647c478bdstevel@tonic-gate#ifdef	__cplusplus
687c478bdstevel@tonic-gate#if defined(_KERNEL) || defined(_KMEMUSER)
707c478bdstevel@tonic-gate#include <sys/param.h>
717c478bdstevel@tonic-gate#include <sys/pcb.h>
727c478bdstevel@tonic-gate#include <sys/siginfo.h>
737c478bdstevel@tonic-gate#include <sys/resource.h>
747c478bdstevel@tonic-gate#include <sys/time.h>
757c478bdstevel@tonic-gate#include <sys/auxv.h>
767c478bdstevel@tonic-gate#include <sys/errno.h>
777c478bdstevel@tonic-gate#include <sys/t_lock.h>
787c478bdstevel@tonic-gate#include <sys/refstr.h>
807c478bdstevel@tonic-gate#ifdef	__cplusplus
817c478bdstevel@tonic-gateextern "C" {
85086d968Patrick Mooney * File Descriptor assignment generation.
86086d968Patrick Mooney *
87086d968Patrick Mooney * Certain file descriptor consumers (namely epoll) need to be able to detect
88086d968Patrick Mooney * when the resource underlying an fd change due to (re)assignment.  Checks
89086d968Patrick Mooney * comparing old and new file_t pointers work OK, but could easily be fooled by
90086d968Patrick Mooney * an entry freed-to and reused-from the cache.  To better detect such
91086d968Patrick Mooney * assingments, a generation number is kept in the uf_entry.  Whenever a
92086d968Patrick Mooney * non-NULL file_t is assigned to the entry, the generation is incremented,
93086d968Patrick Mooney * indicating the change.  There is a minute possibility that a rollover of the
94086d968Patrick Mooney * value could cause assigments to evade detection by consumers, but it is
95086d968Patrick Mooney * considered acceptably small.
96086d968Patrick Mooney */
97086d968Patrick Mooneytypedef uint_t uf_entry_gen_t;
98086d968Patrick Mooney
99086d968Patrick Mooney/*
1007c478bdstevel@tonic-gate * Entry in the per-process list of open files.
1017c478bdstevel@tonic-gate * Note: only certain fields are copied in flist_grow() and flist_fork().
1027c478bdstevel@tonic-gate * This is indicated in brackets in the structure member comments.
1037c478bdstevel@tonic-gate */
1047c478bdstevel@tonic-gatetypedef struct uf_entry {
1057c478bdstevel@tonic-gate	kmutex_t	uf_lock;	/* per-fd lock [never copied] */
1067c478bdstevel@tonic-gate	struct file	*uf_file;	/* file pointer [grow, fork] */
1077c478bdstevel@tonic-gate	struct fpollinfo *uf_fpollinfo;	/* poll state [grow] */
1087c478bdstevel@tonic-gate	int		uf_refcnt;	/* LWPs accessing this file [grow] */
1097c478bdstevel@tonic-gate	int		uf_alloc;	/* right subtree allocs [grow, fork] */
1107c478bdstevel@tonic-gate	short		uf_flag;	/* fcntl F_GETFD flags [grow, fork] */
1117c478bdstevel@tonic-gate	short		uf_busy;	/* file is allocated [grow, fork] */
1127c478bdstevel@tonic-gate	kcondvar_t	uf_wanted_cv;	/* waiting for setf() [never copied] */
1137c478bdstevel@tonic-gate	kcondvar_t	uf_closing_cv;	/* waiting for close() [never copied] */
1147c478bdstevel@tonic-gate	struct portfd 	*uf_portfd;	/* associated with port [grow] */
115086d968Patrick Mooney	uf_entry_gen_t	uf_gen;		/* assigned fd generation [grow,fork] */
1167c478bdstevel@tonic-gate	/* Avoid false sharing - pad to coherency granularity (64 bytes) */
1177c478bdstevel@tonic-gate	char		uf_pad[64 - sizeof (kmutex_t) - 2 * sizeof (void*) -
1187c478bdstevel@tonic-gate		2 * sizeof (int) - 2 * sizeof (short) -
119086d968Patrick Mooney		2 * sizeof (kcondvar_t) - sizeof (struct portfd *) -
120086d968Patrick Mooney		sizeof (uf_entry_gen_t)];
1217c478bdstevel@tonic-gate} uf_entry_t;
1247c478bdstevel@tonic-gate * Retired file lists -- see flist_grow() for details.
1257c478bdstevel@tonic-gate */
1267c478bdstevel@tonic-gatetypedef struct uf_rlist {
1277c478bdstevel@tonic-gate	struct uf_rlist	*ur_next;
1287c478bdstevel@tonic-gate	uf_entry_t	*ur_list;
1297c478bdstevel@tonic-gate	int		ur_nfiles;
1307c478bdstevel@tonic-gate} uf_rlist_t;
1337c478bdstevel@tonic-gate * Per-process file information.
1347c478bdstevel@tonic-gate */
1357c478bdstevel@tonic-gatetypedef struct uf_info {
1367c478bdstevel@tonic-gate	kmutex_t	fi_lock;	/* see below */
137a5f6978craigm	int		fi_badfd;	/* bad file descriptor # */
138a5f6978craigm	int		fi_action;	/* action to take on bad fd use */
1397c478bdstevel@tonic-gate	int		fi_nfiles;	/* number of entries in fi_list[] */
1407c478bdstevel@tonic-gate	uf_entry_t *volatile fi_list;	/* current file list */
1417c478bdstevel@tonic-gate	uf_rlist_t	*fi_rlist;	/* retired file lists */
1427c478bdstevel@tonic-gate} uf_info_t;
1457c478bdstevel@tonic-gate * File list locking.
1467c478bdstevel@tonic-gate *
1477c478bdstevel@tonic-gate * Each process has a list of open files, fi_list, indexed by fd.
1487c478bdstevel@tonic-gate * fi_list is an array of uf_entry_t structures, each with its own lock.
1497c478bdstevel@tonic-gate * One might think that the correct way to lock a file descriptor would be:
1507c478bdstevel@tonic-gate *
1517c478bdstevel@tonic-gate *	ufp = fip->fi_list[fd];
1527c478bdstevel@tonic-gate *	mutex_enter(&ufp->uf_lock);
1537c478bdstevel@tonic-gate *
1547c478bdstevel@tonic-gate * However, that construct is only safe if fi_lock is already held.  If not,
1557c478bdstevel@tonic-gate * fi_list can change in the window between loading ufp and entering uf_lock.
1567c478bdstevel@tonic-gate * The UF_ENTER() macro deals with this possibility.  UF_ENTER(ufp, fip, fd)
1577c478bdstevel@tonic-gate * locks fd and sets ufp to fd's uf_entry.  The locking rules are as follows:
1587c478bdstevel@tonic-gate *
1597c478bdstevel@tonic-gate * (1) fi_lock protects fi_list and fi_nfiles.  It also protects the
1607c478bdstevel@tonic-gate *     uf_alloc and uf_busy fields of every fd's ufp; see fd_find() for
1617c478bdstevel@tonic-gate *     details on file descriptor allocation.
1627c478bdstevel@tonic-gate *
1637c478bdstevel@tonic-gate * (2) UF_ENTER(ufp, fip, fd) locks descriptor fd and sets ufp to point
1647c478bdstevel@tonic-gate *     to the uf_entry_t for fd.  UF_ENTER() protects all fields in ufp
1657c478bdstevel@tonic-gate *     except uf_alloc and uf_busy.  UF_ENTER(ufp, fip, fd) also prevents
1667c478bdstevel@tonic-gate *     ufp->uf_alloc, ufp->uf_busy, fip->fi_list and fip->fi_nfiles from
1677c478bdstevel@tonic-gate *     changing.
1687c478bdstevel@tonic-gate *
1697c478bdstevel@tonic-gate * (3) The lock ordering is (1), (2).
1707c478bdstevel@tonic-gate *
1717c478bdstevel@tonic-gate * (4) Note that fip->fi_list and fip->fi_nfiles cannot change while *any*
1727c478bdstevel@tonic-gate *     file list lock is held.  Thus flist_grow() must acquire all such
1737c478bdstevel@tonic-gate *     locks -- fi_lock and every fd's uf_lock -- to install a new file list.
1747c478bdstevel@tonic-gate */
1757c478bdstevel@tonic-gate#define	UF_ENTER(ufp, fip, fd)					\
1767c478bdstevel@tonic-gate	for (;;) {						\
1777c478bdstevel@tonic-gate		uf_entry_t *_flist = (fip)->fi_list;		\
1787c478bdstevel@tonic-gate		ufp = &_flist[fd];				\
1797c478bdstevel@tonic-gate		ASSERT((fd) < (fip)->fi_nfiles);		\
1807c478bdstevel@tonic-gate		mutex_enter(&ufp->uf_lock);			\
1817c478bdstevel@tonic-gate		if (_flist == (fip)->fi_list)			\
1827c478bdstevel@tonic-gate			break;					\
1837c478bdstevel@tonic-gate		mutex_exit(&ufp->uf_lock);			\
1847c478bdstevel@tonic-gate	}
1867c478bdstevel@tonic-gate#define	UF_EXIT(ufp)	mutex_exit(&ufp->uf_lock)
1887c478bdstevel@tonic-gate#define	PSARGSZ		80	/* Space for exec arguments (used by ps(1)) */
1897c478bdstevel@tonic-gate#define	MAXCOMLEN	16	/* <= MAXNAMLEN, >= sizeof (ac_comm) */
1917c478bdstevel@tonic-gatetypedef struct {		/* kernel syscall set type */
1927c478bdstevel@tonic-gate	uint_t	word[9];	/* space for syscall numbers [1..288] */
1937c478bdstevel@tonic-gate} k_sysset_t;
1967c478bdstevel@tonic-gate * __KERN_NAUXV_IMPL is defined as a convenience sizing mechanism
1977c478bdstevel@tonic-gate * for the portions of the kernel that care about aux vectors.
1987c478bdstevel@tonic-gate *
1997c478bdstevel@tonic-gate * Applications that need to know how many aux vectors the kernel
2007c478bdstevel@tonic-gate * supplies should use the proc(4) interface to read /proc/PID/auxv.
2017c478bdstevel@tonic-gate *
2027c478bdstevel@tonic-gate * This value should not be changed in a patch.
2037c478bdstevel@tonic-gate */
2047c478bdstevel@tonic-gate#if defined(__sparc)
205ebb8ac0Robert Mustacchi#define	__KERN_NAUXV_IMPL 20
2067c478bdstevel@tonic-gate#elif defined(__i386) || defined(__amd64)
207d015822Robert Mustacchi#define	__KERN_NAUXV_IMPL 25
2107c478bdstevel@tonic-gatestruct execsw;
2137c478bdstevel@tonic-gate * The user structure; one allocated per process.  Contains all the
2147c478bdstevel@tonic-gate * per-process data that doesn't need to be referenced while the
2157c478bdstevel@tonic-gate * process is swapped.
2167c478bdstevel@tonic-gate */
2177c478bdstevel@tonic-gatetypedef	struct	user {
2187c478bdstevel@tonic-gate	/*
2197c478bdstevel@tonic-gate	 * These fields are initialized at process creation time and never
2207c478bdstevel@tonic-gate	 * modified.  They can be accessed without acquiring locks.
2217c478bdstevel@tonic-gate	 */
2227c478bdstevel@tonic-gate	struct execsw *u_execsw;	/* pointer to exec switch entry */
2237c478bdstevel@tonic-gate	auxv_t  u_auxv[__KERN_NAUXV_IMPL]; /* aux vector from exec */
2247c478bdstevel@tonic-gate	timestruc_t u_start;		/* hrestime at process start */
2257c478bdstevel@tonic-gate	clock_t	u_ticks;		/* lbolt at process start */
2267c478bdstevel@tonic-gate	char	u_comm[MAXCOMLEN + 1];	/* executable file name from exec */
2277c478bdstevel@tonic-gate	char	u_psargs[PSARGSZ];	/* arguments from exec */
2287c478bdstevel@tonic-gate	int	u_argc;			/* value of argc passed to main() */
2297c478bdstevel@tonic-gate	uintptr_t u_argv;		/* value of argv passed to main() */
2307c478bdstevel@tonic-gate	uintptr_t u_envp;		/* value of envp passed to main() */
2312428aadPatrick Mooney	uintptr_t u_commpagep;		/* address of mapped comm page */
2337c478bdstevel@tonic-gate	/*
2347c478bdstevel@tonic-gate	 * These fields are protected by p_lock:
2357c478bdstevel@tonic-gate	 */
2367c478bdstevel@tonic-gate	struct vnode *u_cdir;		/* current directory */
2377c478bdstevel@tonic-gate	struct vnode *u_rdir;		/* root directory */
2387c478bdstevel@tonic-gate	uint64_t u_mem;			/* accumulated memory usage */
2397c478bdstevel@tonic-gate	size_t	u_mem_max;		/* peak RSS (K) */
2407c478bdstevel@tonic-gate	mode_t	u_cmask;		/* mask for file creation */
2417c478bdstevel@tonic-gate	char	u_acflag;		/* accounting flag */
2427c478bdstevel@tonic-gate	char	u_systrap;		/* /proc: any syscall mask bits set? */
2437c478bdstevel@tonic-gate	refstr_t *u_cwd;		/* cached string for cwd */
2457c478bdstevel@tonic-gate	k_sysset_t u_entrymask;		/* /proc syscall stop-on-entry mask */
2467c478bdstevel@tonic-gate	k_sysset_t u_exitmask;		/* /proc syscall stop-on-exit mask */
2477c478bdstevel@tonic-gate	k_sigset_t u_signodefer;	/* signals defered when caught */
2487c478bdstevel@tonic-gate	k_sigset_t u_sigonstack;	/* signals taken on alternate stack */
2497c478bdstevel@tonic-gate	k_sigset_t u_sigresethand;	/* signals reset when caught */
2507c478bdstevel@tonic-gate	k_sigset_t u_sigrestart;	/* signals that restart system calls */
2517c478bdstevel@tonic-gate	k_sigset_t u_sigmask[MAXSIG];	/* signals held while in catcher */
2527c478bdstevel@tonic-gate	void	(*u_signal[MAXSIG])();	/* Disposition of signals */
2547c478bdstevel@tonic-gate	/*
2557c478bdstevel@tonic-gate	 * Resource controls provide the backend for process resource limits,
2567c478bdstevel@tonic-gate	 * the interfaces for which are maintained for compatibility.  To
2577c478bdstevel@tonic-gate	 * preserve the behaviour associated with the RLIM_SAVED_CUR and
2587c478bdstevel@tonic-gate	 * RLIM_SAVED_MAX tokens, we retain the "saved" rlimits.
2597c478bdstevel@tonic-gate	 */
2607c478bdstevel@tonic-gate	struct rlimit64	u_saved_rlimit[RLIM_NSAVED];
2627c478bdstevel@tonic-gate	uf_info_t	u_finfo;	/* open file information */
2637c478bdstevel@tonic-gate} user_t;
2657c478bdstevel@tonic-gate#include <sys/proc.h>			/* cannot include before user defined */
2677c478bdstevel@tonic-gate#ifdef	_KERNEL
2687c478bdstevel@tonic-gate#define	P_FINFO(p)	(&(p)->p_user.u_finfo)
2697c478bdstevel@tonic-gate#endif	/* _KERNEL */
2717c478bdstevel@tonic-gate#ifdef	__cplusplus
2757c478bdstevel@tonic-gate#else	/* defined(_KERNEL) || defined(_KMEMUSER) */
2787c478bdstevel@tonic-gate * Here, we define a fake version of struct user for programs
2797c478bdstevel@tonic-gate * (debuggers) that use ptrace() to read and modify the saved
2807c478bdstevel@tonic-gate * registers directly in the u-area.  ptrace() has been removed
2817c478bdstevel@tonic-gate * from the operating system and now exists as a library function
2827c478bdstevel@tonic-gate * in libc, built on the /proc process filesystem.  The ptrace()
2837c478bdstevel@tonic-gate * library function provides access only to the members of the
2847c478bdstevel@tonic-gate * fake struct user defined here.
2857c478bdstevel@tonic-gate *
2867c478bdstevel@tonic-gate * User-level programs that must know the real contents of struct
2877c478bdstevel@tonic-gate * user will have to define _KMEMUSER before including <sys/user.h>.
2887c478bdstevel@tonic-gate * Such programs also become machine specific. Carefully consider
2897c478bdstevel@tonic-gate * the consequences of your actions.
2907c478bdstevel@tonic-gate */
2927c478bdstevel@tonic-gate#include <sys/regset.h>
2947c478bdstevel@tonic-gate#ifdef	__cplusplus
2957c478bdstevel@tonic-gateextern "C" {
2987c478bdstevel@tonic-gate#define	PSARGSZ		80	/* Space for exec arguments (used by ps(1)) */
3007c478bdstevel@tonic-gatetypedef	struct	user {
3017c478bdstevel@tonic-gate	gregset_t	u_reg;		/* user's saved registers */
3027c478bdstevel@tonic-gate	greg_t		*u_ar0;		/* address of user's saved R0 */
3037c478bdstevel@tonic-gate	char	u_psargs[PSARGSZ];	/* arguments from exec */
3047c478bdstevel@tonic-gate	void	(*u_signal[MAXSIG])();	/* Disposition of signals */
3057c478bdstevel@tonic-gate	int		u_code;		/* fault code on trap */
3067c478bdstevel@tonic-gate	caddr_t		u_addr;		/* fault PC on trap */
3077c478bdstevel@tonic-gate} user_t;
3097c478bdstevel@tonic-gate#ifdef	__cplusplus
3137c478bdstevel@tonic-gate#endif	/* defined(_KERNEL) || defined(_KMEMUSER) */
3157c478bdstevel@tonic-gate#endif	/* _SYS_USER_H */