summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/syscall/getcontext.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/intel/syscall/getcontext.c')
-rw-r--r--usr/src/uts/intel/syscall/getcontext.c72
1 files changed, 70 insertions, 2 deletions
diff --git a/usr/src/uts/intel/syscall/getcontext.c b/usr/src/uts/intel/syscall/getcontext.c
index f7c404ba72..a210448dc3 100644
--- a/usr/src/uts/intel/syscall/getcontext.c
+++ b/usr/src/uts/intel/syscall/getcontext.c
@@ -20,6 +20,9 @@
*/
/*
+ * Copyright 2015 Joyent, Inc.
+ */
+/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,6 +49,7 @@
#include <sys/schedctl.h>
#include <sys/debug.h>
#include <sys/sysmacros.h>
+#include <sys/sdt.h>
/*
* Save user context.
@@ -125,7 +129,23 @@ savecontext(ucontext_t *ucp, const k_sigset_t *mask)
else
ucp->uc_flags &= ~UC_FPU;
- sigktou(mask, &ucp->uc_sigmask);
+ 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);
+ }
}
/*
@@ -136,7 +156,19 @@ 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) {
@@ -184,6 +216,7 @@ getsetcontext(int flag, void *arg)
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,
@@ -228,6 +261,15 @@ getsetcontext(int flag, void *arg)
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))
@@ -311,7 +353,23 @@ savecontext32(ucontext32_t *ucp, const k_sigset_t *mask)
else
ucp->uc_flags &= ~UC_FPU;
- sigktou(mask, &ucp->uc_sigmask);
+ 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
@@ -323,6 +381,7 @@ getsetcontext32(int flag, void *arg)
klwp_t *lwp = ttolwp(curthread);
caddr32_t ustack32;
stack32_t dummy_stk32;
+ proc_t *p = lwptoproc(lwp);
switch (flag) {
default:
@@ -354,6 +413,15 @@ getsetcontext32(int flag, void *arg)
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);