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) 1990, 1991 UNIX System Laboratories, Inc. */
*** 85,94 ****
--- 88,99 ----
  #include <sys/promif.h>
  #include <sys/systeminfo.h>
  #include <sys/kdi.h>
  #include <sys/contract_impl.h>
  #include <sys/x86_archext.h>
+ #include <sys/brand.h>
+ #include <sys/sdt.h>
  
  /*
   * Construct the execution environment for the user's signal
   * handler and arrange for control to be given to it on return
   * to userland.  The library code now calls setcontext() to
*** 184,194 ****
           * context.  on_fault will catch any faults.
           */
          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
  
!         if (newstack) {
                  fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
                      SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
          } else {
                  /*
                   * Drop below the 128-byte reserved region of the stack frame
--- 189,210 ----
           * context.  on_fault will catch any faults.
           */
          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
  
!         /*
!          * If this is a branded process, the brand may provide an alternate
!          * stack pointer for signal delivery:
!          */
!         if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
!                 /*
!                  * Use the stack pointer value provided by the brand,
!                  * accounting for the 128-byte reserved region.
!                  */
!                 newstack = 0;
!                 fp = BROP(p)->b_sendsig_stack(sig) - STACK_RESERVE;
!         } else if (newstack) {
                  fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
                      SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
          } else {
                  /*
                   * Drop below the 128-byte reserved region of the stack frame
*** 294,303 ****
--- 310,321 ----
                  goto badstack;
          copyout_noerr(tuc, uc, sizeof (*tuc));
          kmem_free(tuc, sizeof (*tuc));
          tuc = NULL;
  
+         DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+             uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
          lwp->lwp_oldcontext = (uintptr_t)uc;
  
          if (newstack) {
                  lwp->lwp_sigaltstack.ss_flags |= SS_ONSTACK;
                  if (lwp->lwp_ustack)
*** 343,352 ****
--- 361,378 ----
                  rp->r_cs = UCS_SEL;
                  rp->r_ss = UDS_SEL;
          }
  
          /*
+          * Allow the brand to perform additional book-keeping once the signal
+          * handling frame has been fully assembled:
+          */
+         if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
+                 BROP(p)->b_sendsig(sig);
+         }
+ 
+         /*
           * Don't set lwp_eosys here.  sendsig() is called via psig() after
           * lwp_eosys is handled, so setting it here would affect the next
           * system call.
           */
          return (1);
*** 418,428 ****
           * context.  on_fault will catch any faults.
           */
          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
  
!         if (newstack) {
                  fp = (caddr_t)(SA32((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
                      SA32(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN32);
          } else if ((rp->r_ss & 0xffff) != UDS_SEL) {
                  user_desc_t *ldt;
                  /*
--- 444,464 ----
           * context.  on_fault will catch any faults.
           */
          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
  
!         /*
!          * If this is a branded process, the brand may provide an alternate
!          * stack pointer for signal delivery:
!          */
!         if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
!                 /*
!                  * Use the stack pointer value provided by the brand:
!                  */
!                 newstack = 0;
!                 fp = BROP(p)->b_sendsig_stack(sig);
!         } else if (newstack) {
                  fp = (caddr_t)(SA32((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
                      SA32(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN32);
          } else if ((rp->r_ss & 0xffff) != UDS_SEL) {
                  user_desc_t *ldt;
                  /*
*** 433,444 ****
                  if ((ldt = p->p_ldt) != NULL)
                          fp = (caddr_t)rp->r_sp +
                              USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
                  else
                          fp = (caddr_t)rp->r_sp;
!         } else
                  fp = (caddr_t)rp->r_sp;
  
          /*
           * Force proper stack pointer alignment, even in the face of a
           * misaligned stack pointer from user-level before the signal.
           * Don't use the SA32() macro because that rounds up, not down.
--- 469,481 ----
                  if ((ldt = p->p_ldt) != NULL)
                          fp = (caddr_t)rp->r_sp +
                              USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
                  else
                          fp = (caddr_t)rp->r_sp;
!         } else {
                  fp = (caddr_t)rp->r_sp;
+         }
  
          /*
           * Force proper stack pointer alignment, even in the face of a
           * misaligned stack pointer from user-level before the signal.
           * Don't use the SA32() macro because that rounds up, not down.
*** 515,524 ****
--- 552,563 ----
                  goto badstack;
          copyout_noerr(tuc, uc, sizeof (*tuc));
          kmem_free(tuc, sizeof (*tuc));
          tuc = NULL;
  
+         DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+             uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
          lwp->lwp_oldcontext = (uintptr_t)uc;
  
          if (newstack) {
                  lwp->lwp_sigaltstack.ss_flags |= SS_ONSTACK;
                  if (lwp->lwp_ustack) {
*** 564,573 ****
--- 603,620 ----
                  rp->r_cs = U32CS_SEL;
                  rp->r_ss = UDS_SEL;
          }
  
          /*
+          * Allow the brand to perform additional book-keeping once the signal
+          * handling frame has been fully assembled:
+          */
+         if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
+                 BROP(p)->b_sendsig(sig);
+         }
+ 
+         /*
           * Don't set lwp_eosys here.  sendsig() is called via psig() after
           * lwp_eosys is handled, so setting it here would affect the next
           * system call.
           */
          return (1);
*** 641,651 ****
           * context. on_fault will catch any faults.
           */
          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
  
!         if (newstack) {
                  fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
                      SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
          } else if ((rp->r_ss & 0xffff) != UDS_SEL) {
                  user_desc_t *ldt;
                  /*
--- 688,708 ----
           * context. on_fault will catch any faults.
           */
          newstack = sigismember(&PTOU(curproc)->u_sigonstack, sig) &&
              !(lwp->lwp_sigaltstack.ss_flags & (SS_ONSTACK|SS_DISABLE));
  
!         /*
!          * If this is a branded process, the brand may provide an alternate
!          * stack pointer for signal delivery:
!          */
!         if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig_stack != NULL) {
!                 /*
!                  * Use the stack pointer value provided by the brand:
!                  */
!                 newstack = 0;
!                 fp = BROP(p)->b_sendsig_stack(sig);
!         } else if (newstack) {
                  fp = (caddr_t)(SA((uintptr_t)lwp->lwp_sigaltstack.ss_sp) +
                      SA(lwp->lwp_sigaltstack.ss_size) - STACK_ALIGN);
          } else if ((rp->r_ss & 0xffff) != UDS_SEL) {
                  user_desc_t *ldt;
                  /*
*** 656,667 ****
                  if ((ldt = p->p_ldt) != NULL)
                          fp = (caddr_t)rp->r_sp +
                              USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
                  else
                          fp = (caddr_t)rp->r_sp;
!         } else
                  fp = (caddr_t)rp->r_sp;
  
          /*
           * Force proper stack pointer alignment, even in the face of a
           * misaligned stack pointer from user-level before the signal.
           * Don't use the SA() macro because that rounds up, not down.
--- 713,725 ----
                  if ((ldt = p->p_ldt) != NULL)
                          fp = (caddr_t)rp->r_sp +
                              USEGD_GETBASE(&ldt[SELTOIDX(rp->r_ss)]);
                  else
                          fp = (caddr_t)rp->r_sp;
!         } else {
                  fp = (caddr_t)rp->r_sp;
+         }
  
          /*
           * Force proper stack pointer alignment, even in the face of a
           * misaligned stack pointer from user-level before the signal.
           * Don't use the SA() macro because that rounds up, not down.
*** 735,744 ****
--- 793,804 ----
          savecontext(tuc, &lwp->lwp_sigoldmask);
          copyout_noerr(tuc, uc, sizeof (*tuc));
          kmem_free(tuc, sizeof (*tuc));
          tuc = NULL;
  
+         DTRACE_PROBE3(oldcontext__set, klwp_t *, lwp,
+             uintptr_t, lwp->lwp_oldcontext, uintptr_t, (uintptr_t)uc);
          lwp->lwp_oldcontext = (uintptr_t)uc;
  
          if (newstack) {
                  lwp->lwp_sigaltstack.ss_flags |= SS_ONSTACK;
                  if (lwp->lwp_ustack)
*** 771,780 ****
--- 831,848 ----
              (rp->r_ss & 0xffff) != UDS_SEL) {
                  rp->r_cs = UCS_SEL;
                  rp->r_ss = UDS_SEL;
          }
  
+         /*
+          * Allow the brand to perform additional book-keeping once the signal
+          * handling frame has been fully assembled:
+          */
+         if (PROC_IS_BRANDED(p) && BROP(p)->b_sendsig != NULL) {
+                 BROP(p)->b_sendsig(sig);
+         }
+ 
          /*
           * Don't set lwp_eosys here.  sendsig() is called via psig() after
           * lwp_eosys is handled, so setting it here would affect the next
           * system call.
           */