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))