- mach_port_name_t old_voucher_name;
- ipc_voucher_t old_voucher;
-#ifdef CONFIG_BANK
- ledger_t bankledger = NULL;
-#endif
-
- if (THREAD_NULL == thread)
- return KERN_INVALID_TASK;
-
- if (thread != current_thread() || thread->started)
- return KERN_INVALID_ARGUMENT;
-
-#ifdef CONFIG_BANK
- bankledger = bank_get_voucher_ledger(new_voucher);
-#endif
-
- thread_mtx_lock(thread);
-
- old_voucher = thread->ith_voucher;
-
- if (IPC_VOUCHER_NULL == old_voucher) {
- old_voucher_name = thread->ith_voucher_name;
-
- /* perform lazy binding if needed */
- if (MACH_PORT_VALID(old_voucher_name)) {
- old_voucher = convert_port_name_to_voucher(old_voucher_name);
- thread->ith_voucher_name = MACH_PORT_NULL;
- thread->ith_voucher = old_voucher;
-
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
- (uintptr_t)thread_tid(thread),
- (uintptr_t)old_voucher_name,
- VM_KERNEL_ADDRPERM((uintptr_t)old_voucher),
- 4, 0);
-
- }
- }
-
- /* swap in new voucher, if old voucher matches the one supplied */
- if (old_voucher == *in_out_old_voucher) {
- ipc_voucher_reference(new_voucher);
- thread->ith_voucher = new_voucher;
- thread->ith_voucher_name = MACH_PORT_NULL;
-#ifdef CONFIG_BANK
- bank_swap_thread_bank_ledger(thread, bankledger);
-#endif
- thread_mtx_unlock(thread);
-
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- MACHDBG_CODE(DBG_MACH_IPC,MACH_THREAD_SET_VOUCHER) | DBG_FUNC_NONE,
- (uintptr_t)thread_tid(thread),
- (uintptr_t)MACH_PORT_NULL,
- VM_KERNEL_ADDRPERM((uintptr_t)new_voucher),
- 5, 0);
-
- ipc_voucher_release(old_voucher);
-
- *in_out_old_voucher = IPC_VOUCHER_NULL;
- return KERN_SUCCESS;
- }
-
- /* Otherwise, just return old voucher reference */
- ipc_voucher_reference(old_voucher);
- thread_mtx_unlock(thread);
- *in_out_old_voucher = old_voucher;
- return KERN_SUCCESS;