Print this page
OS-3561 lxbrand emulation library should execute on alternate stack
OS-3558 lxbrand add support for full in-kernel syscall handling
OS-3545 lx_syscall_regs should not walk stack
OS-3868 many LTP testcases now hang
OS-3901 lxbrand lx_recvmsg fails to translate control messages when 64-bit
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Bryan Cantrill <bryan@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/intel/ia32/syscall/getcontext.c
          +++ new/usr/src/uts/intel/ia32/syscall/getcontext.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  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  
  22   22  /*
       23 + * Copyright 2015 Joyent, Inc.
       24 + */
       25 +/*
  23   26   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   27   * Use is subject to license terms.
  25   28   */
  26   29  
  27   30  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  28   31  /*        All Rights Reserved   */
  29   32  
  30   33  #include <sys/param.h>
  31   34  #include <sys/types.h>
  32   35  #include <sys/vmparam.h>
↓ open down ↓ 6 lines elided ↑ open up ↑
  39   42  #include <sys/proc.h>
  40   43  #include <sys/brand.h>
  41   44  #include <sys/psw.h>
  42   45  #include <sys/ucontext.h>
  43   46  #include <sys/asm_linkage.h>
  44   47  #include <sys/errno.h>
  45   48  #include <sys/archsystm.h>
  46   49  #include <sys/schedctl.h>
  47   50  #include <sys/debug.h>
  48   51  #include <sys/sysmacros.h>
       52 +#include <sys/sdt.h>
  49   53  
  50   54  /*
  51   55   * Save user context.
  52   56   */
  53   57  void
  54   58  savecontext(ucontext_t *ucp, const k_sigset_t *mask)
  55   59  {
  56   60          proc_t *p = ttoproc(curthread);
  57   61          klwp_t *lwp = ttolwp(curthread);
  58   62          struct regs *rp = lwptoregs(lwp);
↓ open down ↓ 59 lines elided ↑ open up ↑
 118  122                          aston(curthread);
 119  123                  }
 120  124          }
 121  125  
 122  126          getgregs(lwp, ucp->uc_mcontext.gregs);
 123  127          if (lwp->lwp_pcb.pcb_fpu.fpu_flags & FPU_EN)
 124  128                  getfpregs(lwp, &ucp->uc_mcontext.fpregs);
 125  129          else
 126  130                  ucp->uc_flags &= ~UC_FPU;
 127  131  
 128      -        sigktou(mask, &ucp->uc_sigmask);
      132 +        if (mask != NULL) {
      133 +                /*
      134 +                 * Save signal mask.
      135 +                 */
      136 +                sigktou(mask, &ucp->uc_sigmask);
      137 +        } else {
      138 +                ucp->uc_flags &= ~UC_SIGMASK;
      139 +                bzero(&ucp->uc_sigmask, sizeof (ucp->uc_sigmask));
      140 +        }
      141 +
      142 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_savecontext != NULL) {
      143 +                /*
      144 +                 * Allow the brand the chance to modify the context we
      145 +                 * saved:
      146 +                 */
      147 +                BROP(p)->b_savecontext(ucp);
      148 +        }
 129  149  }
 130  150  
 131  151  /*
 132  152   * Restore user context.
 133  153   */
 134  154  void
 135  155  restorecontext(ucontext_t *ucp)
 136  156  {
 137  157          kthread_t *t = curthread;
 138  158          klwp_t *lwp = ttolwp(t);
      159 +        proc_t *p = lwptoproc(lwp);
 139  160  
      161 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_restorecontext != NULL) {
      162 +                /*
      163 +                 * Allow the brand the chance to modify the context before
      164 +                 * we restore it:
      165 +                 */
      166 +                BROP(p)->b_restorecontext(ucp);
      167 +        }
      168 +
      169 +        DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
      170 +            uintptr_t, lwp->lwp_oldcontext,
      171 +            uintptr_t, (uintptr_t)ucp->uc_link);
 140  172          lwp->lwp_oldcontext = (uintptr_t)ucp->uc_link;
 141  173  
 142  174          if (ucp->uc_flags & UC_STACK) {
 143  175                  if (ucp->uc_stack.ss_flags == SS_ONSTACK)
 144  176                          lwp->lwp_sigaltstack = ucp->uc_stack;
 145  177                  else
 146  178                          lwp->lwp_sigaltstack.ss_flags &= ~SS_ONSTACK;
 147  179          }
 148  180  
 149  181          if (ucp->uc_flags & UC_CPU) {
↓ open down ↓ 27 lines elided ↑ open up ↑
 177  209  }
 178  210  
 179  211  
 180  212  int
 181  213  getsetcontext(int flag, void *arg)
 182  214  {
 183  215          ucontext_t uc;
 184  216          ucontext_t *ucp;
 185  217          klwp_t *lwp = ttolwp(curthread);
 186  218          stack_t dummy_stk;
      219 +        proc_t *p = lwptoproc(lwp);
 187  220  
 188  221          /*
 189  222           * In future releases, when the ucontext structure grows,
 190  223           * getcontext should be modified to only return the fields
 191  224           * specified in the uc_flags.  That way, the structure can grow
 192  225           * and still be binary compatible will all .o's which will only
 193  226           * have old fields defined in uc_flags
 194  227           */
 195  228  
 196  229          switch (flag) {
↓ open down ↓ 24 lines elided ↑ open up ↑
 221  254                  }
 222  255                  if (uc.uc_flags & UC_SIGMASK)
 223  256                          SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
 224  257  
 225  258                  if ((uc.uc_flags & UC_FPU) &&
 226  259                      copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs,
 227  260                      sizeof (uc.uc_mcontext.fpregs))) {
 228  261                          return (set_errno(EFAULT));
 229  262                  }
 230  263  
      264 +                /*
      265 +                 * If this is a branded process, copy in the brand-private
      266 +                 * data:
      267 +                 */
      268 +                if (PROC_IS_BRANDED(p) && copyin(&ucp->uc_brand_data,
      269 +                    &uc.uc_brand_data, sizeof (uc.uc_brand_data)) != 0) {
      270 +                        return (set_errno(EFAULT));
      271 +                }
      272 +
 231  273                  restorecontext(&uc);
 232  274  
 233  275                  if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))
 234  276                          (void) copyout(&uc.uc_stack, (stack_t *)lwp->lwp_ustack,
 235  277                              sizeof (uc.uc_stack));
 236  278                  return (0);
 237  279  
 238  280          case GETUSTACK:
 239  281                  if (copyout(&lwp->lwp_ustack, arg, sizeof (caddr_t)))
 240  282                          return (set_errno(EFAULT));
