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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * Copyright 2018 Joyent, Inc. 31 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. 32 * Copyright 2023 Oxide Computer Company 33 */ 34 35 #ifndef _SYS_PROC_PRDATA_H 36 #define _SYS_PROC_PRDATA_H 37 38 #include <sys/isa_defs.h> 39 #include <sys/proc.h> 40 #include <sys/vnode.h> 41 #include <sys/prsystm.h> 42 #include <sys/model.h> 43 #include <sys/poll.h> 44 #include <sys/list.h> 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 /* 51 * Test for thread being stopped, not on an event of interest, 52 * but with a directed stop in effect. 53 */ 54 #define DSTOPPED(t) \ 55 ((t)->t_state == TS_STOPPED && \ 56 ((t)->t_proc_flag & TP_PRSTOP)) 57 58 #define round4(r) (((r) + 3) & (~3)) 59 #define round8(r) (((r) + 7) & (~7)) 60 #define round16(r) (((r) + 15) & (~15)) 61 #define roundlong(r) (((r) + sizeof (long) - 1) & (~(sizeof (long) - 1))) 62 63 #define PNSIZ 10 /* max size of /proc name entries */ 64 #define PLNSIZ 10 /* max size of /proc lwp name entries */ 65 66 /* 67 * Common file object to which all /proc vnodes for a specific process 68 * or lwp refer. One for the process, one for each lwp. 69 */ 70 typedef struct prcommon { 71 kmutex_t prc_mutex; /* to wait for the proc/lwp to stop */ 72 kcondvar_t prc_wait; /* to wait for the proc/lwp to stop */ 73 ushort_t prc_flags; /* flags */ 74 uint_t prc_writers; /* number of write opens of prnodes */ 75 uint_t prc_selfopens; /* number of write opens by self */ 76 pid_t prc_pid; /* process id */ 77 model_t prc_datamodel; /* data model of the process */ 78 proc_t *prc_proc; /* process being traced */ 79 kthread_t *prc_thread; /* thread (lwp) being traced */ 80 int prc_slot; /* procdir slot number */ 81 id_t prc_tid; /* thread (lwp) id */ 82 int prc_tslot; /* lwpdir slot number, -1 if reaped */ 83 int prc_refcnt; /* this structure's reference count */ 84 struct pollhead prc_pollhead; /* list of all pollers */ 85 } prcommon_t; 86 87 /* prc_flags */ 88 #define PRC_DESTROY 0x01 /* process or lwp is being destroyed */ 89 #define PRC_LWP 0x02 /* structure refers to an lwp */ 90 #define PRC_SYS 0x04 /* process is a system process */ 91 #define PRC_POLL 0x08 /* poll() in progress on this process/lwp */ 92 #define PRC_EXCL 0x10 /* exclusive access granted (old /proc) */ 93 94 /* 95 * Macros for mapping between i-numbers and pids. 96 */ 97 #define pmkino(tslot, pslot, nodetype) \ 98 (((((ino_t)(tslot) << nproc_highbit) | \ 99 (ino_t)(pslot)) << 6) | \ 100 (nodetype) + 2) 101 102 /* for old /proc interface */ 103 #define PRBIAS 64 104 #define ptoi(n) ((int)(((n) + PRBIAS))) /* pid to i-number */ 105 106 /* 107 * Node types for /proc files (directories and files contained therein). 108 */ 109 typedef enum prnodetype { 110 PR_PROCDIR, /* /proc */ 111 PR_SELF, /* /proc/self */ 112 PR_PIDDIR, /* /proc/<pid> */ 113 PR_AS, /* /proc/<pid>/as */ 114 PR_CTL, /* /proc/<pid>/ctl */ 115 PR_STATUS, /* /proc/<pid>/status */ 116 PR_LSTATUS, /* /proc/<pid>/lstatus */ 117 PR_PSINFO, /* /proc/<pid>/psinfo */ 118 PR_LPSINFO, /* /proc/<pid>/lpsinfo */ 119 PR_MAP, /* /proc/<pid>/map */ 120 PR_RMAP, /* /proc/<pid>/rmap */ 121 PR_XMAP, /* /proc/<pid>/xmap */ 122 PR_CRED, /* /proc/<pid>/cred */ 123 PR_SIGACT, /* /proc/<pid>/sigact */ 124 PR_AUXV, /* /proc/<pid>/auxv */ 125 #if defined(__i386) || defined(__amd64) 126 PR_LDT, /* /proc/<pid>/ldt */ 127 #endif 128 PR_USAGE, /* /proc/<pid>/usage */ 129 PR_LUSAGE, /* /proc/<pid>/lusage */ 130 PR_PAGEDATA, /* /proc/<pid>/pagedata */ 131 PR_WATCH, /* /proc/<pid>/watch */ 132 PR_CURDIR, /* /proc/<pid>/cwd */ 133 PR_ROOTDIR, /* /proc/<pid>/root */ 134 PR_FDDIR, /* /proc/<pid>/fd */ 135 PR_FD, /* /proc/<pid>/fd/nn */ 136 PR_FDINFODIR, /* /proc/<pid>/fdinfo */ 137 PR_FDINFO, /* /proc/<pid>/fdinfo/nn */ 138 PR_OBJECTDIR, /* /proc/<pid>/object */ 139 PR_OBJECT, /* /proc/<pid>/object/xxx */ 140 PR_LWPDIR, /* /proc/<pid>/lwp */ 141 PR_LWPIDDIR, /* /proc/<pid>/lwp/<lwpid> */ 142 PR_LWPCTL, /* /proc/<pid>/lwp/<lwpid>/lwpctl */ 143 PR_LWPNAME, /* /proc/<pid>/lwp/<lwpid>/lwpname */ 144 PR_LWPSTATUS, /* /proc/<pid>/lwp/<lwpid>/lwpstatus */ 145 PR_LWPSINFO, /* /proc/<pid>/lwp/<lwpid>/lwpsinfo */ 146 PR_LWPUSAGE, /* /proc/<pid>/lwp/<lwpid>/lwpusage */ 147 PR_XREGS, /* /proc/<pid>/lwp/<lwpid>/xregs */ 148 PR_TMPLDIR, /* /proc/<pid>/lwp/<lwpid>/templates */ 149 PR_TMPL, /* /proc/<pid>/lwp/<lwpid>/templates/<id> */ 150 PR_SPYMASTER, /* /proc/<pid>/lwp/<lwpid>/spymaster */ 151 #if defined(__sparc) 152 PR_GWINDOWS, /* /proc/<pid>/lwp/<lwpid>/gwindows */ 153 PR_ASRS, /* /proc/<pid>/lwp/<lwpid>/asrs */ 154 #endif 155 PR_PRIV, /* /proc/<pid>/priv */ 156 PR_PATHDIR, /* /proc/<pid>/path */ 157 PR_PATH, /* /proc/<pid>/path/xxx */ 158 PR_CTDIR, /* /proc/<pid>/contracts */ 159 PR_CT, /* /proc/<pid>/contracts/<ctid> */ 160 PR_SECFLAGS, /* /proc/<pid>/secflags */ 161 PR_PIDFILE, /* old process file */ 162 PR_LWPIDFILE, /* old lwp file */ 163 PR_OPAGEDATA, /* old page data file */ 164 PR_NFILES /* number of /proc node types */ 165 } prnodetype_t; 166 167 typedef struct prnode { 168 vnode_t *pr_next; /* list of all vnodes for process */ 169 uint_t pr_flags; /* private flags */ 170 kmutex_t pr_mutex; /* locks pr_files and child pr_flags */ 171 prnodetype_t pr_type; /* node type */ 172 mode_t pr_mode; /* file mode */ 173 ino_t pr_ino; /* node id (for stat(2)) */ 174 uint_t pr_hatid; /* hat layer id for page data files */ 175 prcommon_t *pr_common; /* common data structure */ 176 prcommon_t *pr_pcommon; /* process common data structure */ 177 vnode_t *pr_parent; /* parent directory */ 178 vnode_t **pr_files; /* contained files array (directory) */ 179 uint_t pr_index; /* position within parent */ 180 vnode_t *pr_pidfile; /* substitute vnode for old /proc */ 181 vnode_t *pr_realvp; /* real vnode, file in object,fd dirs */ 182 proc_t *pr_owner; /* the process that created this node */ 183 vnode_t *pr_vnode; /* pointer to vnode */ 184 struct contract *pr_contract; /* contract pointer */ 185 int pr_cttype; /* active template type */ 186 } prnode_t; 187 188 /* 189 * Values for pr_flags. 190 */ 191 #define PR_INVAL 0x01 /* vnode is invalidated */ 192 #define PR_ISSELF 0x02 /* vnode is a self-open */ 193 #define PR_AOUT 0x04 /* vnode is for an a.out path */ 194 #define PR_OFFMAX 0x08 /* vnode is a large file open */ 195 196 /* 197 * Conversion macros. 198 */ 199 #define VTOP(vp) ((struct prnode *)(vp)->v_data) 200 #define PTOV(pnp) ((pnp)->pr_vnode) 201 202 /* 203 * Flags to prlock(). 204 */ 205 #define ZNO 0 /* Fail on encountering a zombie process. */ 206 #define ZYES 1 /* Allow zombies. */ 207 208 /* 209 * Assign one set to another (possible different sizes). 210 * 211 * Assigning to a smaller set causes members to be lost. 212 * Assigning to a larger set causes extra members to be cleared. 213 */ 214 #define prassignset(ap, sp) \ 215 { \ 216 register int _i_ = sizeof (*(ap))/sizeof (uint32_t); \ 217 while (--_i_ >= 0) \ 218 ((uint32_t *)(ap))[_i_] = \ 219 (_i_ >= sizeof (*(sp))/sizeof (uint32_t)) ? \ 220 0 : ((uint32_t *)(sp))[_i_]; \ 221 } 222 223 /* 224 * Determine whether or not a set (of arbitrary size) is empty. 225 */ 226 #define prisempty(sp) \ 227 setisempty((uint32_t *)(sp), \ 228 (uint_t)(sizeof (*(sp)) / sizeof (uint32_t))) 229 230 /* 231 * Resource usage with times as hrtime_t rather than timestruc_t. 232 * Each member exactly matches the corresponding member in prusage_t. 233 * This is for convenience of internal computation. 234 */ 235 typedef struct prhusage { 236 id_t pr_lwpid; /* lwp id. 0: process or defunct */ 237 int pr_count; /* number of contributing lwps */ 238 hrtime_t pr_tstamp; /* current time stamp */ 239 hrtime_t pr_create; /* process/lwp creation time stamp */ 240 hrtime_t pr_term; /* process/lwp termination time stamp */ 241 hrtime_t pr_rtime; /* total lwp real (elapsed) time */ 242 hrtime_t pr_utime; /* user level CPU time */ 243 hrtime_t pr_stime; /* system call CPU time */ 244 hrtime_t pr_ttime; /* other system trap CPU time */ 245 hrtime_t pr_tftime; /* text page fault sleep time */ 246 hrtime_t pr_dftime; /* data page fault sleep time */ 247 hrtime_t pr_kftime; /* kernel page fault sleep time */ 248 hrtime_t pr_ltime; /* user lock wait sleep time */ 249 hrtime_t pr_slptime; /* all other sleep time */ 250 hrtime_t pr_wtime; /* wait-cpu (latency) time */ 251 hrtime_t pr_stoptime; /* stopped time */ 252 hrtime_t filltime[6]; /* filler for future expansion */ 253 uint64_t pr_minf; /* minor page faults */ 254 uint64_t pr_majf; /* major page faults */ 255 uint64_t pr_nswap; /* swaps */ 256 uint64_t pr_inblk; /* input blocks */ 257 uint64_t pr_oublk; /* output blocks */ 258 uint64_t pr_msnd; /* messages sent */ 259 uint64_t pr_mrcv; /* messages received */ 260 uint64_t pr_sigs; /* signals received */ 261 uint64_t pr_vctx; /* voluntary context switches */ 262 uint64_t pr_ictx; /* involuntary context switches */ 263 uint64_t pr_sysc; /* system calls */ 264 uint64_t pr_ioch; /* chars read and written */ 265 uint64_t filler[10]; /* filler for future expansion */ 266 } prhusage_t; 267 268 #if defined(_KERNEL) 269 270 /* Exclude system processes from this test */ 271 #define PROCESS_NOT_32BIT(p) \ 272 (!((p)->p_flag & SSYS) && (p)->p_as != &kas && \ 273 (p)->p_model != DATAMODEL_ILP32) 274 275 extern int prnwatch; /* number of supported watchpoints */ 276 extern int nproc_highbit; /* highbit(v.v_nproc) */ 277 278 extern struct vnodeops *prvnodeops; 279 280 /* 281 * Generic chained copyout buffers for procfs use. 282 * In order to prevent procfs from making huge oversize kmem_alloc calls, 283 * a list of smaller buffers can be concatenated and copied to userspace in 284 * sequence. 285 * 286 * The implementation is opaque. 287 * 288 * A user of this will perform the following steps: 289 * 290 * list_t listhead; 291 * struct my *mp; 292 * 293 * pr_iol_initlist(&listhead, sizeof (*mp), n); 294 * while (whatever) { 295 * mp = pr_iol_newbuf(&listhead, sizeof (*mp)); 296 * ... 297 * error = ... 298 * } 299 * 300 * When done, depending on whether copyout() or uiomove() is supposed to 301 * be used for transferring the buffered data to userspace, call either: 302 * 303 * error = pr_iol_copyout_and_free(&listhead, &cmaddr, error); 304 * 305 * or else: 306 * 307 * error = pr_iol_uiomove_and_free(&listhead, uiop, error); 308 * 309 * These two functions will in any case kmem_free() all list items, but 310 * if an error occurred before they will not perform the copyout/uiomove. 311 * If copyout/uiomove are done, the passed target address / uio_t 312 * are updated. The error returned will either be the one passed in, or 313 * the error that occurred during copyout/uiomove. 314 */ 315 316 extern void pr_iol_initlist(list_t *head, size_t itemsize, int nitems); 317 extern void * pr_iol_newbuf(list_t *head, size_t itemsize); 318 extern int pr_iol_copyout_and_free(list_t *head, caddr_t *tgt, int errin); 319 extern int pr_iol_uiomove_and_free(list_t *head, uio_t *uiop, int errin); 320 extern void pr_iol_freelist(list_t *); 321 322 #if defined(_SYSCALL32_IMPL) 323 324 extern int prwritectl32(vnode_t *, struct uio *, cred_t *); 325 extern void prgetaction32(proc_t *, user_t *, uint_t, struct sigaction32 *); 326 extern void prcvtusage32(struct prhusage *, prusage32_t *); 327 328 #endif /* _SYSCALL32_IMPL */ 329 330 /* kludge to support old /proc interface */ 331 #if !defined(_SYS_OLD_PROCFS_H) 332 extern int prgetmap(proc_t *, int, list_t *); 333 extern int prgetxmap(proc_t *, list_t *); 334 #if defined(_SYSCALL32_IMPL) 335 extern int prgetmap32(proc_t *, int, list_t *); 336 extern int prgetxmap32(proc_t *, list_t *); 337 #endif /* _SYSCALL32_IMPL */ 338 #endif /* !_SYS_OLD_PROCFS_H */ 339 340 extern proc_t *pr_p_lock(prnode_t *); 341 extern kthread_t *pr_thread(prnode_t *); 342 extern void pr_stop(prnode_t *); 343 extern int pr_wait_stop(prnode_t *, time_t); 344 extern int pr_setrun(prnode_t *, ulong_t); 345 extern int pr_wait(prcommon_t *, timestruc_t *, int); 346 extern void pr_wait_die(prnode_t *); 347 extern int pr_setsig(prnode_t *, siginfo_t *); 348 extern int pr_kill(prnode_t *, int, cred_t *); 349 extern int pr_unkill(prnode_t *, int); 350 extern int pr_nice(proc_t *, int, cred_t *); 351 extern void pr_setentryexit(proc_t *, sysset_t *, int); 352 extern int pr_set(proc_t *, long); 353 extern int pr_unset(proc_t *, long); 354 extern void pr_sethold(prnode_t *, sigset_t *); 355 extern file_t *pr_getf(proc_t *, uint_t, short *); 356 extern void pr_releasef(file_t *); 357 extern void pr_setfault(proc_t *, fltset_t *); 358 extern int prusrio(proc_t *, enum uio_rw, struct uio *, int); 359 extern int prwritectl(vnode_t *, struct uio *, cred_t *); 360 extern int prlock(prnode_t *, int); 361 extern void prunmark(proc_t *); 362 extern void prunlock(prnode_t *); 363 extern size_t prpdsize(struct as *); 364 extern int prpdread(proc_t *, uint_t, struct uio *); 365 extern size_t oprpdsize(struct as *); 366 extern int oprpdread(struct as *, uint_t, struct uio *); 367 extern void prgetaction(proc_t *, user_t *, uint_t, struct sigaction *); 368 extern void prgetusage(kthread_t *, struct prhusage *); 369 extern void praddusage(kthread_t *, struct prhusage *); 370 extern void prcvtusage(struct prhusage *, prusage_t *); 371 extern void prscaleusage(prhusage_t *); 372 extern kthread_t *prchoose(proc_t *); 373 extern void allsetrun(proc_t *); 374 extern int setisempty(uint32_t *, uint_t); 375 extern int pr_u32tos(uint32_t, char *, int); 376 extern vnode_t *prlwpnode(prnode_t *, uint_t); 377 extern prnode_t *prgetnode(vnode_t *, prnodetype_t); 378 extern void prfreenode(prnode_t *); 379 extern void pr_object_name(char *, vnode_t *, struct vattr *); 380 extern int set_watched_area(proc_t *, struct watched_area *); 381 extern int clear_watched_area(proc_t *, struct watched_area *); 382 extern void pr_free_watchpoints(proc_t *); 383 extern proc_t *pr_cancel_watch(prnode_t *); 384 extern struct seg *break_seg(proc_t *); 385 extern void prgethold(kthread_t *, sigset_t *); 386 387 /* 388 * Machine-dependent routines (defined in prmachdep.c). 389 */ 390 extern void prgetprregs(klwp_t *, prgregset_t); 391 extern void prsetprregs(klwp_t *, prgregset_t, int); 392 393 #if defined(_SYSCALL32_IMPL) 394 extern void prgetprregs32(klwp_t *, prgregset32_t); 395 extern void prgregset_32ton(klwp_t *, prgregset32_t, prgregset_t); 396 extern void prgetprfpregs32(klwp_t *, prfpregset32_t *); 397 extern void prsetprfpregs32(klwp_t *, prfpregset32_t *); 398 extern size_t prpdsize32(struct as *); 399 extern int prpdread32(proc_t *, uint_t, struct uio *); 400 extern size_t oprpdsize32(struct as *); 401 extern int oprpdread32(struct as *, uint_t, struct uio *); 402 #endif /* _SYSCALL32_IMPL */ 403 404 extern void prpokethread(kthread_t *t); 405 extern int prgetrvals(klwp_t *, long *, long *); 406 extern void prgetprfpregs(klwp_t *, prfpregset_t *); 407 extern void prsetprfpregs(klwp_t *, prfpregset_t *); 408 extern int prhasfp(void); 409 extern caddr_t prgetstackbase(proc_t *); 410 extern caddr_t prgetpsaddr(proc_t *); 411 extern int prisstep(klwp_t *); 412 extern void prsvaddr(klwp_t *, caddr_t); 413 extern int prfetchinstr(klwp_t *, ulong_t *); 414 extern ushort_t prgetpctcpu(uint64_t); 415 416 /* 417 * This set of routines is used by platforms to implement support for the 418 * 'xregs' or extended registers in /proc. Unlike other registers which 419 * generally have a well-defined value determined by the ABI that never changes, 420 * we expect these to change. 421 * 422 * An important thing to note is that you'll see we have moved away from a 423 * traditional version of a fixed size, non-opaque definition of the 424 * prxregset_t. This is because the size varies and we don't want applications 425 * to incorrectly bake a real definition in and cause problems where extending 426 * it becomes very hard to do (ala the prgregset_t and prfregset_t). This is a 427 * little more work for everyone implementing it, but it does ensure that we are 428 * generally in better shape. 429 * 430 * Here are the semantics of what these are required to do and how the fit 431 * together: 432 * 433 * o prhasx Determine if the process in question supports the 434 * extended register sets. Note, this is may be a 435 * process-specific setting due to things like whether or 436 * not the FPU is enabled or other things. 437 * 438 * o prgetxregsize This returns the size of the actual xregs file for a 439 * given process. This may change between processes because 440 * not every process may have the same set of extended 441 * features enabled (e.g. AMX on x86). If xregs is not 442 * supported then this should return 0. If xregs are 443 * supported, then returning zero will lead other 444 * operations to fail. 445 * 446 * o prwriteminxreg This is used by the prwritectl() and related worlds to 447 * determine the minimum amount of data that much be 448 * present to determine if the actual size of a write is 449 * valid. If xregs is not supported, then this should 450 * return B_FALSE. If xregs is supported, this may return 0 451 * if no additional information is required to determine 452 * the appropriate size to copy in. This would be the case 453 * if the xregs structure is a fixed size. 454 * 455 * o prwritesizexreg This is meant to indicate how much data is required to 456 * be copied in for a given xregs write. The base data will 457 * already be present from having called prwriteminxreg 458 * previously. If xregs are not supported this should 459 * return B_FALSE. 460 * 461 * There is a wrinkle in this which is not true of other 462 * callers. The data that we are given is not guaranteed to 463 * be aligned in the slightest due to the need to support 464 * both ILP32 and LP64! 465 * 466 * o prgetprxregs This is a request to fill in the xregs data. Right now 467 * the system guarantees that the buffer size is at least 468 * the result of the prgetprxregs() call for this process. 469 * Callers may assume that the process remains locked 470 * between the two so that the size doesn't change. This 471 * will not be called for processes where prhasx() return 472 * false. 473 * 474 * o prsetprxregs This is a request to set the xregs data. The only 475 * assumption that should be made is that the validation of 476 * the size in prwritesizexreg() has been performed. Users 477 * can and will potentially try to trick us with invalid 478 * values. Do not blindly apply the supplied xregs. 479 * 480 * If xregs are not supported this should return EINVAL. 481 * While yes other errnos may make more sense, that is what 482 * we have always returned in /proc for this case. 483 */ 484 extern int prhasx(proc_t *); 485 extern size_t prgetprxregsize(proc_t *); 486 extern void prgetprxregs(klwp_t *, prxregset_t *); 487 extern boolean_t prwriteminxreg(size_t *); 488 extern boolean_t prwritesizexreg(const void *, size_t *); 489 extern int prsetprxregs(klwp_t *, prxregset_t *); 490 491 #endif /* _KERNEL */ 492 493 #ifdef __cplusplus 494 } 495 #endif 496 497 #endif /* _SYS_PROC_PRDATA_H */ 498