1 /* 2 * Copyright (c) 2012-2019 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #ifndef _BANK_BANK_INTERNAL_H_ 30 #define _BANK_BANK_INTERNAL_H_ 31 32 #include <stdint.h> 33 #include <mach/mach_types.h> 34 35 #ifdef MACH_KERNEL_PRIVATE 36 37 #include <kern/thread.h> 38 #include <kern/thread_group.h> 39 #include <kern/locks.h> 40 #include <kern/queue.h> 41 #include <ipc/ipc_voucher.h> 42 #include <bank/bank_types.h> 43 44 /* Default value for Voucher Attribute Manager for BANK */ 45 #define BANK_DEFAULT_VALUE NULL 46 #define BANK_DEFAULT_TASK_VALUE ((void *) 1) 47 48 typedef mach_voucher_attr_value_handle_t bank_handle_t __kernel_ptr_semantics; 49 50 #define BANK_TASK 0 51 #define BANK_ACCOUNT 1 52 53 struct bank_element { 54 unsigned int be_type:31, /* Type of element */ 55 be_voucher_ref:1; /* Voucher system holds a ref */ 56 int be_refs; /* Ref count */ 57 unsigned int be_made; /* Made refs for voucher, Actual ref is only taken for voucher ref transition (0 to 1) */ 58 #if DEVELOPMENT || DEBUG 59 task_t be_task; /* Customer task, do not use it since ref is not taken on task */ 60 #endif 61 }; 62 63 typedef struct bank_element * bank_element_t; 64 #define BANK_ELEMENT_NULL ((bank_element_t) 0) 65 66 struct bank_task { 67 struct bank_element bt_elem; /* Bank element */ 68 struct proc_persona_info bt_proc_persona; /* Persona of the process */ 69 ledger_t bt_ledger; /* Ledger of the customer task */ 70 queue_head_t bt_accounts_to_pay; /* List of accounts worked for me and need to pay */ 71 queue_head_t bt_accounts_to_charge; /* List of accounts I did work and need to charge */ 72 decl_lck_mtx_data(, bt_acc_to_pay_lock); /* Lock to protect accounts to pay list */ 73 decl_lck_mtx_data(, bt_acc_to_charge_lock); /* Lock to protect accounts to charge list */ 74 uint32_t bt_hasentitlement:1, /* If the secure persona entitlement is set on the task */ 75 bt_platform_binary:1, /* If the process is a platform binary */ 76 bt_adopt_any_entitled:1; /* If the adopt any persona entitlement is set on the task */ 77 #if CONFIG_THREAD_GROUPS 78 struct thread_group * bt_thread_group; /* Task's home thread group pointer */ 79 #endif 80 #if DEVELOPMENT || DEBUG 81 queue_chain_t bt_global_elt; /* Element on the global bank task chain */ 82 #endif 83 }; 84 85 #define bt_type bt_elem.be_type 86 #define bt_voucher_ref bt_elem.be_voucher_ref 87 #define bt_refs bt_elem.be_refs 88 #define bt_made bt_elem.be_made 89 90 #define bt_flags bt_proc_persona.flags 91 #define bt_unique_pid bt_proc_persona.unique_pid 92 #define bt_pid bt_proc_persona.pid 93 #define bt_pidversion bt_proc_persona.pidversion 94 #define bt_persona_id bt_proc_persona.persona_id 95 #define bt_uid bt_proc_persona.uid 96 #define bt_gid bt_proc_persona.gid 97 #define bt_macho_uuid bt_proc_persona.macho_uuid 98 99 #if DEVELOPMENT || DEBUG 100 #define bt_task bt_elem.be_task 101 #endif 102 103 typedef struct bank_task * bank_task_t; 104 #define BANK_TASK_NULL ((bank_task_t) 0) 105 106 #define bank_task_reference(elem) \ 107 (OSAddAtomic(1, &(elem)->bt_refs)) 108 109 #define bank_task_release(elem) \ 110 (OSAddAtomic(-1, &(elem)->bt_refs)) 111 112 #define bank_task_release_num(elem, num) \ 113 (OSAddAtomic(-(num), &(elem)->bt_refs)) 114 115 #define bank_task_made_reference(elem) \ 116 (os_atomic_inc_orig(&(elem)->bt_made, relaxed)) 117 118 #define bank_task_made_release(elem) \ 119 (os_atomic_dec_orig(&(elem)->bt_made, relaxed)) 120 121 #define bank_task_made_release_num(elem, num) \ 122 (os_atomic_sub_orig(&(elem)->bt_made, (num), relaxed)) 123 124 125 struct bank_account { 126 struct bank_element ba_elem; /* Bank element */ 127 ledger_t ba_bill; /* Temporary ledger i.e. chit */ 128 bank_task_t ba_merchant; /* Task who worked for me, who will charge me on behalf of */ 129 bank_task_t ba_holder; /* Credit Card task holder */ 130 bank_task_t ba_secureoriginator; /* Bank task of the secure originator */ 131 bank_task_t ba_proximateprocess; /* Process who propagated the voucher to us */ 132 queue_chain_t ba_next_acc_to_pay; /* Next account I need to pay to */ 133 queue_chain_t ba_next_acc_to_charge; /* Next account I need to charge to */ 134 #if CONFIG_THREAD_GROUPS 135 struct thread_group * ba_thread_group; /* thread group to be adopted */ 136 #endif 137 #if DEVELOPMENT || DEBUG 138 queue_chain_t ba_global_elt; /* Element on the global account chain */ 139 #endif 140 uint32_t ba_so_persona_id; /* Persona ID of ba_secureoriginator, 141 * unless modified by a entitled process */ 142 }; 143 144 #define ba_type ba_elem.be_type 145 #define ba_voucher_ref ba_elem.be_voucher_ref 146 #define ba_refs ba_elem.be_refs 147 #define ba_made ba_elem.be_made 148 149 #if DEVELOPMENT || DEBUG 150 #define ba_task ba_elem.be_task 151 #endif 152 153 typedef struct bank_account * bank_account_t; 154 #define BANK_ACCOUNT_NULL ((bank_account_t) 0) 155 156 #define bank_account_reference(elem) \ 157 (OSAddAtomic(1, &(elem)->ba_refs)) 158 159 #define bank_account_release(elem) \ 160 (OSAddAtomic(-1, &(elem)->ba_refs)) 161 162 #define bank_account_release_num(elem, num) \ 163 (OSAddAtomic(-(num), &(elem)->ba_refs)) 164 165 #define bank_account_made_reference(elem) \ 166 (os_atomic_inc_orig(&(elem)->ba_made, relaxed)) 167 168 #define bank_account_made_release(elem) \ 169 (os_atomic_dec_orig(&(elem)->ba_made, relaxed)) 170 171 #define bank_account_made_release_num(elem, num) \ 172 (os_atomic_sub_orig(&(elem)->ba_made, (num), relaxed)) 173 174 struct _bank_ledger_indices { 175 int cpu_time; 176 int energy; 177 }; 178 179 extern struct _bank_ledger_indices bank_ledgers; 180 181 extern void bank_init(void); 182 extern void bank_task_destroy(task_t); 183 extern void bank_task_initialize(task_t task); 184 extern void bank_billed_balance_safe(task_t task, uint64_t *cpu_time, uint64_t *energy); 185 extern void bank_billed_balance(bank_task_t bank_task, uint64_t *cpu_time, uint64_t *energy); 186 extern void bank_serviced_balance_safe(task_t task, uint64_t *cpu_time, uint64_t *energy); 187 extern void bank_serviced_balance(bank_task_t bank_task, uint64_t *cpu_time, uint64_t *energy); 188 extern kern_return_t bank_get_bank_ledger_thread_group_and_persona(ipc_voucher_t voucher, 189 ledger_t *bankledger, struct thread_group **banktg, uint32_t *persona_id); 190 extern void bank_swap_thread_bank_ledger(thread_t thread, ledger_t ledger); 191 #if CONFIG_PREADOPT_TG 192 extern kern_return_t 193 bank_get_preadopt_thread_group(ipc_voucher_t voucher, struct thread_group **banktg); 194 #endif 195 196 #endif /* MACH_KERNEL_PRIVATE */ 197 #endif /* _BANK_BANK_INTERNAL_H_ */ 198