X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/cf7d32b81c573a0536dc4da4157f9c26f8d0bed3..39236c6e673c41db228275375ab7fdb0f837b292:/osfmk/kern/ast.c?ds=sidebyside diff --git a/osfmk/kern/ast.c b/osfmk/kern/ast.c index f0b75b59a..ee197f7f6 100644 --- a/osfmk/kern/ast.c +++ b/osfmk/kern/ast.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2008 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -77,15 +77,26 @@ #include #include #include +#if CONFIG_TELEMETRY +#include +#endif #include +#include #include #include // for CHUD AST hook +#include +#include // for MACF AST hook + +volatile perfASTCallback perfASTHook; + void ast_init(void) { } +extern void chudxnu_thread_ast(thread_t); // XXX this should probably be in a header... + /* * Called at splsched. */ @@ -98,21 +109,21 @@ ast_taken( boolean_t preempt_trap = (reasons == AST_PREEMPTION); ast_t *myast = ast_pending(); thread_t thread = current_thread(); + perfASTCallback perf_hook = perfASTHook; /* * CHUD hook - all threads including idle processor threads */ - if(perfASTHook) { - if(*myast & AST_CHUD_ALL) { - perfASTHook(0, NULL, 0, 0); + if (perf_hook) { + if (*myast & AST_CHUD_ALL) { + (*perf_hook)(reasons, myast); - if(*myast == AST_NONE) { - return; // nothing left to do - } + if (*myast == AST_NONE) + return; } - } else { - *myast &= ~AST_CHUD_ALL; } + else + *myast &= ~AST_CHUD_ALL; reasons &= *myast; *myast &= ~reasons; @@ -152,26 +163,58 @@ ast_taken( bsd_ast(thread); } #endif - +#if CONFIG_MACF + /* + * Handle MACF hook. + */ + if (reasons & AST_MACF) { + thread_ast_clear(thread, AST_MACF); + mac_thread_userret(thread); + } +#endif /* * Thread APC hook. */ if (reasons & AST_APC) act_execute_returnhandlers(); + + if (reasons & AST_GUARD) { + thread_ast_clear(thread, AST_GUARD); + guard_ast(thread); + } + + if (reasons & AST_LEDGER) { + thread_ast_clear(thread, AST_LEDGER); + ledger_ast(thread); + } + + /* + * Kernel Profiling Hook + */ + if (reasons & AST_KPERF) { + thread_ast_clear(thread, AST_KPERF); + chudxnu_thread_ast(thread); + } + +#if CONFIG_TELEMETRY + if (reasons & AST_TELEMETRY_ALL) { + boolean_t interrupted_userspace; + + assert((reasons & AST_TELEMETRY_ALL) != AST_TELEMETRY_ALL); /* only one is valid at a time */ + interrupted_userspace = (reasons & AST_TELEMETRY_USER) ? TRUE : FALSE; + thread_ast_clear(thread, AST_TELEMETRY_ALL); + telemetry_ast(thread, interrupted_userspace); + } +#endif ml_set_interrupts_enabled(FALSE); /* * Check for preemption. */ - if (reasons & AST_PREEMPT) { - processor_t myprocessor = current_processor(); + if (reasons & AST_PREEMPT) + reasons = csw_check(current_processor()); - if (csw_needed(thread, myprocessor)) - reasons = AST_PREEMPT; - else - reasons = AST_NONE; - } if ( (reasons & AST_PREEMPT) && wait_queue_assert_possible(thread) ) { counter(c_ast_taken_block++); @@ -193,6 +236,7 @@ ast_check( thread_t thread = processor->active_thread; processor->current_pri = thread->sched_pri; + processor->current_thmode = thread->sched_mode; if ( processor->state == PROCESSOR_RUNNING || processor->state == PROCESSOR_SHUTDOWN ) { ast_t preempt; @@ -200,12 +244,14 @@ ast_check( /* * Propagate thread ast to processor. */ + pal_ast_check(thread); + ast_propagate(thread->ast); /* * Context switch check. */ - if ((preempt = csw_check(thread, processor)) != AST_NONE) + if ((preempt = csw_check(processor)) != AST_NONE) ast_on(preempt); } }