10baeff3dSrab /*
20baeff3dSrab * CDDL HEADER START
30baeff3dSrab *
40baeff3dSrab * The contents of this file are subject to the terms of the
50baeff3dSrab * Common Development and Distribution License, Version 1.0 only
60baeff3dSrab * (the "License"). You may not use this file except in compliance
70baeff3dSrab * with the License.
80baeff3dSrab *
90baeff3dSrab * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100baeff3dSrab * or http://www.opensolaris.org/os/licensing.
110baeff3dSrab * See the License for the specific language governing permissions
120baeff3dSrab * and limitations under the License.
130baeff3dSrab *
140baeff3dSrab * When distributing Covered Code, include this CDDL HEADER in each
150baeff3dSrab * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160baeff3dSrab * If applicable, add the following below this CDDL HEADER, with the
170baeff3dSrab * fields enclosed by brackets "[]" replaced with your own identifying
180baeff3dSrab * information: Portions Copyright [yyyy] [name of copyright owner]
190baeff3dSrab *
200baeff3dSrab * CDDL HEADER END
210baeff3dSrab */
220baeff3dSrab /*
230baeff3dSrab * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
240baeff3dSrab * Use is subject to license terms.
257ac89421SRobert Mustacchi * Copyright (c) 2013, Joyent, Inc. All rights reserved.
260baeff3dSrab */
270baeff3dSrab
280baeff3dSrab #include <sys/proc.h>
297ac89421SRobert Mustacchi #include <sys/cpuvar.h>
307ac89421SRobert Mustacchi #include <sys/disp.h>
310baeff3dSrab
320baeff3dSrab /*
330baeff3dSrab * Install process context ops for the current process.
340baeff3dSrab */
350baeff3dSrab void
installpctx(proc_t * p,void * arg,void (* save)(void *),void (* restore)(void *),void (* fork)(void *,void *),void (* exit)(void *),void (* free)(void *,int))360baeff3dSrab installpctx(
370baeff3dSrab proc_t *p,
380baeff3dSrab void *arg,
390baeff3dSrab void (*save)(void *),
400baeff3dSrab void (*restore)(void *),
410baeff3dSrab void (*fork)(void *, void *),
420baeff3dSrab void (*exit)(void *),
430baeff3dSrab void (*free)(void *, int))
440baeff3dSrab {
450baeff3dSrab struct pctxop *pctx;
460baeff3dSrab
470baeff3dSrab pctx = kmem_alloc(sizeof (struct pctxop), KM_SLEEP);
480baeff3dSrab pctx->save_op = save;
490baeff3dSrab pctx->restore_op = restore;
500baeff3dSrab pctx->fork_op = fork;
510baeff3dSrab pctx->exit_op = exit;
520baeff3dSrab pctx->free_op = free;
530baeff3dSrab pctx->arg = arg;
540baeff3dSrab pctx->next = p->p_pctx;
550baeff3dSrab p->p_pctx = pctx;
560baeff3dSrab }
570baeff3dSrab
580baeff3dSrab /*
590baeff3dSrab * Remove a process context ops from the current process.
600baeff3dSrab */
610baeff3dSrab int
removepctx(proc_t * p,void * arg,void (* save)(void *),void (* restore)(void *),void (* fork)(void *,void *),void (* exit)(void *),void (* free)(void *,int))620baeff3dSrab removepctx(
630baeff3dSrab proc_t *p,
640baeff3dSrab void *arg,
650baeff3dSrab void (*save)(void *),
660baeff3dSrab void (*restore)(void *),
670baeff3dSrab void (*fork)(void *, void *),
680baeff3dSrab void (*exit)(void *),
690baeff3dSrab void (*free)(void *, int))
700baeff3dSrab {
710baeff3dSrab struct pctxop *pctx, *prev_pctx;
720baeff3dSrab
730baeff3dSrab prev_pctx = NULL;
747ac89421SRobert Mustacchi kpreempt_disable();
750baeff3dSrab for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) {
760baeff3dSrab if (pctx->save_op == save && pctx->restore_op == restore &&
770baeff3dSrab pctx->fork_op == fork &&
780baeff3dSrab pctx->exit_op == exit && pctx->free_op == free &&
790baeff3dSrab pctx->arg == arg) {
800baeff3dSrab if (prev_pctx)
810baeff3dSrab prev_pctx->next = pctx->next;
820baeff3dSrab else
830baeff3dSrab p->p_pctx = pctx->next;
840baeff3dSrab if (pctx->free_op != NULL)
850baeff3dSrab (pctx->free_op)(pctx->arg, 0);
860baeff3dSrab kmem_free(pctx, sizeof (struct pctxop));
877ac89421SRobert Mustacchi kpreempt_enable();
880baeff3dSrab return (1);
890baeff3dSrab }
900baeff3dSrab prev_pctx = pctx;
910baeff3dSrab }
927ac89421SRobert Mustacchi kpreempt_enable();
930baeff3dSrab return (0);
940baeff3dSrab }
950baeff3dSrab
960baeff3dSrab void
savepctx(proc_t * p)970baeff3dSrab savepctx(proc_t *p)
980baeff3dSrab {
990baeff3dSrab struct pctxop *pctx;
1000baeff3dSrab
1010baeff3dSrab ASSERT(p == curthread->t_procp);
1020baeff3dSrab for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
1030baeff3dSrab if (pctx->save_op != NULL)
1040baeff3dSrab (pctx->save_op)(pctx->arg);
1050baeff3dSrab }
1060baeff3dSrab
1070baeff3dSrab void
restorepctx(proc_t * p)1080baeff3dSrab restorepctx(proc_t *p)
1090baeff3dSrab {
1100baeff3dSrab struct pctxop *pctx;
1110baeff3dSrab
1120baeff3dSrab ASSERT(p == curthread->t_procp);
1130baeff3dSrab for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
1140baeff3dSrab if (pctx->restore_op != NULL)
1150baeff3dSrab (pctx->restore_op)(pctx->arg);
1160baeff3dSrab }
1170baeff3dSrab
1180baeff3dSrab void
forkpctx(proc_t * p,proc_t * cp)1190baeff3dSrab forkpctx(proc_t *p, proc_t *cp)
1200baeff3dSrab {
1210baeff3dSrab struct pctxop *pctx;
1220baeff3dSrab
1230baeff3dSrab for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
1240baeff3dSrab if (pctx->fork_op != NULL)
1250baeff3dSrab (pctx->fork_op)(p, cp);
1260baeff3dSrab }
1270baeff3dSrab
1280baeff3dSrab /*
1290baeff3dSrab * exitpctx is called during thread/lwp exit to perform any actions
1300baeff3dSrab * needed when an LWP in the process leaves the processor for the last
1310baeff3dSrab * time. This routine is not intended to deal with freeing memory; freepctx()
1320baeff3dSrab * is used for that purpose during proc_exit(). This routine is provided to
1330baeff3dSrab * allow for clean-up that can't wait until thread_free().
1340baeff3dSrab */
1350baeff3dSrab void
exitpctx(proc_t * p)1360baeff3dSrab exitpctx(proc_t *p)
1370baeff3dSrab {
1380baeff3dSrab struct pctxop *pctx;
1390baeff3dSrab
1400baeff3dSrab for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
1410baeff3dSrab if (pctx->exit_op != NULL)
1420baeff3dSrab (pctx->exit_op)(p);
1430baeff3dSrab }
1440baeff3dSrab
1450baeff3dSrab /*
1460baeff3dSrab * freepctx is called from proc_exit() to get rid of the actual context ops.
1470baeff3dSrab */
1480baeff3dSrab void
freepctx(proc_t * p,int isexec)1490baeff3dSrab freepctx(proc_t *p, int isexec)
1500baeff3dSrab {
1510baeff3dSrab struct pctxop *pctx;
1520baeff3dSrab
1537ac89421SRobert Mustacchi kpreempt_disable();
1540baeff3dSrab while ((pctx = p->p_pctx) != NULL) {
1550baeff3dSrab p->p_pctx = pctx->next;
1560baeff3dSrab if (pctx->free_op != NULL)
1570baeff3dSrab (pctx->free_op)(pctx->arg, isexec);
1580baeff3dSrab kmem_free(pctx, sizeof (struct pctxop));
1590baeff3dSrab }
1607ac89421SRobert Mustacchi kpreempt_enable();
1610baeff3dSrab }
162*d2a70789SRichard Lowe
163*d2a70789SRichard Lowe boolean_t
secflag_enabled(proc_t * p,secflag_t flag)164*d2a70789SRichard Lowe secflag_enabled(proc_t *p, secflag_t flag)
165*d2a70789SRichard Lowe {
166*d2a70789SRichard Lowe return (secflag_isset(p->p_secflags.psf_effective, flag));
167*d2a70789SRichard Lowe }
168*d2a70789SRichard Lowe
169*d2a70789SRichard Lowe void
secflags_promote(proc_t * p)170*d2a70789SRichard Lowe secflags_promote(proc_t *p)
171*d2a70789SRichard Lowe {
172*d2a70789SRichard Lowe secflags_copy(&p->p_secflags.psf_effective, &p->p_secflags.psf_inherit);
173*d2a70789SRichard Lowe }
174