0baeff3d96eae184e775c1064f1836090446a7bfrab/*
0baeff3d96eae184e775c1064f1836090446a7bfrab * CDDL HEADER START
0baeff3d96eae184e775c1064f1836090446a7bfrab *
0baeff3d96eae184e775c1064f1836090446a7bfrab * The contents of this file are subject to the terms of the
0baeff3d96eae184e775c1064f1836090446a7bfrab * Common Development and Distribution License, Version 1.0 only
0baeff3d96eae184e775c1064f1836090446a7bfrab * (the "License"). You may not use this file except in compliance
0baeff3d96eae184e775c1064f1836090446a7bfrab * with the License.
0baeff3d96eae184e775c1064f1836090446a7bfrab *
0baeff3d96eae184e775c1064f1836090446a7bfrab * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0baeff3d96eae184e775c1064f1836090446a7bfrab * or http://www.opensolaris.org/os/licensing.
0baeff3d96eae184e775c1064f1836090446a7bfrab * See the License for the specific language governing permissions
0baeff3d96eae184e775c1064f1836090446a7bfrab * and limitations under the License.
0baeff3d96eae184e775c1064f1836090446a7bfrab *
0baeff3d96eae184e775c1064f1836090446a7bfrab * When distributing Covered Code, include this CDDL HEADER in each
0baeff3d96eae184e775c1064f1836090446a7bfrab * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
0baeff3d96eae184e775c1064f1836090446a7bfrab * If applicable, add the following below this CDDL HEADER, with the
0baeff3d96eae184e775c1064f1836090446a7bfrab * fields enclosed by brackets "[]" replaced with your own identifying
0baeff3d96eae184e775c1064f1836090446a7bfrab * information: Portions Copyright [yyyy] [name of copyright owner]
0baeff3d96eae184e775c1064f1836090446a7bfrab *
0baeff3d96eae184e775c1064f1836090446a7bfrab * CDDL HEADER END
0baeff3d96eae184e775c1064f1836090446a7bfrab */
0baeff3d96eae184e775c1064f1836090446a7bfrab/*
0baeff3d96eae184e775c1064f1836090446a7bfrab * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
0baeff3d96eae184e775c1064f1836090446a7bfrab * Use is subject to license terms.
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi * Copyright (c) 2013, Joyent, Inc. All rights reserved.
0baeff3d96eae184e775c1064f1836090446a7bfrab */
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab#include <sys/proc.h>
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi#include <sys/cpuvar.h>
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi#include <sys/disp.h>
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab/*
0baeff3d96eae184e775c1064f1836090446a7bfrab * Install process context ops for the current process.
0baeff3d96eae184e775c1064f1836090446a7bfrab */
0baeff3d96eae184e775c1064f1836090446a7bfrabvoid
0baeff3d96eae184e775c1064f1836090446a7bfrabinstallpctx(
0baeff3d96eae184e775c1064f1836090446a7bfrab proc_t *p,
0baeff3d96eae184e775c1064f1836090446a7bfrab void *arg,
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*save)(void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*restore)(void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*fork)(void *, void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*exit)(void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*free)(void *, int))
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx = kmem_alloc(sizeof (struct pctxop), KM_SLEEP);
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->save_op = save;
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->restore_op = restore;
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->fork_op = fork;
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->exit_op = exit;
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->free_op = free;
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->arg = arg;
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->next = p->p_pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab p->p_pctx = pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab}
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab/*
0baeff3d96eae184e775c1064f1836090446a7bfrab * Remove a process context ops from the current process.
0baeff3d96eae184e775c1064f1836090446a7bfrab */
0baeff3d96eae184e775c1064f1836090446a7bfrabint
0baeff3d96eae184e775c1064f1836090446a7bfrabremovepctx(
0baeff3d96eae184e775c1064f1836090446a7bfrab proc_t *p,
0baeff3d96eae184e775c1064f1836090446a7bfrab void *arg,
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*save)(void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*restore)(void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*fork)(void *, void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*exit)(void *),
0baeff3d96eae184e775c1064f1836090446a7bfrab void (*free)(void *, int))
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx, *prev_pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab prev_pctx = NULL;
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi kpreempt_disable();
0baeff3d96eae184e775c1064f1836090446a7bfrab for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) {
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->save_op == save && pctx->restore_op == restore &&
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->fork_op == fork &&
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->exit_op == exit && pctx->free_op == free &&
0baeff3d96eae184e775c1064f1836090446a7bfrab pctx->arg == arg) {
0baeff3d96eae184e775c1064f1836090446a7bfrab if (prev_pctx)
0baeff3d96eae184e775c1064f1836090446a7bfrab prev_pctx->next = pctx->next;
0baeff3d96eae184e775c1064f1836090446a7bfrab else
0baeff3d96eae184e775c1064f1836090446a7bfrab p->p_pctx = pctx->next;
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->free_op != NULL)
0baeff3d96eae184e775c1064f1836090446a7bfrab (pctx->free_op)(pctx->arg, 0);
0baeff3d96eae184e775c1064f1836090446a7bfrab kmem_free(pctx, sizeof (struct pctxop));
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi kpreempt_enable();
0baeff3d96eae184e775c1064f1836090446a7bfrab return (1);
0baeff3d96eae184e775c1064f1836090446a7bfrab }
0baeff3d96eae184e775c1064f1836090446a7bfrab prev_pctx = pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab }
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi kpreempt_enable();
0baeff3d96eae184e775c1064f1836090446a7bfrab return (0);
0baeff3d96eae184e775c1064f1836090446a7bfrab}
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrabvoid
0baeff3d96eae184e775c1064f1836090446a7bfrabsavepctx(proc_t *p)
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab ASSERT(p == curthread->t_procp);
0baeff3d96eae184e775c1064f1836090446a7bfrab for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->save_op != NULL)
0baeff3d96eae184e775c1064f1836090446a7bfrab (pctx->save_op)(pctx->arg);
0baeff3d96eae184e775c1064f1836090446a7bfrab}
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrabvoid
0baeff3d96eae184e775c1064f1836090446a7bfrabrestorepctx(proc_t *p)
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab ASSERT(p == curthread->t_procp);
0baeff3d96eae184e775c1064f1836090446a7bfrab for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->restore_op != NULL)
0baeff3d96eae184e775c1064f1836090446a7bfrab (pctx->restore_op)(pctx->arg);
0baeff3d96eae184e775c1064f1836090446a7bfrab}
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrabvoid
0baeff3d96eae184e775c1064f1836090446a7bfrabforkpctx(proc_t *p, proc_t *cp)
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->fork_op != NULL)
0baeff3d96eae184e775c1064f1836090446a7bfrab (pctx->fork_op)(p, cp);
0baeff3d96eae184e775c1064f1836090446a7bfrab}
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab/*
0baeff3d96eae184e775c1064f1836090446a7bfrab * exitpctx is called during thread/lwp exit to perform any actions
0baeff3d96eae184e775c1064f1836090446a7bfrab * needed when an LWP in the process leaves the processor for the last
0baeff3d96eae184e775c1064f1836090446a7bfrab * time. This routine is not intended to deal with freeing memory; freepctx()
0baeff3d96eae184e775c1064f1836090446a7bfrab * is used for that purpose during proc_exit(). This routine is provided to
0baeff3d96eae184e775c1064f1836090446a7bfrab * allow for clean-up that can't wait until thread_free().
0baeff3d96eae184e775c1064f1836090446a7bfrab */
0baeff3d96eae184e775c1064f1836090446a7bfrabvoid
0baeff3d96eae184e775c1064f1836090446a7bfrabexitpctx(proc_t *p)
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->exit_op != NULL)
0baeff3d96eae184e775c1064f1836090446a7bfrab (pctx->exit_op)(p);
0baeff3d96eae184e775c1064f1836090446a7bfrab}
0baeff3d96eae184e775c1064f1836090446a7bfrab
0baeff3d96eae184e775c1064f1836090446a7bfrab/*
0baeff3d96eae184e775c1064f1836090446a7bfrab * freepctx is called from proc_exit() to get rid of the actual context ops.
0baeff3d96eae184e775c1064f1836090446a7bfrab */
0baeff3d96eae184e775c1064f1836090446a7bfrabvoid
0baeff3d96eae184e775c1064f1836090446a7bfrabfreepctx(proc_t *p, int isexec)
0baeff3d96eae184e775c1064f1836090446a7bfrab{
0baeff3d96eae184e775c1064f1836090446a7bfrab struct pctxop *pctx;
0baeff3d96eae184e775c1064f1836090446a7bfrab
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi kpreempt_disable();
0baeff3d96eae184e775c1064f1836090446a7bfrab while ((pctx = p->p_pctx) != NULL) {
0baeff3d96eae184e775c1064f1836090446a7bfrab p->p_pctx = pctx->next;
0baeff3d96eae184e775c1064f1836090446a7bfrab if (pctx->free_op != NULL)
0baeff3d96eae184e775c1064f1836090446a7bfrab (pctx->free_op)(pctx->arg, isexec);
0baeff3d96eae184e775c1064f1836090446a7bfrab kmem_free(pctx, sizeof (struct pctxop));
0baeff3d96eae184e775c1064f1836090446a7bfrab }
7ac89421b5a801d998dd60ee8cd0684bc6e83fcdRobert Mustacchi kpreempt_enable();
0baeff3d96eae184e775c1064f1836090446a7bfrab}
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Loweboolean_t
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowesecflag_enabled(proc_t *p, secflag_t flag)
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe{
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe return (secflag_isset(p->p_secflags.psf_effective, flag));
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe}
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowevoid
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowesecflags_promote(proc_t *p)
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe{
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe secflags_copy(&p->p_secflags.psf_effective, &p->p_secflags.psf_inherit);
d2a70789f056fc6c9ce3ab047b52126d80b0e3daRichard Lowe}