↓ open down ↓ 63 lines elided ↑ open up ↑
 304  346                          aston(curthread);
 305  347                  }
 306  348          }
 307  349  
 308  350          getgregs32(lwp, ucp->uc_mcontext.gregs);
 309  351          if (lwp->lwp_pcb.pcb_fpu.fpu_flags & FPU_EN)
 310  352                  getfpregs32(lwp, &ucp->uc_mcontext.fpregs);
 311  353          else
 312  354                  ucp->uc_flags &= ~UC_FPU;
 313  355  
 314      -        sigktou(mask, &ucp->uc_sigmask);
      356 +        if (mask != NULL) {
      357 +                /*
      358 +                 * Save signal mask.
      359 +                 */
      360 +                sigktou(mask, &ucp->uc_sigmask);
      361 +        } else {
      362 +                ucp->uc_flags &= ~UC_SIGMASK;
      363 +                bzero(&ucp->uc_sigmask, sizeof (ucp->uc_sigmask));
      364 +        }
      365 +
      366 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_savecontext32 != NULL) {
      367 +                /*
      368 +                 * Allow the brand the chance to modify the context we
      369 +                 * saved:
      370 +                 */
      371 +                BROP(p)->b_savecontext32(ucp);
      372 +        }
 315  373  }
 316  374  
 317  375  int
 318  376  getsetcontext32(int flag, void *arg)
 319  377  {
 320  378          ucontext32_t uc;
 321  379          ucontext_t ucnat;
 322  380          ucontext32_t *ucp;
 323  381          klwp_t *lwp = ttolwp(curthread);
 324  382          caddr32_t ustack32;
 325  383          stack32_t dummy_stk32;
      384 +        proc_t *p = lwptoproc(lwp);
 326  385  
 327  386          switch (flag) {
 328  387          default:
 329  388                  return (set_errno(EINVAL));
 330  389  
 331  390          case GETCONTEXT:
 332  391                  schedctl_finish_sigblock(curthread);
 333  392                  savecontext32(&uc, &curthread->t_hold);
 334  393                  if (uc.uc_flags & UC_SIGMASK)
 335  394                          SIGSET_NATIVE_TO_BRAND(&uc.uc_sigmask);
↓ open down ↓ 10 lines elided ↑ open up ↑
 346  405                      sizeof (uc.uc_mcontext.fpregs))) {
 347  406                          return (set_errno(EFAULT));
 348  407                  }
 349  408                  if (uc.uc_flags & UC_SIGMASK)
 350  409                          SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
 351  410                  if ((uc.uc_flags & UC_FPU) &&
 352  411                      copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs,
 353  412                      sizeof (uc.uc_mcontext.fpregs))) {
 354  413                          return (set_errno(EFAULT));
 355  414                  }
      415 +
      416 +                /*
      417 +                 * If this is a branded process, copy in the brand-private
      418 +                 * data:
      419 +                 */
      420 +                if (PROC_IS_BRANDED(p) && copyin(&ucp->uc_brand_data,
      421 +                    &uc.uc_brand_data, sizeof (uc.uc_brand_data)) != 0) {
      422 +                        return (set_errno(EFAULT));
      423 +                }
 356  424  
 357  425                  ucontext_32ton(&uc, &ucnat);
 358  426                  restorecontext(&ucnat);
 359  427  
 360  428                  if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))
 361  429                          (void) copyout(&uc.uc_stack,
 362  430                              (stack32_t *)lwp->lwp_ustack, sizeof (uc.uc_stack));
 363  431                  return (0);
 364  432  
 365  433          case GETUSTACK:
↓ open down ↓ 14 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX