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