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 2013 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*
  30  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  31  */
  32 
  33 #ifndef _SYS_KLWP_H
  34 #define _SYS_KLWP_H
  35 
  36 #include <sys/types.h>
  37 #include <sys/condvar.h>
  38 #include <sys/thread.h>
  39 #include <sys/signal.h>
  40 #include <sys/siginfo.h>
  41 #include <sys/pcb.h>
  42 #include <sys/time.h>
  43 #include <sys/msacct.h>
  44 #include <sys/ucontext.h>
  45 #include <sys/lwp.h>
  46 #include <sys/contract.h>
  47 
  48 #if (defined(_KERNEL) || defined(_KMEMUSER)) && defined(_MACHDEP)
  49 #include <sys/machparam.h>
  50 #endif
  51 
  52 #ifdef  __cplusplus
  53 extern "C" {
  54 #endif
  55 
  56 /*
  57  * The light-weight process object and the methods by which it
  58  * is accessed.
  59  */
  60 
  61 #define MAXSYSARGS      8       /* Maximum # of arguments passed to a syscall */
  62 
  63 /* lwp_eosys values */
  64 #define NORMALRETURN    0       /* normal return; adjusts PC, registers */
  65 #define JUSTRETURN      1       /* just return, leave registers alone */
  66 
  67 /*
  68  * Resource usage, per-lwp plus per-process (sum over defunct lwps).
  69  */
  70 struct lrusage {
  71         u_longlong_t    minflt;         /* minor page faults */
  72         u_longlong_t    majflt;         /* major page faults */
  73         u_longlong_t    nswap;          /* swaps */
  74         u_longlong_t    inblock;        /* input blocks */
  75         u_longlong_t    oublock;        /* output blocks */
  76         u_longlong_t    msgsnd;         /* messages sent */
  77         u_longlong_t    msgrcv;         /* messages received */
  78         u_longlong_t    nsignals;       /* signals received */
  79         u_longlong_t    nvcsw;          /* voluntary context switches */
  80         u_longlong_t    nivcsw;         /* involuntary context switches */
  81         u_longlong_t    sysc;           /* system calls */
  82         u_longlong_t    ioch;           /* chars read and written */
  83 };
  84 
  85 typedef struct _klwp    *klwp_id_t;
  86 
  87 typedef struct _klwp {
  88         /*
  89          * user-mode context
  90          */
  91         struct pcb      lwp_pcb;                /* user regs save pcb */
  92         uintptr_t       lwp_oldcontext;         /* previous user context */
  93 
  94         /*
  95          * system-call interface
  96          */
  97         long    *lwp_ap;        /* pointer to arglist */
  98         int     lwp_errno;      /* error for current syscall (private) */
  99         /*
 100          * support for I/O
 101          */
 102         char    lwp_error;      /* return error code */
 103         char    lwp_eosys;      /* special action on end of syscall */
 104         char    lwp_argsaved;   /* are all args in lwp_arg */
 105         char    lwp_watchtrap;  /* lwp undergoing watchpoint single-step */
 106         long    lwp_arg[MAXSYSARGS];    /* args to current syscall */
 107         void    *lwp_regs;      /* pointer to saved regs on stack */
 108         void    *lwp_fpu;       /* pointer to fpu regs */
 109         label_t lwp_qsav;       /* longjmp label for quits and interrupts */
 110 
 111         /*
 112          * signal handling and debugger (/proc) interface
 113          */
 114         uchar_t lwp_cursig;             /* current signal */
 115         uchar_t lwp_curflt;             /* current fault */
 116         uchar_t lwp_sysabort;           /* if set, abort syscall */
 117         uchar_t lwp_asleep;             /* lwp asleep in syscall */
 118         uchar_t lwp_extsig;             /* cursig sent from another contract */
 119         stack_t lwp_sigaltstack;        /* alternate signal stack */
 120         struct sigqueue *lwp_curinfo;   /* siginfo for current signal */
 121         k_siginfo_t     lwp_siginfo;    /* siginfo for stop-on-fault */
 122         k_sigset_t      lwp_sigoldmask; /* for sigsuspend */
 123         struct lwp_watch {              /* used in watchpoint single-stepping */
 124                 caddr_t wpaddr;
 125                 size_t  wpsize;
 126                 int     wpcode;
 127                 int     wpmapped;
 128                 greg_t  wppc;
 129         } lwp_watch[4];         /* one for each of exec/write/read/read */
 130 
 131         uint32_t lwp_oweupc;            /* profil(2) ticks owed to this lwp */
 132 
 133         /*
 134          * Microstate accounting.  Timestamps are made at the start and the
 135          * end of each microstate (see <sys/msacct.h> for state definitions)
 136          * and the corresponding accounting info is updated.  The current
 137          * microstate is kept in the thread struct, since there are cases
 138          * when one thread must update another thread's state (a no-no
 139          * for an lwp since it may be swapped/paged out).  The rest of the
 140          * microstate stuff is kept here to avoid wasting space on things
 141          * like kernel threads that don't have an associated lwp.
 142          */
 143         struct mstate {
 144                 int ms_prev;                    /* previous running mstate */
 145                 hrtime_t ms_start;              /* lwp creation time */
 146                 hrtime_t ms_term;               /* lwp termination time */
 147                 hrtime_t ms_state_start;        /* start time of this mstate */
 148                 hrtime_t ms_acct[NMSTATES];     /* per mstate accounting */
 149         } lwp_mstate;
 150 
 151         /*
 152          * Per-lwp resource usage.
 153          */
 154         struct lrusage lwp_ru;
 155 
 156         /*
 157          * Things to keep for real-time (SIGPROF) profiling.
 158          */
 159         int     lwp_lastfault;
 160         caddr_t lwp_lastfaddr;
 161 
 162         /*
 163          * timers. Protected by lwp->procp->p_lock
 164          */
 165         struct itimerval lwp_timer[3];
 166 
 167         /*
 168          * used to stop/alert lwps
 169          */
 170         char    lwp_unused;
 171         char    lwp_state;      /* Running in User/Kernel mode (no lock req) */
 172         ushort_t lwp_nostop;    /* Don't stop this lwp (no lock required) */
 173         ushort_t lwp_pad;       /* Reserved for future use */
 174 
 175         /*
 176          * Last failed privilege.
 177          */
 178         short   lwp_badpriv;
 179 
 180         /*
 181          * linkage
 182          */
 183         struct _kthread *lwp_thread;
 184         struct proc     *lwp_procp;
 185 
 186         size_t lwp_childstksz;  /* kernel stksize for this lwp's descendants */
 187 
 188         uintptr_t       lwp_ustack;             /* current stack bounds */
 189         size_t          lwp_old_stk_ctl;        /* old stack limit */
 190 
 191         /*
 192          * Contracts
 193          */
 194         struct ct_template *lwp_ct_active[CTT_MAXTYPE]; /* active templates */
 195         struct contract *lwp_ct_latest[CTT_MAXTYPE]; /* last created contract */
 196 
 197         void    *lwp_brand;             /* per-lwp brand data */
 198         struct psinfo *lwp_spymaster;   /* if an agent LWP, our spymaster */
 199 } klwp_t;
 200 
 201 /* lwp states */
 202 #define LWP_USER        0x01            /* Running in user mode */
 203 #define LWP_SYS         0x02            /* Running in kernel mode */
 204 
 205 #if     defined(_KERNEL)
 206 extern  volatile int    lwp_default_stksize;
 207 extern  int     lwp_reapcnt;
 208 
 209 extern  struct _kthread *lwp_deathrow;
 210 extern  kmutex_t        reaplock;
 211 extern  struct kmem_cache *lwp_cache;
 212 extern  void            *segkp_lwp;
 213 extern  klwp_t          lwp0;
 214 
 215 /* where newly-created lwps normally start */
 216 extern  void    lwp_rtt(void);
 217 
 218 #endif  /* _KERNEL */
 219 
 220 #ifdef  __cplusplus
 221 }
 222 #endif
 223 
 224 #endif  /* _SYS_KLWP_H */