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. 25*7ac89421SRobert Mustacchi * Copyright (c) 2013, Joyent, Inc. All rights reserved. 260baeff3dSrab */ 270baeff3dSrab 280baeff3dSrab #include <sys/proc.h> 29*7ac89421SRobert Mustacchi #include <sys/cpuvar.h> 30*7ac89421SRobert Mustacchi #include <sys/disp.h> 310baeff3dSrab 320baeff3dSrab /* 330baeff3dSrab * Install process context ops for the current process. 340baeff3dSrab */ 350baeff3dSrab void 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 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; 74*7ac89421SRobert 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)); 87*7ac89421SRobert Mustacchi kpreempt_enable(); 880baeff3dSrab return (1); 890baeff3dSrab } 900baeff3dSrab prev_pctx = pctx; 910baeff3dSrab } 92*7ac89421SRobert Mustacchi kpreempt_enable(); 930baeff3dSrab return (0); 940baeff3dSrab } 950baeff3dSrab 960baeff3dSrab void 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 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 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 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 1490baeff3dSrab freepctx(proc_t *p, int isexec) 1500baeff3dSrab { 1510baeff3dSrab struct pctxop *pctx; 1520baeff3dSrab 153*7ac89421SRobert 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 } 160*7ac89421SRobert Mustacchi kpreempt_enable(); 1610baeff3dSrab } 162