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/intel/fs/proc/prmachdep.c
          +++ new/usr/src/uts/intel/fs/proc/prmachdep.c
   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]
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  28      -/*        All Rights Reserved   */
       28 +/*        All Rights Reserved   */
  29   29  
       30 +/*
       31 + * Copyright 2023 Oxide Computer Company
       32 + */
       33 +
  30   34  #include <sys/types.h>
  31   35  #include <sys/t_lock.h>
  32   36  #include <sys/param.h>
  33   37  #include <sys/cred.h>
  34   38  #include <sys/debug.h>
  35   39  #include <sys/inline.h>
  36   40  #include <sys/kmem.h>
  37   41  #include <sys/proc.h>
  38   42  #include <sys/regset.h>
  39   43  #include <sys/privregs.h>
  40   44  #include <sys/sysmacros.h>
  41   45  #include <sys/systm.h>
  42   46  #include <sys/vfs.h>
  43   47  #include <sys/vnode.h>
  44   48  #include <sys/psw.h>
  45   49  #include <sys/pcb.h>
  46   50  #include <sys/buf.h>
  47   51  #include <sys/signal.h>
  48   52  #include <sys/user.h>
  49   53  #include <sys/cpuvar.h>
       54 +#include <sys/stdalign.h>
  50   55  
  51   56  #include <sys/fault.h>
  52   57  #include <sys/syscall.h>
  53   58  #include <sys/procfs.h>
  54   59  #include <sys/cmn_err.h>
  55   60  #include <sys/stack.h>
  56   61  #include <sys/debugreg.h>
  57   62  #include <sys/copyops.h>
  58   63  
  59   64  #include <sys/vmem.h>
  60   65  #include <sys/mman.h>
  61   66  #include <sys/vmparam.h>
  62   67  #include <sys/fp.h>
  63   68  #include <sys/archsystm.h>
  64   69  #include <sys/vmsystm.h>
  65   70  #include <vm/hat.h>
  66   71  #include <vm/as.h>
  67   72  #include <vm/seg.h>
  68   73  #include <vm/seg_kmem.h>
  69   74  #include <vm/seg_kp.h>
  70   75  #include <vm/page.h>
  71   76  
  72   77  #include <sys/sysi86.h>
  73   78  
  74   79  #include <fs/proc/prdata.h>
  75   80  
  76   81  int     prnwatch = 10000;       /* maximum number of watched areas */
  77   82  
  78   83  /*
  79   84   * Force a thread into the kernel if it is not already there.
  80   85   * This is a no-op on uniprocessors.
  81   86   */
  82   87  /* ARGSUSED */
  83   88  void
  84   89  prpokethread(kthread_t *t)
  85   90  {
  86   91          if (t->t_state == TS_ONPROC && t->t_cpu != CPU)
  87   92                  poke_cpu(t->t_cpu->cpu_id);
  88   93  }
  89   94  
  90   95  /*
  91   96   * Return general registers.
  92   97   */
  93   98  void
  94   99  prgetprregs(klwp_t *lwp, prgregset_t prp)
  95  100  {
  96  101          ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
  97  102  
  98  103          getgregs(lwp, prp);
  99  104  }
 100  105  
 101  106  /*
 102  107   * Set general registers.
 103  108   * (Note: This can be an alias to setgregs().)
 104  109   */
 105  110  void
 106  111  prsetprregs(klwp_t *lwp, prgregset_t prp, int initial)
 107  112  {
 108  113          if (initial)            /* set initial values */
 109  114                  lwptoregs(lwp)->r_ps = PSL_USER;
 110  115          (void) setgregs(lwp, prp);
 111  116  }
 112  117  
 113  118  #ifdef _SYSCALL32_IMPL
 114  119  
 115  120  /*
 116  121   * Convert prgregset32 to native prgregset
 117  122   */
 118  123  void
 119  124  prgregset_32ton(klwp_t *lwp, prgregset32_t src, prgregset_t dst)
 120  125  {
 121  126          struct regs *rp = lwptoregs(lwp);
 122  127  
 123  128          dst[REG_GSBASE] = lwp->lwp_pcb.pcb_gsbase;
 124  129          dst[REG_FSBASE] = lwp->lwp_pcb.pcb_fsbase;
 125  130  
 126  131          dst[REG_DS] = (uint16_t)src[DS];
 127  132          dst[REG_ES] = (uint16_t)src[ES];
 128  133  
 129  134          dst[REG_GS] = (uint16_t)src[GS];
 130  135          dst[REG_FS] = (uint16_t)src[FS];
 131  136          dst[REG_SS] = (uint16_t)src[SS];
 132  137          dst[REG_RSP] = (uint32_t)src[UESP];
 133  138          dst[REG_RFL] =
 134  139              (rp->r_ps & ~PSL_USERMASK) | (src[EFL] & PSL_USERMASK);
 135  140          dst[REG_CS] = (uint16_t)src[CS];
 136  141          dst[REG_RIP] = (uint32_t)src[EIP];
 137  142          dst[REG_ERR] = (uint32_t)src[ERR];
 138  143          dst[REG_TRAPNO] = (uint32_t)src[TRAPNO];
 139  144          dst[REG_RAX] = (uint32_t)src[EAX];
 140  145          dst[REG_RCX] = (uint32_t)src[ECX];
 141  146          dst[REG_RDX] = (uint32_t)src[EDX];
 142  147          dst[REG_RBX] = (uint32_t)src[EBX];
 143  148          dst[REG_RBP] = (uint32_t)src[EBP];
 144  149          dst[REG_RSI] = (uint32_t)src[ESI];
 145  150          dst[REG_RDI] = (uint32_t)src[EDI];
 146  151          dst[REG_R8] = dst[REG_R9] = dst[REG_R10] = dst[REG_R11] =
 147  152              dst[REG_R12] = dst[REG_R13] = dst[REG_R14] = dst[REG_R15] = 0;
 148  153  }
 149  154  
 150  155  /*
 151  156   * Return 32-bit general registers
 152  157   */
 153  158  void
 154  159  prgetprregs32(klwp_t *lwp, prgregset32_t prp)
 155  160  {
 156  161          ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
 157  162          getgregs32(lwp, prp);
 158  163  }
 159  164  
 160  165  #endif  /* _SYSCALL32_IMPL */
 161  166  
 162  167  /*
 163  168   * Get the syscall return values for the lwp.
 164  169   */
 165  170  int
 166  171  prgetrvals(klwp_t *lwp, long *rval1, long *rval2)
 167  172  {
 168  173          struct regs *r = lwptoregs(lwp);
 169  174  
 170  175          if (r->r_ps & PS_C)
 171  176                  return (r->r_r0);
 172  177          if (lwp->lwp_eosys == JUSTRETURN) {
 173  178                  *rval1 = 0;
 174  179                  *rval2 = 0;
 175  180          } else if (lwp_getdatamodel(lwp) != DATAMODEL_NATIVE) {
 176  181                  /*
 177  182                   * XX64 Not sure we -really- need to do this, because the
 178  183                   *      syscall return already masks off the bottom values ..?
 179  184                   */
 180  185                  *rval1 = r->r_r0 & (uint32_t)0xffffffffu;
 181  186                  *rval2 = r->r_r1 & (uint32_t)0xffffffffu;
 182  187          } else {
 183  188                  *rval1 = r->r_r0;
 184  189                  *rval2 = r->r_r1;
 185  190          }
 186  191          return (0);
 187  192  }
 188  193  
 189  194  /*
 190  195   * Does the system support floating-point, either through hardware
 191  196   * or by trapping and emulating floating-point machine instructions?
 192  197   */
 193  198  int
 194  199  prhasfp(void)
 195  200  {
 196  201          extern int fp_kind;
 197  202  
 198  203          return (fp_kind != FP_NO);
 199  204  }
 200  205  
 201  206  /*
 202  207   * Get floating-point registers.
 203  208   */
 204  209  void
 205  210  prgetprfpregs(klwp_t *lwp, prfpregset_t *pfp)
 206  211  {
 207  212          bzero(pfp, sizeof (prfpregset_t));
 208  213          getfpregs(lwp, pfp);
 209  214  }
 210  215  
 211  216  #if defined(_SYSCALL32_IMPL)
 212  217  void
 213  218  prgetprfpregs32(klwp_t *lwp, prfpregset32_t *pfp)
 214  219  {
 215  220          bzero(pfp, sizeof (*pfp));
 216  221          getfpregs32(lwp, pfp);
 217  222  }
 218  223  #endif  /* _SYSCALL32_IMPL */
 219  224  
 220  225  /*
 221  226   * Set floating-point registers.
 222  227   * (Note: This can be an alias to setfpregs().)
 223  228   */
 224  229  void
 225  230  prsetprfpregs(klwp_t *lwp, prfpregset_t *pfp)
 226  231  {
 227  232          setfpregs(lwp, pfp);
 228  233  }
  
    | 
      ↓ open down ↓ | 
    169 lines elided | 
    
      ↑ open up ↑ | 
  
 229  234  
 230  235  #if defined(_SYSCALL32_IMPL)
 231  236  void
 232  237  prsetprfpregs32(klwp_t *lwp, prfpregset32_t *pfp)
 233  238  {
 234  239          setfpregs32(lwp, pfp);
 235  240  }
 236  241  #endif  /* _SYSCALL32_IMPL */
 237  242  
 238  243  /*
 239      - * Does the system support extra register state?
      244 + * This is a general function that the main part of /proc and the rest of the
      245 + * system uses to ask does a given process actually have extended state. Right
      246 + * now, this question is not process-specific, but rather CPU specific. We look
      247 + * at whether xsave has been enabled to determine that. While strictly speaking
      248 + * one could make the argument that all amd64 CPUs support fxsave and we could
      249 + * emulate something that only supports that, we don't think that makes sense.
 240  250   */
 241      -/* ARGSUSED */
 242  251  int
 243  252  prhasx(proc_t *p)
 244  253  {
 245      -        return (0);
      254 +        return (fpu_xsave_enabled());
 246  255  }
 247  256  
 248  257  /*
 249      - * Get the size of the extra registers.
      258 + * Return the minimum size that we need to determine the full size of a
      259 + * prxregset_t.
 250  260   */
 251      -/* ARGSUSED */
 252      -int
      261 +boolean_t
      262 +prwriteminxreg(size_t *sizep)
      263 +{
      264 +        *sizep = sizeof (prxregset_hdr_t);
      265 +        return (B_TRUE);
      266 +}
      267 +
      268 +/*
      269 + * This routine services both ILP32 and LP64 callers. We cannot assume anything
      270 + * about the alignment of argp and must bcopy things to known structures that we
      271 + * care about. We are guaranteed we have prxregset_hdr_t bytes because we asked
      272 + * for them above.
      273 + */
      274 +boolean_t
      275 +prwritesizexreg(const void *argp, size_t *sizep)
      276 +{
      277 +        prxregset_hdr_t hdr;
      278 +
      279 +        /*
      280 +         * While it's tempting to validate everything here, the only thing we
      281 +         * care about is that we understand the type and the size meets our
      282 +         * constraints:
      283 +         *
      284 +         *  o We actually have an item of type PR_TYPE_XSAVE, otherwise we
      285 +         *    don't know what this is.
      286 +         *  o The indicated size actually contains at least the
      287 +         *    prxregset_hdr_t.
      288 +         *  o The indicated size isn't larger than what the FPU tells us is
      289 +         *    allowed.
      290 +         *
      291 +         * We do not check if the reset of the structure makes semantic sense at
      292 +         * this point. We save all other validation for the normal set function
      293 +         * as that's when we'll have the rest of our data.
      294 +         */
      295 +        bcopy(argp, &hdr, sizeof (hdr));
      296 +        if (hdr.pr_type != PR_TYPE_XSAVE ||
      297 +            hdr.pr_size > fpu_proc_xregs_max_size() ||
      298 +            hdr.pr_size < sizeof (prxregset_hdr_t)) {
      299 +                return (B_FALSE);
      300 +        }
      301 +
      302 +        *sizep = hdr.pr_size - sizeof (prxregset_hdr_t);
      303 +        return (B_TRUE);
      304 +}
      305 +
      306 +/*
      307 + * Get the size of the extra registers. The ultimate size here depends on a
      308 + * combination of a few different things. Right now the xregs always have our
      309 + * header, the illumos-specific XCR information, the xsave information, and then
      310 + * otherwise this varies based on the items that the CPU supports.
      311 + *
      312 + * The ultimate size here is going to be:
      313 + *
      314 + *  o 1x prxregset_hdr_t
      315 + *  o n  prxregset_info_t structures
      316 + *  o The individual data for each one
      317 + */
      318 +size_t
 253  319  prgetprxregsize(proc_t *p)
 254  320  {
 255      -        return (0);
      321 +        uint32_t size;
      322 +
      323 +        fpu_proc_xregs_info(p, NULL, &size, NULL);
      324 +        return (size);
 256  325  }
 257  326  
 258  327  /*
 259  328   * Get extra registers.
 260  329   */
 261      -/*ARGSUSED*/
 262  330  void
 263      -prgetprxregs(klwp_t *lwp, caddr_t prx)
      331 +prgetprxregs(klwp_t *lwp, prxregset_t *prx)
 264  332  {
 265      -        /* no extra registers */
      333 +        fpu_proc_xregs_get(lwp, prx);
 266  334  }
 267  335  
 268  336  /*
 269  337   * Set extra registers.
      338 + *
      339 + * We've been given a regset to set. Before we hand it off to the FPU, we have
      340 + * to go through and make sure that the different parts of this actually make
      341 + * sense. The kernel has guaranteed us through the functions above that we have
      342 + * the number of bytes that the header indicates are present. In particular we
      343 + * need to validate:
      344 + *
      345 + *   o The information in the header is reasonable: we have a known type, flags
      346 + *     and padding are zero, and there is at least one info structure.
      347 + *   o Each of the info structures has a valid type, size, and fits within the
      348 + *     data we were given.
      349 + *   o We do not validate or modify the actual data in the different pieces for
      350 + *     validity. That is considered something that the FPU does. Similarly if
      351 + *     something is read-only or not used, that is something that it checks.
      352 + *
      353 + * While we would like to return something other than EINVAL, the /proc APIs
      354 + * pretty much lead that to being the primary errno for all sorts of situations.
 270  355   */
 271      -/*ARGSUSED*/
 272      -void
 273      -prsetprxregs(klwp_t *lwp, caddr_t prx)
      356 +int
      357 +prsetprxregs(klwp_t *lwp, prxregset_t *prx)
 274  358  {
 275      -        /* no extra registers */
      359 +        size_t infosz;
      360 +        prxregset_hdr_t *hdr = (prxregset_hdr_t *)prx;
      361 +
      362 +        if (hdr->pr_type != PR_TYPE_XSAVE || hdr->pr_flags != 0 ||
      363 +            hdr->pr_pad[0] != 0 || hdr->pr_pad[1] != 0 || hdr->pr_pad[2] != 0 ||
      364 +            hdr->pr_pad[3] != 0 || hdr->pr_ninfo == 0) {
      365 +                return (EINVAL);
      366 +        }
      367 +
      368 +        infosz = hdr->pr_ninfo * sizeof (prxregset_info_t) +
      369 +            sizeof (prxregset_hdr_t);
      370 +        if (infosz > hdr->pr_size) {
      371 +                return (EINVAL);
      372 +        }
      373 +
      374 +        for (uint32_t i = 0; i < hdr->pr_ninfo; i++) {
      375 +                uint32_t exp_size;
      376 +                size_t need_len, exp_align;
      377 +                const prxregset_info_t *info = &hdr->pr_info[i];
      378 +
      379 +                switch (info->pri_type) {
      380 +                case PRX_INFO_XCR:
      381 +                        exp_size = sizeof (prxregset_xcr_t);
      382 +                        exp_align = alignof (prxregset_xcr_t);
      383 +                        break;
      384 +                case PRX_INFO_XSAVE:
      385 +                        exp_size = sizeof (prxregset_xsave_t);
      386 +                        exp_align = alignof (prxregset_xsave_t);
      387 +                        break;
      388 +                case PRX_INFO_YMM:
      389 +                        exp_size = sizeof (prxregset_ymm_t);
      390 +                        exp_align = alignof (prxregset_ymm_t);
      391 +                        break;
      392 +                case PRX_INFO_OPMASK:
      393 +                        exp_size = sizeof (prxregset_opmask_t);
      394 +                        exp_align = alignof (prxregset_opmask_t);
      395 +                        break;
      396 +                case PRX_INFO_ZMM:
      397 +                        exp_size = sizeof (prxregset_zmm_t);
      398 +                        exp_align = alignof (prxregset_zmm_t);
      399 +                        break;
      400 +                case PRX_INFO_HI_ZMM:
      401 +                        exp_size = sizeof (prxregset_hi_zmm_t);
      402 +                        exp_align = alignof (prxregset_hi_zmm_t);
      403 +                        break;
      404 +                default:
      405 +                        return (EINVAL);
      406 +                }
      407 +
      408 +                if (info->pri_flags != 0 || info->pri_size != exp_size) {
      409 +                        return (EINVAL);
      410 +                }
      411 +
      412 +                if ((info->pri_offset % exp_align) != 0) {
      413 +                        return (EINVAL);
      414 +                }
      415 +
      416 +                /*
      417 +                 * No bytes of this item's entry should overlap with the
      418 +                 * information area. If users want to overlap the actual data
      419 +                 * information for some odd reason, we don't check that and let
      420 +                 * them do what they want. However, the total data for this
      421 +                 * region must actually fit. Because exp_size and pri_offset are
      422 +                 * uint32_t's, we can sum them without overflow worries in an
      423 +                 * LP64 environment.
      424 +                 *
      425 +                 * While we try to grantee alignment when writing this structure
      426 +                 * out to userland, that is in no way a requirement and users
      427 +                 * are allowed to start these structures wherever they want.
      428 +                 * Hence that is not checked here.
      429 +                 */
      430 +                need_len = (size_t)exp_size + (size_t)info->pri_offset;
      431 +                if (info->pri_offset < infosz ||
      432 +                    need_len > (size_t)hdr->pr_size) {
      433 +                        return (EINVAL);
      434 +                }
      435 +        }
      436 +
      437 +        return (fpu_proc_xregs_set(lwp, prx));
 276  438  }
 277  439  
 278  440  /*
 279  441   * Return the base (lower limit) of the process stack.
 280  442   */
 281  443  caddr_t
 282  444  prgetstackbase(proc_t *p)
 283  445  {
 284  446          return (p->p_usrstack - p->p_stksize);
 285  447  }
 286  448  
 287  449  /*
 288  450   * Return the "addr" field for pr_addr in prpsinfo_t.
 289  451   * This is a vestige of the past, so whatever we return is OK.
 290  452   */
 291  453  caddr_t
 292  454  prgetpsaddr(proc_t *p)
 293  455  {
 294  456          return ((caddr_t)p);
 295  457  }
 296  458  
 297  459  /*
 298  460   * Arrange to single-step the lwp.
 299  461   */
 300  462  void
 301  463  prstep(klwp_t *lwp, int watchstep)
 302  464  {
 303  465          ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
 304  466  
 305  467          /*
 306  468           * flag LWP so that its r_efl trace bit (PS_T) will be set on
 307  469           * next return to usermode.
 308  470           */
 309  471          lwp->lwp_pcb.pcb_flags |= REQUEST_STEP;
 310  472          lwp->lwp_pcb.pcb_flags &= ~REQUEST_NOSTEP;
 311  473  
 312  474          if (watchstep)
 313  475                  lwp->lwp_pcb.pcb_flags |= WATCH_STEP;
 314  476          else
 315  477                  lwp->lwp_pcb.pcb_flags |= NORMAL_STEP;
 316  478  
 317  479          aston(lwptot(lwp));     /* let trap() set PS_T in rp->r_efl */
 318  480  }
 319  481  
 320  482  /*
 321  483   * Undo prstep().
 322  484   */
 323  485  void
 324  486  prnostep(klwp_t *lwp)
 325  487  {
 326  488          ASSERT(ttolwp(curthread) == lwp ||
 327  489              MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
 328  490  
 329  491          /*
 330  492           * flag LWP so that its r_efl trace bit (PS_T) will be cleared on
 331  493           * next return to usermode.
 332  494           */
 333  495          lwp->lwp_pcb.pcb_flags |= REQUEST_NOSTEP;
 334  496  
 335  497          lwp->lwp_pcb.pcb_flags &=
 336  498              ~(REQUEST_STEP|NORMAL_STEP|WATCH_STEP|DEBUG_PENDING);
 337  499  
 338  500          aston(lwptot(lwp));     /* let trap() clear PS_T in rp->r_efl */
 339  501  }
 340  502  
 341  503  /*
 342  504   * Return non-zero if a single-step is in effect.
 343  505   */
 344  506  int
 345  507  prisstep(klwp_t *lwp)
 346  508  {
 347  509          ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
 348  510  
 349  511          return ((lwp->lwp_pcb.pcb_flags &
 350  512              (NORMAL_STEP|WATCH_STEP|DEBUG_PENDING)) != 0);
 351  513  }
 352  514  
 353  515  /*
 354  516   * Set the PC to the specified virtual address.
 355  517   */
 356  518  void
 357  519  prsvaddr(klwp_t *lwp, caddr_t vaddr)
 358  520  {
 359  521          struct regs *r = lwptoregs(lwp);
 360  522  
 361  523          ASSERT(MUTEX_NOT_HELD(&lwptoproc(lwp)->p_lock));
 362  524  
 363  525          r->r_pc = (uintptr_t)vaddr;
 364  526  }
 365  527  
 366  528  /*
 367  529   * Map address "addr" in address space "as" into a kernel virtual address.
 368  530   * The memory is guaranteed to be resident and locked down.
 369  531   */
 370  532  caddr_t
 371  533  prmapin(struct as *as, caddr_t addr, int writing)
 372  534  {
 373  535          page_t *pp;
 374  536          caddr_t kaddr;
 375  537          pfn_t pfnum;
 376  538  
 377  539          /*
 378  540           * XXX - Because of past mistakes, we have bits being returned
 379  541           * by getpfnum that are actually the page type bits of the pte.
 380  542           * When the object we are trying to map is a memory page with
 381  543           * a page structure everything is ok and we can use the optimal
 382  544           * method, ppmapin.  Otherwise, we have to do something special.
 383  545           */
 384  546          pfnum = hat_getpfnum(as->a_hat, addr);
 385  547          if (pf_is_memory(pfnum)) {
 386  548                  pp = page_numtopp_nolock(pfnum);
 387  549                  if (pp != NULL) {
 388  550                          ASSERT(PAGE_LOCKED(pp));
 389  551                          kaddr = ppmapin(pp, writing ?
 390  552                              (PROT_READ | PROT_WRITE) : PROT_READ, (caddr_t)-1);
 391  553                          return (kaddr + ((uintptr_t)addr & PAGEOFFSET));
 392  554                  }
 393  555          }
 394  556  
 395  557          /*
 396  558           * Oh well, we didn't have a page struct for the object we were
 397  559           * trying to map in; ppmapin doesn't handle devices, but allocating a
 398  560           * heap address allows ppmapout to free virtual space when done.
 399  561           */
 400  562          kaddr = vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);
 401  563  
 402  564          hat_devload(kas.a_hat, kaddr, MMU_PAGESIZE,  pfnum,
 403  565              writing ? (PROT_READ | PROT_WRITE) : PROT_READ, 0);
 404  566  
 405  567          return (kaddr + ((uintptr_t)addr & PAGEOFFSET));
 406  568  }
 407  569  
 408  570  /*
 409  571   * Unmap address "addr" in address space "as"; inverse of prmapin().
 410  572   */
 411  573  /* ARGSUSED */
 412  574  void
 413  575  prmapout(struct as *as, caddr_t addr, caddr_t vaddr, int writing)
 414  576  {
 415  577          extern void ppmapout(caddr_t);
 416  578  
 417  579          vaddr = (caddr_t)((uintptr_t)vaddr & PAGEMASK);
 418  580          ppmapout(vaddr);
 419  581  }
 420  582  
 421  583  /*
 422  584   * Make sure the lwp is in an orderly state
 423  585   * for inspection by a debugger through /proc.
 424  586   *
 425  587   * This needs to be called only once while the current thread remains in the
 426  588   * kernel and needs to be called while holding no resources (mutex locks, etc).
 427  589   *
 428  590   * As a hedge against these conditions, if prstop() is called repeatedly
 429  591   * before prunstop() is called, it does nothing and just returns.
 430  592   *
 431  593   * prunstop() must be called before the thread returns to user level.
 432  594   */
 433  595  /* ARGSUSED */
 434  596  void
 435  597  prstop(int why, int what)
 436  598  {
 437  599          klwp_t *lwp = ttolwp(curthread);
 438  600          struct regs *r = lwptoregs(lwp);
 439  601  
 440  602          if (lwp->lwp_pcb.pcb_flags & PRSTOP_CALLED)
 441  603                  return;
 442  604  
 443  605          /*
 444  606           * Make sure we don't deadlock on a recursive call
 445  607           * to prstop().  stop() tests the lwp_nostop flag.
 446  608           */
 447  609          ASSERT(lwp->lwp_nostop == 0);
 448  610          lwp->lwp_nostop = 1;
 449  611  
 450  612          if (copyin_nowatch((caddr_t)r->r_pc, &lwp->lwp_pcb.pcb_instr,
 451  613              sizeof (lwp->lwp_pcb.pcb_instr)) == 0)
 452  614                  lwp->lwp_pcb.pcb_flags |= INSTR_VALID;
 453  615          else {
 454  616                  lwp->lwp_pcb.pcb_flags &= ~INSTR_VALID;
 455  617                  lwp->lwp_pcb.pcb_instr = 0;
 456  618          }
 457  619  
 458  620          (void) save_syscall_args();
 459  621          ASSERT(lwp->lwp_nostop == 1);
 460  622          lwp->lwp_nostop = 0;
 461  623  
 462  624          lwp->lwp_pcb.pcb_flags |= PRSTOP_CALLED;
 463  625          aston(curthread);       /* so prunstop() will be called */
 464  626  }
 465  627  
 466  628  /*
 467  629   * Inform prstop() that it should do its work again
 468  630   * the next time it is called.
 469  631   */
 470  632  void
 471  633  prunstop(void)
 472  634  {
 473  635          ttolwp(curthread)->lwp_pcb.pcb_flags &= ~PRSTOP_CALLED;
 474  636  }
 475  637  
 476  638  /*
 477  639   * Fetch the user-level instruction on which the lwp is stopped.
 478  640   * It was saved by the lwp itself, in prstop().
 479  641   * Return non-zero if the instruction is valid.
 480  642   */
 481  643  int
 482  644  prfetchinstr(klwp_t *lwp, ulong_t *ip)
 483  645  {
 484  646          *ip = (ulong_t)(instr_t)lwp->lwp_pcb.pcb_instr;
 485  647          return (lwp->lwp_pcb.pcb_flags & INSTR_VALID);
 486  648  }
 487  649  
 488  650  /*
 489  651   * Called from trap() when a load or store instruction
 490  652   * falls in a watched page but is not a watchpoint.
 491  653   * We emulate the instruction in the kernel.
 492  654   */
 493  655  /* ARGSUSED */
 494  656  int
 495  657  pr_watch_emul(struct regs *rp, caddr_t addr, enum seg_rw rw)
 496  658  {
 497  659  #ifdef SOMEDAY
 498  660          int res;
 499  661          proc_t *p = curproc;
 500  662          char *badaddr = (caddr_t)(-1);
 501  663          int mapped;
 502  664  
 503  665          /* prevent recursive calls to pr_watch_emul() */
 504  666          ASSERT(!(curthread->t_flag & T_WATCHPT));
 505  667          curthread->t_flag |= T_WATCHPT;
 506  668  
 507  669          watch_disable_addr(addr, 8, rw);
 508  670          res = do_unaligned(rp, &badaddr);
 509  671          watch_enable_addr(addr, 8, rw);
 510  672  
 511  673          curthread->t_flag &= ~T_WATCHPT;
 512  674          if (res == SIMU_SUCCESS) {
 513  675                  /* adjust the pc */
 514  676                  return (1);
 515  677          }
 516  678  #endif
 517  679          return (0);
 518  680  }
 519  681  
 520  682  /*
 521  683   * Return the number of active entries in the local descriptor table.
 522  684   */
 523  685  int
 524  686  prnldt(proc_t *p)
 525  687  {
 526  688          int limit, i, n;
 527  689          user_desc_t *udp;
 528  690  
 529  691          ASSERT(MUTEX_HELD(&p->p_ldtlock));
 530  692  
 531  693          /*
 532  694           * Currently 64 bit processes cannot have private LDTs.
 533  695           */
 534  696          ASSERT(p->p_model != DATAMODEL_LP64 || p->p_ldt == NULL);
 535  697  
 536  698          if (p->p_ldt == NULL)
 537  699                  return (0);
 538  700          n = 0;
 539  701          limit = p->p_ldtlimit;
 540  702          ASSERT(limit >= 0 && limit < MAXNLDT);
 541  703  
 542  704          /*
 543  705           * Count all present user descriptors.
 544  706           */
 545  707          for (i = LDT_UDBASE, udp = &p->p_ldt[i]; i <= limit; i++, udp++)
 546  708                  if (udp->usd_type != 0 || udp->usd_dpl != 0 || udp->usd_p != 0)
 547  709                          n++;
 548  710          return (n);
 549  711  }
 550  712  
 551  713  /*
 552  714   * Fetch the active entries from the local descriptor table.
 553  715   */
 554  716  void
 555  717  prgetldt(proc_t *p, struct ssd *ssd)
 556  718  {
 557  719          int i, limit;
 558  720          user_desc_t *udp;
 559  721  
 560  722          ASSERT(MUTEX_HELD(&p->p_ldtlock));
 561  723  
 562  724          if (p->p_ldt == NULL)
 563  725                  return;
 564  726  
 565  727          limit = p->p_ldtlimit;
 566  728          ASSERT(limit >= 0 && limit < MAXNLDT);
 567  729  
 568  730          /*
 569  731           * All present user descriptors.
 570  732           */
 571  733          for (i = LDT_UDBASE, udp = &p->p_ldt[i]; i <= limit; i++, udp++)
 572  734                  if (udp->usd_type != 0 || udp->usd_dpl != 0 ||
 573  735                      udp->usd_p != 0)
 574  736                          usd_to_ssd(udp, ssd++, SEL_LDT(i));
 575  737  }
  
    | 
      ↓ open down ↓ | 
    290 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX