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. */