X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/9bccf70c0258c7cac2dcb80011b2a964d884c552..8ad349bb6ed4a0be06e34c92be0d98b92e078db4:/osfmk/kern/exception.c?ds=inline diff --git a/osfmk/kern/exception.c b/osfmk/kern/exception.c index b99139fc2..348b4cae4 100644 --- a/osfmk/kern/exception.c +++ b/osfmk/kern/exception.c @@ -1,23 +1,31 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_LICENSE_OSREFERENCE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the + * License may not be used to create, or enable the creation or + * redistribution of, unlawful or unlicensed copies of an Apple operating + * system, or to circumvent, violate, or enable the circumvention or + * violation of, any terms of an Apple operating system software license + * agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ */ /* * @OSF_COPYRIGHT@ @@ -52,11 +60,13 @@ #include +#include #include #include #include #include #include +#include #include #include #include @@ -66,12 +76,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include @@ -103,6 +111,20 @@ unsigned long c_tsk_exc_raise = 0; unsigned long c_tsk_exc_raise_state = 0; unsigned long c_tsk_exc_raise_state_id = 0; +/* forward declarations */ +void exception_deliver( + exception_type_t exception, + exception_data_t code, + mach_msg_type_number_t codeCnt, + struct exception_action *excp, + mutex_t *mutex); + +#ifdef MACH_BSD +kern_return_t bsd_exception( + exception_type_t exception, + exception_data_t code, + mach_msg_type_number_t codeCnt); +#endif /* MACH_BSD */ /* * Routine: exception_deliver @@ -124,7 +146,7 @@ exception_deliver( struct exception_action *excp, mutex_t *mutex) { - thread_act_t a_self = current_act(); + thread_t self = current_thread(); ipc_port_t exc_port; int behavior; int flavor; @@ -134,7 +156,7 @@ exception_deliver( * Save work if we are terminating. * Just go back to our AST handler. */ - if (!a_self->active) + if (!self->active) thread_exception_return(); /* @@ -167,11 +189,11 @@ exception_deliver( switch (behavior) { case EXCEPTION_STATE: { mach_msg_type_number_t state_cnt; - natural_t state[ THREAD_MACHINE_STATE_MAX ]; + thread_state_data_t state; c_thr_exc_raise_state++; - state_cnt = state_count[flavor]; - kr = thread_getstatus(a_self, flavor, + state_cnt = _MachineStateCount[flavor]; + kr = thread_getstatus(self, flavor, (thread_state_t)state, &state_cnt); if (kr == KERN_SUCCESS) { @@ -181,7 +203,7 @@ exception_deliver( state, state_cnt, state, &state_cnt); if (kr == MACH_MSG_SUCCESS) - kr = thread_setstatus(a_self, flavor, + kr = thread_setstatus(self, flavor, (thread_state_t)state, state_cnt); } @@ -195,8 +217,8 @@ exception_deliver( case EXCEPTION_DEFAULT: c_thr_exc_raise++; kr = exception_raise(exc_port, - retrieve_act_self_fast(a_self), - retrieve_task_self_fast(a_self->task), + retrieve_thread_self_fast(self), + retrieve_task_self_fast(self->task), exception, code, codeCnt); @@ -207,24 +229,24 @@ exception_deliver( case EXCEPTION_STATE_IDENTITY: { mach_msg_type_number_t state_cnt; - natural_t state[ THREAD_MACHINE_STATE_MAX ]; + thread_state_data_t state; c_thr_exc_raise_state_id++; - state_cnt = state_count[flavor]; - kr = thread_getstatus(a_self, flavor, + state_cnt = _MachineStateCount[flavor]; + kr = thread_getstatus(self, flavor, (thread_state_t)state, &state_cnt); if (kr == KERN_SUCCESS) { kr = exception_raise_state_identity(exc_port, - retrieve_act_self_fast(a_self), - retrieve_task_self_fast(a_self->task), + retrieve_thread_self_fast(self), + retrieve_task_self_fast(self->task), exception, code, codeCnt, &flavor, state, state_cnt, state, &state_cnt); if (kr == MACH_MSG_SUCCESS) - kr = thread_setstatus(a_self, flavor, + kr = thread_setstatus(self, flavor, (thread_state_t)state, state_cnt); } @@ -254,12 +276,12 @@ exception_deliver( * Doesn't return. */ void -exception( +exception_triage( exception_type_t exception, exception_data_t code, mach_msg_type_number_t codeCnt) { - thread_act_t thr_act; + thread_t thread; task_t task; host_priv_t host_priv; struct exception_action *excp; @@ -273,9 +295,9 @@ exception( /* * Try to raise the exception at the activation level. */ - thr_act = current_act(); - mutex = mutex_addr(thr_act->lock); - excp = &thr_act->exc_actions[exception]; + thread = current_thread(); + mutex = mutex_addr(thread->mutex); + excp = &thread->exc_actions[exception]; exception_deliver(exception, code, codeCnt, excp, mutex); /* @@ -322,10 +344,9 @@ bsd_exception( mach_msg_type_number_t codeCnt) { task_t task; - host_priv_t host_priv; struct exception_action *excp; mutex_t *mutex; - thread_act_t a_self = current_act(); + thread_t self = current_thread(); ipc_port_t exc_port; int behavior; int flavor; @@ -342,7 +363,7 @@ bsd_exception( * Save work if we are terminating. * Just go back to our AST handler. */ - if (!a_self->active) { + if (!self->active) { return(KERN_FAILURE); } @@ -376,11 +397,11 @@ bsd_exception( switch (behavior) { case EXCEPTION_STATE: { mach_msg_type_number_t state_cnt; - natural_t state[ THREAD_MACHINE_STATE_MAX ]; + thread_state_data_t state; c_thr_exc_raise_state++; - state_cnt = state_count[flavor]; - kr = thread_getstatus(a_self, flavor, + state_cnt = _MachineStateCount[flavor]; + kr = thread_getstatus(self, flavor, (thread_state_t)state, &state_cnt); if (kr == KERN_SUCCESS) { @@ -390,7 +411,7 @@ bsd_exception( state, state_cnt, state, &state_cnt); if (kr == MACH_MSG_SUCCESS) - kr = thread_setstatus(a_self, flavor, + kr = thread_setstatus(self, flavor, (thread_state_t)state, state_cnt); } @@ -404,8 +425,8 @@ bsd_exception( case EXCEPTION_DEFAULT: c_thr_exc_raise++; kr = exception_raise(exc_port, - retrieve_act_self_fast(a_self), - retrieve_task_self_fast(a_self->task), + retrieve_thread_self_fast(self), + retrieve_task_self_fast(self->task), exception, code, codeCnt); @@ -415,24 +436,24 @@ bsd_exception( case EXCEPTION_STATE_IDENTITY: { mach_msg_type_number_t state_cnt; - natural_t state[ THREAD_MACHINE_STATE_MAX ]; + thread_state_data_t state; c_thr_exc_raise_state_id++; - state_cnt = state_count[flavor]; - kr = thread_getstatus(a_self, flavor, + state_cnt = _MachineStateCount[flavor]; + kr = thread_getstatus(self, flavor, (thread_state_t)state, &state_cnt); if (kr == KERN_SUCCESS) { kr = exception_raise_state_identity(exc_port, - retrieve_act_self_fast(a_self), - retrieve_task_self_fast(a_self->task), + retrieve_thread_self_fast(self), + retrieve_task_self_fast(self->task), exception, code, codeCnt, &flavor, state, state_cnt, state, &state_cnt); if (kr == MACH_MSG_SUCCESS) - kr = thread_setstatus(a_self, flavor, + kr = thread_setstatus(self, flavor, (thread_state_t)state, state_cnt); } @@ -449,3 +470,63 @@ bsd_exception( return(KERN_FAILURE); } + + + +/* + * Handle interface for special perfomance monitoring + * This is a special case of the host exception handler + */ + +kern_return_t sys_perf_notify(struct task *task, + exception_data_t code, + mach_msg_type_number_t codeCnt) +{ + host_priv_t hostp; + struct exception_action *excp; + thread_t thread = current_thread(); + ipc_port_t xport; + kern_return_t ret; + wait_interrupt_t wsave; + + hostp = host_priv_self(); /* Get the host privileged ports */ + excp = &hostp->exc_actions[EXC_RPC_ALERT]; /* Point to the RPC_ALERT action */ + + mutex_lock(&hostp->lock); /* Lock the priv port */ + xport = excp->port; /* Get the port for this exception */ + if (!IP_VALID(xport)) { /* Is it valid? */ + mutex_unlock(&hostp->lock); /* Unlock */ + return(KERN_FAILURE); /* Go away... */ + } + + ip_lock(xport); /* Lock the exception port */ + if (!ip_active(xport)) { /* and is it active? */ + ip_unlock(xport); /* Nope, fail */ + mutex_unlock(&hostp->lock); /* Unlock */ + return(KERN_FAILURE); /* Go away... */ + } + + if (task->itk_space == xport->data.receiver) { /* Are we trying to send to ourselves? */ + ip_unlock(xport); /* Yes, fail */ + mutex_unlock(&hostp->lock); /* Unlock */ + return(KERN_FAILURE); /* Go away... */ + } + + ip_reference(xport); /* Bump reference so it doesn't go away */ + xport->ip_srights++; /* Bump send rights */ + ip_unlock(xport); /* We can unlock it now */ + + mutex_unlock(&hostp->lock); /* All done with the lock */ + + wsave = thread_interrupt_level(THREAD_UNINT); /* Make sure we aren't aborted here */ + + ret = exception_raise(xport, /* Send the exception to the perf handler */ + retrieve_thread_self_fast(thread), /* Not always the dying guy */ + retrieve_task_self_fast(thread->task), /* Not always the dying guy */ + EXC_RPC_ALERT, /* Unused exception type until now */ + code, codeCnt); + + (void)thread_interrupt_level(wsave); /* Restore interrupt level */ + + return(ret); /* Tell caller how it went */ +}