Print this page
*** 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 */
*** 48,57 ****
--- 51,61 ----
#include <sys/errno.h>
#include <sys/archsystm.h>
#include <sys/schedctl.h>
#include <sys/debug.h>
#include <sys/sysmacros.h>
+ #include <sys/sdt.h>
/*
* This is a wrapper around copyout_noerr that returns a guaranteed error code.
* Because we're using copyout_noerr(), we need to bound the time we're under an
* on_fault/no_fault and attempt to do so only while we're actually copying data
*** 189,199 ****
--- 193,211 ----
if (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));
+ }
/*
* Determine if we need to get the reset of the xsave context out here.
* If the thread doesn't actually have the FPU enabled, then we don't
* actually need to do this. We also don't have to if it wasn't
*** 218,227 ****
--- 230,248 ----
savecontext_copyout);
} else {
ret = fpu_signal_copyout(lwp, ucp->uc_xsave, copyout);
}
+ if (PROC_IS_BRANDED(p) && BROP(p)->b_savecontext != NULL) {
+ /*
+ * Allow the brand the chance to modify the context we
+ * saved:
+ */
+ /* XXX KEBE SAYS FIX ME! */
+ BROP(p)->b_savecontext(ucp);
+ }
+
return (ret);
}
/*
* Restore user context.
*** 229,239 ****
--- 250,272 ----
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;
*** 288,297 ****
--- 321,331 ----
ucontext_t uc;
ucontext_t *ucp;
klwp_t *lwp = ttolwp(curthread);
void *fpu = NULL;
stack_t dummy_stk;
+ proc_t *p = lwptoproc(lwp);
int ret;
/*
* In future releases, when the ucontext structure grows,
* getcontext should be modified to only return the fields
*** 352,362 ****
exit(CLD_EXITED, 0);
/*
* Don't copyin filler or floating state unless we need it.
* The ucontext_t struct and fields are specified in the ABI.
*/
! if (copyin(ucp, &uc, offsetof(ucontext_t, uc_filler) -
sizeof (uc.uc_mcontext.fpregs))) {
return (set_errno(EFAULT));
}
if (uc.uc_flags & UC_SIGMASK)
SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
--- 386,396 ----
exit(CLD_EXITED, 0);
/*
* Don't copyin filler or floating state unless we need it.
* The ucontext_t struct and fields are specified in the ABI.
*/
! if (copyin(ucp, &uc, offsetof(ucontext_t, uc_brand_data) -
sizeof (uc.uc_mcontext.fpregs))) {
return (set_errno(EFAULT));
}
if (uc.uc_flags & UC_SIGMASK)
SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
*** 365,374 ****
--- 399,417 ----
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));
+ }
+
uc.uc_xsave = 0;
if ((uc.uc_flags & UC_XSAVE) != 0) {
int ret;
if (copyin(&ucp->uc_xsave, &uc.uc_xsave,
*** 482,492 ****
--- 525,543 ----
if (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 (!need_xsave || !fpu_en) {
return (0);
}
*** 505,514 ****
--- 556,575 ----
ret = fpu_signal_copyout(lwp, uaddr, savecontext_copyout);
} else {
ret = fpu_signal_copyout(lwp, uaddr, copyout);
}
+
+ if (PROC_IS_BRANDED(p) && BROP(p)->b_savecontext32 != NULL) {
+ /*
+ * Allow the brand the chance to modify the context we
+ * saved:
+ */
+ /* XXX KEBE SAYS FIX ME */
+ BROP(p)->b_savecontext32(ucp);
+ }
+
return (ret);
}
int
getsetcontext32(int flag, void *arg)
*** 517,526 ****
--- 578,588 ----
ucontext_t ucnat;
ucontext32_t *ucp;
klwp_t *lwp = ttolwp(curthread);
caddr32_t ustack32;
stack32_t dummy_stk32;
+ proc_t *p = lwptoproc(lwp);
int ret;
switch (flag) {
default:
return (set_errno(EINVAL));
*** 557,567 ****
case SETCONTEXT:
ucp = arg;
if (ucp == NULL)
exit(CLD_EXITED, 0);
! if (copyin(ucp, &uc, offsetof(ucontext32_t, uc_filler) -
sizeof (uc.uc_mcontext.fpregs))) {
return (set_errno(EFAULT));
}
if (uc.uc_flags & UC_SIGMASK)
SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
--- 619,629 ----
case SETCONTEXT:
ucp = arg;
if (ucp == NULL)
exit(CLD_EXITED, 0);
! if (copyin(ucp, &uc, offsetof(ucontext32_t, uc_brand_data) -
sizeof (uc.uc_mcontext.fpregs))) {
return (set_errno(EFAULT));
}
if (uc.uc_flags & UC_SIGMASK)
SIGSET_BRAND_TO_NATIVE(&uc.uc_sigmask);
*** 568,577 ****
--- 630,648 ----
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));
+ }
uc.uc_xsave = 0;
if ((uc.uc_flags & UC_XSAVE) != 0 &&
copyin(&ucp->uc_xsave, &uc.uc_xsave,
sizeof (uc.uc_xsave)) != 0) {