X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..5eebf7385fedb1517b66b53c28e5aa6bb0a2be50:/osfmk/kern/task.c?ds=inline diff --git a/osfmk/kern/task.c b/osfmk/kern/task.c index aef657a27..e9acf180b 100644 --- a/osfmk/kern/task.c +++ b/osfmk/kern/task.c @@ -1,24 +1,21 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * 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 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. 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 + * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * 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@ */ @@ -151,6 +148,16 @@ kern_return_t task_set_ledger( ledger_t wired, ledger_t paged); +void +task_backing_store_privileged( + task_t task) +{ + task_lock(task); + task->priv_flags |= VM_BACKING_STORE_PRIV; + task_unlock(task); + return; +} + void task_init(void) { @@ -164,20 +171,12 @@ task_init(void) /* * Create the kernel task as the first task. - * Task_create_local must assign to kernel_task as a side effect, - * for other initialization. (:-() */ - if (task_create_local( - TASK_NULL, FALSE, FALSE, &kernel_task) != KERN_SUCCESS) + if (task_create_internal(TASK_NULL, FALSE, &kernel_task) != KERN_SUCCESS) panic("task_init\n"); + vm_map_deallocate(kernel_task->map); kernel_task->map = kernel_map; - -#if MACH_ASSERT - if (watchacts & WA_TASK) - printf("task_init: kernel_task = %x map=%x\n", - kernel_task, kernel_map); -#endif /* MACH_ASSERT */ } #if MACH_HOST @@ -240,48 +239,7 @@ kernel_task_create( vm_size_t map_size, task_t *child_task) { - kern_return_t result; - task_t new_task; - vm_map_t old_map; - - /* - * Create the task. - */ - result = task_create_local(parent_task, FALSE, TRUE, &new_task); - if (result != KERN_SUCCESS) - return (result); - - /* - * Task_create_local creates the task with a user-space map. - * We attempt to replace the map and free it afterwards; else - * task_deallocate will free it (can NOT set map to null before - * task_deallocate, this impersonates a norma placeholder task). - * _Mark the memory as pageable_ -- this is what we - * want for images (like servers) loaded into the kernel. - */ - if (map_size == 0) { - vm_map_deallocate(new_task->map); - new_task->map = kernel_map; - *child_task = new_task; - } else { - old_map = new_task->map; - if ((result = kmem_suballoc(kernel_map, &map_base, - map_size, TRUE, FALSE, - &new_task->map)) != KERN_SUCCESS) { - /* - * New task created with ref count of 2 -- decrement by - * one to force task deletion. - */ - printf("kmem_suballoc(%x,%x,%x,1,0,&new) Fails\n", - kernel_map, map_base, map_size); - --new_task->ref_count; - task_deallocate(new_task); - return (result); - } - vm_map_deallocate(old_map); - *child_task = new_task; - } - return (KERN_SUCCESS); + return (KERN_INVALID_ARGUMENT); } kern_return_t @@ -295,8 +253,8 @@ task_create( if (parent_task == TASK_NULL) return(KERN_INVALID_ARGUMENT); - return task_create_local( - parent_task, inherit_memory, FALSE, child_task); + return task_create_internal( + parent_task, inherit_memory, child_task); } kern_return_t @@ -304,6 +262,7 @@ host_security_create_task_token( host_security_t host_security, task_t parent_task, security_token_t sec_token, + audit_token_t audit_token, host_priv_t host_priv, ledger_port_array_t ledger_ports, mach_msg_type_number_t num_ledger_ports, @@ -318,8 +277,8 @@ host_security_create_task_token( if (host_security == HOST_NULL) return(KERN_INVALID_SECURITY); - result = task_create_local( - parent_task, inherit_memory, FALSE, child_task); + result = task_create_internal( + parent_task, inherit_memory, child_task); if (result != KERN_SUCCESS) return(result); @@ -327,6 +286,7 @@ host_security_create_task_token( result = host_security_set_task_token(host_security, *child_task, sec_token, + audit_token, host_priv); if (result != KERN_SUCCESS) @@ -336,10 +296,9 @@ host_security_create_task_token( } kern_return_t -task_create_local( +task_create_internal( task_t parent_task, boolean_t inherit_memory, - boolean_t kernel_loaded, task_t *child_task) /* OUT */ { task_t new_task; @@ -361,15 +320,14 @@ task_create_local( trunc_page_32(VM_MAX_ADDRESS), TRUE); mutex_init(&new_task->lock, ETAP_THREAD_TASK_NEW); - queue_init(&new_task->thr_acts); + queue_init(&new_task->threads); new_task->suspend_count = 0; - new_task->thr_act_count = 0; - new_task->res_act_count = 0; - new_task->active_act_count = 0; + new_task->thread_count = 0; + new_task->res_thread_count = 0; + new_task->active_thread_count = 0; new_task->user_stop_count = 0; new_task->role = TASK_UNSPECIFIED; new_task->active = TRUE; - new_task->kernel_loaded = kernel_loaded; new_task->user_data = 0; new_task->faults = 0; new_task->cow_faults = 0; @@ -377,6 +335,7 @@ task_create_local( new_task->messages_sent = 0; new_task->messages_received = 0; new_task->syscalls_mach = 0; + new_task->priv_flags = 0; new_task->syscalls_unix=0; new_task->csw=0; new_task->taskFeatures[0] = 0; /* Init task features */ @@ -436,6 +395,7 @@ task_create_local( pset = &default_pset; new_task->sec_token = parent_task->sec_token; + new_task->audit_token = parent_task->audit_token; shared_region_mapping_ref(parent_task->system_shared_region); new_task->system_shared_region = parent_task->system_shared_region; @@ -449,12 +409,13 @@ task_create_local( pset = &default_pset; new_task->sec_token = KERNEL_SECURITY_TOKEN; + new_task->audit_token = KERNEL_AUDIT_TOKEN; new_task->wired_ledger_port = ledger_copy(root_wired_ledger); new_task->paged_ledger_port = ledger_copy(root_paged_ledger); } if (kernel_task == TASK_NULL) { - new_task->priority = MINPRI_KERNEL; + new_task->priority = BASEPRI_KERNEL; new_task->max_priority = MAXPRI_KERNEL; } else { @@ -470,28 +431,11 @@ task_create_local( task_unfreeze(parent_task); #endif /* MACH_HOST */ -#if FAST_TAS - if (inherit_memory) { - new_task->fast_tas_base = parent_task->fast_tas_base; - new_task->fast_tas_end = parent_task->fast_tas_end; - } else { - new_task->fast_tas_base = (vm_offset_t)0; - new_task->fast_tas_end = (vm_offset_t)0; - } -#endif /* FAST_TAS */ + if (vm_backing_store_low && parent_task != NULL) + new_task->priv_flags |= (parent_task->priv_flags&VM_BACKING_STORE_PRIV); ipc_task_enable(new_task); -#if TASK_SWAPPER - task_swapout_eligible(new_task); -#endif /* TASK_SWAPPER */ - -#if MACH_ASSERT - if (watchacts & WA_TASK) - printf("*** task_create_local(par=%x inh=%x) == 0x%x\n", - parent_task, inherit_memory, new_task); -#endif /* MACH_ASSERT */ - *child_task = new_task; return(KERN_SUCCESS); } @@ -527,7 +471,6 @@ task_deallocate( if(task->dynamic_working_set) tws_hash_destroy((tws_hash_t)task->dynamic_working_set); - eml_task_deallocate(task); ipc_task_terminate(task); @@ -546,9 +489,6 @@ task_deallocate( task_unfreeze(task); #endif - if (task->kernel_loaded) - vm_map_remove(kernel_map, task->map->min_offset, - task->map->max_offset, VM_MAP_NO_FLAGS); vm_map_deallocate(task->map); is_release(task->itk_space); task_prof_deallocate(task); @@ -686,18 +626,17 @@ task_terminate_internal( * handed over to the reaper, who will finally remove the * thread from the task list and free the structures. */ - queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) { + queue_iterate(&task->threads, thr_act, thread_act_t, task_threads) { thread_terminate_internal(thr_act); } /* - * Clean up any virtual machine state/resources associated - * with the current activation because it may hold wiring - * and other references on resources we will be trying to - * release below. + * Give the machine dependent code a chance + * to perform cleanup before ripping apart + * the task. */ if (cur_thr_act->task == task) - act_virtual_machine_destroy(cur_thr_act); + machine_thread_terminate_self(); task_unlock(task); @@ -709,8 +648,7 @@ task_terminate_internal( /* * Destroy the IPC space, leaving just a reference for it. */ - if (!task->kernel_loaded) - ipc_space_destroy(task->itk_space); + ipc_space_destroy(task->itk_space); /* * If the current thread is a member of the task @@ -796,7 +734,7 @@ task_halt( return(KERN_FAILURE); } - if (task->thr_act_count > 1) { + if (task->thread_count > 1) { /* * Mark all the threads to keep them from starting any more * user-level execution. The thread_terminate_internal code @@ -814,7 +752,7 @@ task_halt( * handed over to the reaper, who will finally remove the * thread from the task list and free the structures. */ - queue_iterate(&task->thr_acts, thr_act, thread_act_t,thr_acts) { + queue_iterate(&task->threads, thr_act, thread_act_t, task_threads) { if (thr_act != cur_thr_act) thread_terminate_internal(thr_act); } @@ -822,12 +760,11 @@ task_halt( } /* - * If the current thread has any virtual machine state - * associated with it, we need to explicitly clean that - * up now (because we did not terminate the current act) - * before we try to clean up the task VM and port spaces. + * Give the machine dependent code a chance + * to perform cleanup before ripping apart + * the task. */ - act_virtual_machine_destroy(cur_thr_act); + machine_thread_terminate_self(); task_unlock(task); @@ -840,8 +777,7 @@ task_halt( * Destroy the contents of the IPC space, leaving just * a reference for it. */ - if (!task->kernel_loaded) - ipc_space_clean(task->itk_space); + ipc_space_clean(task->itk_space); /* * Clean out the address space, as we are going to be @@ -877,7 +813,7 @@ task_hold_locked( /* * Iterate through all the thread_act's and hold them. */ - queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) { + queue_iterate(&task->threads, thr_act, thread_act_t, task_threads) { act_lock_thread(thr_act); thread_hold(thr_act); act_unlock_thread(thr_act); @@ -935,12 +871,12 @@ task_wait_locked( * stop. Do not wait for the current thread if it is within * the task. */ - queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) { + queue_iterate(&task->threads, thr_act, thread_act_t, task_threads) { if (thr_act != cur_thr_act) { - thread_shuttle_t thr_shuttle; + thread_t thread; - thr_shuttle = act_lock_thread(thr_act); - thread_wait(thr_shuttle); + thread = act_lock_thread(thr_act); + thread_wait(thread); act_unlock_thread(thr_act); } } @@ -970,7 +906,7 @@ task_release_locked( * Do not hold the current thread_act if it is within the * task. */ - queue_iterate(&task->thr_acts, thr_act, thread_act_t, thr_acts) { + queue_iterate(&task->threads, thr_act, thread_act_t, task_threads) { act_lock_thread(thr_act); thread_release(thr_act); act_unlock_thread(thr_act); @@ -1032,7 +968,7 @@ task_threads( return KERN_FAILURE; } - actual = task->thr_act_count; + actual = task->thread_count; /* do we have the memory we need? */ size_needed = actual * sizeof(mach_port_t); @@ -1056,17 +992,17 @@ task_threads( /* OK, have memory and the task is locked & active */ thr_acts = (thread_act_t *) addr; - for (i = j = 0, thr_act = (thread_act_t) queue_first(&task->thr_acts); + for (i = j = 0, thr_act = (thread_act_t) queue_first(&task->threads); i < actual; - i++, thr_act = (thread_act_t) queue_next(&thr_act->thr_acts)) { + i++, thr_act = (thread_act_t) queue_next(&thr_act->task_threads)) { act_lock(thr_act); - if (thr_act->ref_count > 0) { - act_locked_act_reference(thr_act); + if (thr_act->act_ref_count > 0) { + act_reference_locked(thr_act); thr_acts[j++] = thr_act; } act_unlock(thr_act); } - assert(queue_end(&task->thr_acts, (queue_entry_t) thr_act)); + assert(queue_end(&task->threads, (queue_entry_t) thr_act)); actual = j; size_needed = actual * sizeof(mach_port_t); @@ -1199,8 +1135,10 @@ host_security_set_task_token( host_security_t host_security, task_t task, security_token_t sec_token, + audit_token_t audit_token, host_priv_t host_priv) { + ipc_port_t host_port; kern_return_t kr; if (task == TASK_NULL) @@ -1211,17 +1149,16 @@ host_security_set_task_token( task_lock(task); task->sec_token = sec_token; + task->audit_token = audit_token; task_unlock(task); if (host_priv != HOST_PRIV_NULL) { - kr = task_set_special_port(task, - TASK_HOST_PORT, - ipc_port_make_send(realhost.host_priv_self)); + kr = host_get_host_priv_port(host_priv, &host_port); } else { - kr = task_set_special_port(task, - TASK_HOST_PORT, - ipc_port_make_send(realhost.host_self)); + kr = host_get_host_port(host_priv_self(), &host_port); } + assert(kr == KERN_SUCCESS); + kr = task_set_special_port(task, TASK_HOST_PORT, host_port); return(kr); } @@ -1344,8 +1281,8 @@ task_info( times_info->system_time.microseconds = 0; task_lock(task); - queue_iterate(&task->thr_acts, thr_act, - thread_act_t, thr_acts) + queue_iterate(&task->threads, thr_act, + thread_act_t, task_threads) { time_value_t user_time, system_time; spl_t s; @@ -1448,6 +1385,24 @@ task_info( break; } + case TASK_AUDIT_TOKEN: + { + register audit_token_t *audit_token_p; + + if (*task_info_count < TASK_AUDIT_TOKEN_COUNT) { + return(KERN_INVALID_ARGUMENT); + } + + audit_token_p = (audit_token_t *) task_info_out; + + task_lock(task); + *audit_token_p = task->audit_token; + task_unlock(task); + + *task_info_count = TASK_AUDIT_TOKEN_COUNT; + break; + } + case TASK_SCHED_INFO: return(KERN_INVALID_ARGUMENT); @@ -1734,6 +1689,25 @@ task_set_port_space( return kr; } +/* + * Routine: + * task_is_classic + * Purpose: + * Returns true if the task is a P_CLASSIC task. + */ +boolean_t +task_is_classic( + task_t task) +{ + boolean_t result = FALSE; + + if (task) { + struct proc *p = get_bsdtask_info(task); + result = proc_is_classic(p) ? TRUE : FALSE; + } + return result; +} + /* * We need to export some functions to other components that * are currently implemented in macros within the osfmk @@ -1742,9 +1716,9 @@ task_set_port_space( boolean_t is_kerneltask(task_t t) { if (t == kernel_task) - return(TRUE); - else - return((t->kernel_loaded)); + return (TRUE); + + return (FALSE); } #undef current_task