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>
        
*** 18,27 ****
--- 18,30 ----
   *
   * CDDL HEADER END
   */
  
  /*
+  * Copyright 2015 Joyent, Inc.
+  */
+ /*
   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
   * Use is subject to license terms.
   */
  
  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
*** 44,53 ****
--- 47,57 ----
  #include <sys/errno.h>
  #include <sys/archsystm.h>
  #include <sys/schedctl.h>
  #include <sys/debug.h>
  #include <sys/sysmacros.h>
+ #include <sys/sdt.h>
  
  /*
   * Save user context.
   */
  void
*** 123,133 ****
--- 127,153 ----
          if (lwp->lwp_pcb.pcb_fpu.fpu_flags & FPU_EN)
                  getfpregs(lwp, &ucp->uc_mcontext.fpregs);
          else
                  ucp->uc_flags &= ~UC_FPU;
  
+         if (mask != NULL) {
+                 /*
+                  * Save signal mask.
+                  */
                  sigktou(mask, &ucp->uc_sigmask);
+         } else {
+                 ucp->uc_flags &= ~UC_SIGMASK;
+                 bzero(&ucp->uc_sigmask, sizeof (ucp->uc_sigmask));
+         }
+ 
+         if (PROC_IS_BRANDED(p) && BROP(p)->b_savecontext != NULL) {
+                 /*
+                  * Allow the brand the chance to modify the context we
+                  * saved:
+                  */
+                 BROP(p)->b_savecontext(ucp);
+         }
  }
  
  /*
   * Restore user context.
   */
*** 134,144 ****
--- 154,176 ----
  void
  restorecontext(ucontext_t *ucp)
  {
          kthread_t *t = curthread;
          klwp_t *lwp = ttolwp(t);
+         proc_t *p = lwptoproc(lwp);
  
+         if (PROC_IS_BRANDED(p) && BROP(p)->b_restorecontext != NULL) {
+                 /*
+                  * Allow the brand the chance to modify the context before
+                  * we restore it:
+                  */
+                 BROP(p)->b_restorecontext(ucp);
+         }
+ 
+         DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+             uintptr_t, lwp->lwp_oldcontext,
+             uintptr_t, (uintptr_t)ucp->uc_link);
          lwp->lwp_oldcontext = (uintptr_t)ucp->uc_link;
  
          if (ucp->uc_flags & UC_STACK) {
                  if (ucp->uc_stack.ss_flags == SS_ONSTACK)
                          lwp->lwp_sigaltstack = ucp->uc_stack;
*** 182,191 ****
--- 214,224 ----
  {
          ucontext_t uc;
          ucontext_t *ucp;
          klwp_t *lwp = ttolwp(curthread);
          stack_t dummy_stk;
+         proc_t *p = lwptoproc(lwp);
  
          /*
           * In future releases, when the ucontext structure grows,
           * getcontext should be modified to only return the fields
           * specified in the uc_flags.  That way, the structure can grow
*** 226,235 ****
--- 259,277 ----
                      copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs,
                      sizeof (uc.uc_mcontext.fpregs))) {
                          return (set_errno(EFAULT));
                  }
  
+                 /*
+                  * If this is a branded process, copy in the brand-private
+                  * data:
+                  */
+                 if (PROC_IS_BRANDED(p) && copyin(&ucp->uc_brand_data,
+                     &uc.uc_brand_data, sizeof (uc.uc_brand_data)) != 0) {
+                         return (set_errno(EFAULT));
+                 }
+ 
                  restorecontext(&uc);
  
                  if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))
                          (void) copyout(&uc.uc_stack, (stack_t *)lwp->lwp_ustack,
                              sizeof (uc.uc_stack));
*** 309,319 ****
--- 351,377 ----
          if (lwp->lwp_pcb.pcb_fpu.fpu_flags & FPU_EN)
                  getfpregs32(lwp, &ucp->uc_mcontext.fpregs);
          else
                  ucp->uc_flags &= ~UC_FPU;
  
+         if (mask != NULL) {
+                 /*
+                  * Save signal mask.
+                  */
                  sigktou(mask, &ucp->uc_sigmask);
+         } else {
+                 ucp->uc_flags &= ~UC_SIGMASK;
+                 bzero(&ucp->uc_sigmask, sizeof (ucp->uc_sigmask));
+         }
+ 
+         if (PROC_IS_BRANDED(p) && BROP(p)->b_savecontext32 != NULL) {
+                 /*
+                  * Allow the brand the chance to modify the context we
+                  * saved:
+                  */
+                 BROP(p)->b_savecontext32(ucp);
+         }
  }
  
  int
  getsetcontext32(int flag, void *arg)
  {
*** 321,330 ****
--- 379,389 ----
          ucontext_t ucnat;
          ucontext32_t *ucp;
          klwp_t *lwp = ttolwp(curthread);
          caddr32_t ustack32;
          stack32_t dummy_stk32;
+         proc_t *p = lwptoproc(lwp);
  
          switch (flag) {
          default:
                  return (set_errno(EINVAL));
  
*** 351,360 ****
--- 410,428 ----
                  if ((uc.uc_flags & UC_FPU) &&
                      copyin(&ucp->uc_mcontext.fpregs, &uc.uc_mcontext.fpregs,
                      sizeof (uc.uc_mcontext.fpregs))) {
                          return (set_errno(EFAULT));
                  }
+ 
+                 /*
+                  * If this is a branded process, copy in the brand-private
+                  * data:
+                  */
+                 if (PROC_IS_BRANDED(p) && copyin(&ucp->uc_brand_data,
+                     &uc.uc_brand_data, sizeof (uc.uc_brand_data)) != 0) {
+                         return (set_errno(EFAULT));
+                 }
  
                  ucontext_32ton(&uc, &ucnat);
                  restorecontext(&ucnat);
  
                  if ((uc.uc_flags & UC_STACK) && (lwp->lwp_ustack != 0))