xref: /illumos-gate/usr/src/uts/common/os/proc.c (revision d2a70789)
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