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