Lines Matching +full:async +full:- +full:prefix

1 // SPDX-License-Identifier: GPL-2.0-only
6 * Copyright (C) 2007-2008 Google, Inc.
15 * 1) proc->outer_lock : protects binder_ref
18 * 2) node->lock : protects most fields of binder_node.
21 * 3) proc->inner_lock : protects the thread and node lists
22 * (proc->threads, proc->waiting_threads, proc->nodes)
24 * (proc->todo, thread->todo, proc->delivered_death and
25 * node->async_todo), as well as thread->transaction_stack
35 * foo_olocked() : requires node->outer_lock
36 * foo_nlocked() : requires node->lock
37 * foo_ilocked() : requires proc->inner_lock
38 * foo_oilocked(): requires proc->outer_lock and proc->inner_lock
39 * foo_nilocked(): requires node->lock and proc->inner_lock
173 (ee)->id = _id; \
174 (ee)->command = _command; \
175 (ee)->param = _param; \
232 unsigned int cur = atomic_inc_return(&log->cur); in binder_transaction_log_add()
234 if (cur >= ARRAY_SIZE(log->entry)) in binder_transaction_log_add()
235 log->full = true; in binder_transaction_log_add()
236 e = &log->entry[cur % ARRAY_SIZE(log->entry)]; in binder_transaction_log_add()
237 WRITE_ONCE(e->debug_id_done, 0); in binder_transaction_log_add()
239 * write-barrier to synchronize access to e->debug_id_done. in binder_transaction_log_add()
263 * binder_proc_lock() - Acquire outer lock for given binder_proc
266 * Acquires proc->outer_lock. Used to protect binder_ref
272 __acquires(&proc->outer_lock) in _binder_proc_lock()
276 spin_lock(&proc->outer_lock); in _binder_proc_lock()
280 * binder_proc_unlock() - Release spinlock for given binder_proc
288 __releases(&proc->outer_lock) in _binder_proc_unlock()
292 spin_unlock(&proc->outer_lock); in _binder_proc_unlock()
296 * binder_inner_proc_lock() - Acquire inner lock for given binder_proc
299 * Acquires proc->inner_lock. Used to protect todo lists
304 __acquires(&proc->inner_lock) in _binder_inner_proc_lock()
308 spin_lock(&proc->inner_lock); in _binder_inner_proc_lock()
312 * binder_inner_proc_unlock() - Release inner lock for given binder_proc
320 __releases(&proc->inner_lock) in _binder_inner_proc_unlock()
324 spin_unlock(&proc->inner_lock); in _binder_inner_proc_unlock()
328 * binder_node_lock() - Acquire spinlock for given binder_node
331 * Acquires node->lock. Used to protect binder_node fields
336 __acquires(&node->lock) in _binder_node_lock()
340 spin_lock(&node->lock); in _binder_node_lock()
344 * binder_node_unlock() - Release spinlock for given binder_proc
352 __releases(&node->lock) in _binder_node_unlock()
356 spin_unlock(&node->lock); in _binder_node_unlock()
360 * binder_node_inner_lock() - Acquire node and inner locks
363 * Acquires node->lock. If node->proc also acquires
364 * proc->inner_lock. Used to protect binder_node fields
369 __acquires(&node->lock) __acquires(&node->proc->inner_lock) in _binder_node_inner_lock()
373 spin_lock(&node->lock); in _binder_node_inner_lock()
374 if (node->proc) in _binder_node_inner_lock()
375 binder_inner_proc_lock(node->proc); in _binder_node_inner_lock()
378 __acquire(&node->proc->inner_lock); in _binder_node_inner_lock()
382 * binder_node_inner_unlock() - Release node and inner locks
390 __releases(&node->lock) __releases(&node->proc->inner_lock) in _binder_node_inner_unlock()
392 struct binder_proc *proc = node->proc; in _binder_node_inner_unlock()
400 __release(&node->proc->inner_lock); in _binder_node_inner_unlock()
401 spin_unlock(&node->lock); in _binder_node_inner_unlock()
410 * binder_worklist_empty() - Check if no items on the work list
428 * binder_enqueue_work_ilocked() - Add an item to the work list
435 * Requires the proc->inner_lock to be held.
442 BUG_ON(work->entry.next && !list_empty(&work->entry)); in binder_enqueue_work_ilocked()
443 list_add_tail(&work->entry, target_list); in binder_enqueue_work_ilocked()
447 * binder_enqueue_deferred_thread_work_ilocked() - Add deferred thread work
455 * Requires the proc->inner_lock to be held.
461 WARN_ON(!list_empty(&thread->waiting_thread_node)); in binder_enqueue_deferred_thread_work_ilocked()
462 binder_enqueue_work_ilocked(work, &thread->todo); in binder_enqueue_deferred_thread_work_ilocked()
466 * binder_enqueue_thread_work_ilocked() - Add an item to the thread work list
473 * Requires the proc->inner_lock to be held.
479 WARN_ON(!list_empty(&thread->waiting_thread_node)); in binder_enqueue_thread_work_ilocked()
480 binder_enqueue_work_ilocked(work, &thread->todo); in binder_enqueue_thread_work_ilocked()
482 /* (e)poll-based threads require an explicit wakeup signal when in binder_enqueue_thread_work_ilocked()
487 if (thread->looper & BINDER_LOOPER_STATE_POLL && in binder_enqueue_thread_work_ilocked()
488 thread->pid == current->pid && !thread->process_todo) in binder_enqueue_thread_work_ilocked()
489 wake_up_interruptible_sync(&thread->wait); in binder_enqueue_thread_work_ilocked()
491 thread->process_todo = true; in binder_enqueue_thread_work_ilocked()
495 * binder_enqueue_thread_work() - Add an item to the thread work list
506 binder_inner_proc_lock(thread->proc); in binder_enqueue_thread_work()
508 binder_inner_proc_unlock(thread->proc); in binder_enqueue_thread_work()
514 list_del_init(&work->entry); in binder_dequeue_work_ilocked()
518 * binder_dequeue_work() - Removes an item from the work list
540 list_del_init(&w->entry); in binder_dequeue_work_head_ilocked()
553 return thread->process_todo || in binder_has_work_ilocked()
554 thread->looper_need_return || in binder_has_work_ilocked()
556 !binder_worklist_empty_ilocked(&thread->proc->todo)); in binder_has_work_ilocked()
563 binder_inner_proc_lock(thread->proc); in binder_has_work()
565 binder_inner_proc_unlock(thread->proc); in binder_has_work()
572 return !thread->transaction_stack && in binder_available_for_proc_work_ilocked()
573 binder_worklist_empty_ilocked(&thread->todo) && in binder_available_for_proc_work_ilocked()
574 (thread->looper & (BINDER_LOOPER_STATE_ENTERED | in binder_available_for_proc_work_ilocked()
584 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in binder_wakeup_poll_threads_ilocked()
586 if (thread->looper & BINDER_LOOPER_STATE_POLL && in binder_wakeup_poll_threads_ilocked()
589 wake_up_interruptible_sync(&thread->wait); in binder_wakeup_poll_threads_ilocked()
591 wake_up_interruptible(&thread->wait); in binder_wakeup_poll_threads_ilocked()
597 * binder_select_thread_ilocked() - selects a thread for doing proc work.
613 assert_spin_locked(&proc->inner_lock); in binder_select_thread_ilocked()
614 thread = list_first_entry_or_null(&proc->waiting_threads, in binder_select_thread_ilocked()
619 list_del_init(&thread->waiting_thread_node); in binder_select_thread_ilocked()
625 * binder_wakeup_thread_ilocked() - wakes up a thread for doing proc work.
627 * @thread: specific thread to wake-up (may be NULL)
628 * @sync: whether to do a synchronous wake-up
631 * The caller may provide a specific thread to wake-up in
644 assert_spin_locked(&proc->inner_lock); in binder_wakeup_thread_ilocked()
648 wake_up_interruptible_sync(&thread->wait); in binder_wakeup_thread_ilocked()
650 wake_up_interruptible(&thread->wait); in binder_wakeup_thread_ilocked()
664 * a thread that called into (e)poll is handling non-binder in binder_wakeup_thread_ilocked()
688 current->pid, nice, min_nice); in binder_set_nice()
692 binder_user_error("%d RLIMIT_NICE not set\n", current->pid); in binder_set_nice()
698 struct rb_node *n = proc->nodes.rb_node; in binder_get_node_ilocked()
701 assert_spin_locked(&proc->inner_lock); in binder_get_node_ilocked()
706 if (ptr < node->ptr) in binder_get_node_ilocked()
707 n = n->rb_left; in binder_get_node_ilocked()
708 else if (ptr > node->ptr) in binder_get_node_ilocked()
709 n = n->rb_right; in binder_get_node_ilocked()
739 struct rb_node **p = &proc->nodes.rb_node; in binder_init_node_ilocked()
742 binder_uintptr_t ptr = fp ? fp->binder : 0; in binder_init_node_ilocked()
743 binder_uintptr_t cookie = fp ? fp->cookie : 0; in binder_init_node_ilocked()
744 __u32 flags = fp ? fp->flags : 0; in binder_init_node_ilocked()
746 assert_spin_locked(&proc->inner_lock); in binder_init_node_ilocked()
753 if (ptr < node->ptr) in binder_init_node_ilocked()
754 p = &(*p)->rb_left; in binder_init_node_ilocked()
755 else if (ptr > node->ptr) in binder_init_node_ilocked()
756 p = &(*p)->rb_right; in binder_init_node_ilocked()
769 node->tmp_refs++; in binder_init_node_ilocked()
770 rb_link_node(&node->rb_node, parent, p); in binder_init_node_ilocked()
771 rb_insert_color(&node->rb_node, &proc->nodes); in binder_init_node_ilocked()
772 node->debug_id = atomic_inc_return(&binder_last_id); in binder_init_node_ilocked()
773 node->proc = proc; in binder_init_node_ilocked()
774 node->ptr = ptr; in binder_init_node_ilocked()
775 node->cookie = cookie; in binder_init_node_ilocked()
776 node->work.type = BINDER_WORK_NODE; in binder_init_node_ilocked()
777 node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; in binder_init_node_ilocked()
778 node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); in binder_init_node_ilocked()
779 node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX); in binder_init_node_ilocked()
780 spin_lock_init(&node->lock); in binder_init_node_ilocked()
781 INIT_LIST_HEAD(&node->work.entry); in binder_init_node_ilocked()
782 INIT_LIST_HEAD(&node->async_todo); in binder_init_node_ilocked()
785 proc->pid, current->pid, node->debug_id, in binder_init_node_ilocked()
786 (u64)node->ptr, (u64)node->cookie); in binder_init_node_ilocked()
821 struct binder_proc *proc = node->proc; in binder_inc_node_nilocked()
823 assert_spin_locked(&node->lock); in binder_inc_node_nilocked()
825 assert_spin_locked(&proc->inner_lock); in binder_inc_node_nilocked()
829 node->internal_strong_refs == 0 && in binder_inc_node_nilocked()
830 !(node->proc && in binder_inc_node_nilocked()
831 node == node->proc->context->binder_context_mgr_node && in binder_inc_node_nilocked()
832 node->has_strong_ref)) { in binder_inc_node_nilocked()
834 node->debug_id); in binder_inc_node_nilocked()
835 return -EINVAL; in binder_inc_node_nilocked()
837 node->internal_strong_refs++; in binder_inc_node_nilocked()
839 node->local_strong_refs++; in binder_inc_node_nilocked()
840 if (!node->has_strong_ref && target_list) { in binder_inc_node_nilocked()
843 binder_dequeue_work_ilocked(&node->work); in binder_inc_node_nilocked()
844 BUG_ON(&thread->todo != target_list); in binder_inc_node_nilocked()
846 &node->work); in binder_inc_node_nilocked()
850 node->local_weak_refs++; in binder_inc_node_nilocked()
851 if (!node->has_weak_ref && list_empty(&node->work.entry)) { in binder_inc_node_nilocked()
854 node->debug_id); in binder_inc_node_nilocked()
855 return -EINVAL; in binder_inc_node_nilocked()
860 binder_enqueue_work_ilocked(&node->work, target_list); in binder_inc_node_nilocked()
881 struct binder_proc *proc = node->proc; in binder_dec_node_nilocked()
883 assert_spin_locked(&node->lock); in binder_dec_node_nilocked()
885 assert_spin_locked(&proc->inner_lock); in binder_dec_node_nilocked()
888 node->internal_strong_refs--; in binder_dec_node_nilocked()
890 node->local_strong_refs--; in binder_dec_node_nilocked()
891 if (node->local_strong_refs || node->internal_strong_refs) in binder_dec_node_nilocked()
895 node->local_weak_refs--; in binder_dec_node_nilocked()
896 if (node->local_weak_refs || node->tmp_refs || in binder_dec_node_nilocked()
897 !hlist_empty(&node->refs)) in binder_dec_node_nilocked()
901 if (proc && (node->has_strong_ref || node->has_weak_ref)) { in binder_dec_node_nilocked()
902 if (list_empty(&node->work.entry)) { in binder_dec_node_nilocked()
903 binder_enqueue_work_ilocked(&node->work, &proc->todo); in binder_dec_node_nilocked()
907 if (hlist_empty(&node->refs) && !node->local_strong_refs && in binder_dec_node_nilocked()
908 !node->local_weak_refs && !node->tmp_refs) { in binder_dec_node_nilocked()
910 binder_dequeue_work_ilocked(&node->work); in binder_dec_node_nilocked()
911 rb_erase(&node->rb_node, &proc->nodes); in binder_dec_node_nilocked()
914 node->debug_id); in binder_dec_node_nilocked()
916 BUG_ON(!list_empty(&node->work.entry)); in binder_dec_node_nilocked()
922 if (node->tmp_refs) { in binder_dec_node_nilocked()
926 hlist_del(&node->dead_node); in binder_dec_node_nilocked()
930 node->debug_id); in binder_dec_node_nilocked()
956 node->tmp_refs++; in binder_inc_node_tmpref_ilocked()
960 * binder_inc_node_tmpref() - take a temporary reference on node
967 * (node->proc is NULL), use binder_dead_nodes_lock to protect
968 * node->tmp_refs against dead-node-only cases where the node
975 if (node->proc) in binder_inc_node_tmpref()
976 binder_inner_proc_lock(node->proc); in binder_inc_node_tmpref()
980 if (node->proc) in binder_inc_node_tmpref()
981 binder_inner_proc_unlock(node->proc); in binder_inc_node_tmpref()
988 * binder_dec_node_tmpref() - remove a temporary reference on node
998 if (!node->proc) in binder_dec_node_tmpref()
1002 node->tmp_refs--; in binder_dec_node_tmpref()
1003 BUG_ON(node->tmp_refs < 0); in binder_dec_node_tmpref()
1004 if (!node->proc) in binder_dec_node_tmpref()
1028 struct rb_node *n = proc->refs_by_desc.rb_node; in binder_get_ref_olocked()
1034 if (desc < ref->data.desc) { in binder_get_ref_olocked()
1035 n = n->rb_left; in binder_get_ref_olocked()
1036 } else if (desc > ref->data.desc) { in binder_get_ref_olocked()
1037 n = n->rb_right; in binder_get_ref_olocked()
1038 } else if (need_strong_ref && !ref->data.strong) { in binder_get_ref_olocked()
1049 * binder_get_ref_for_node_olocked() - get the ref associated with given node
1062 * returned ref would be different than the passed-in
1071 struct binder_context *context = proc->context; in binder_get_ref_for_node_olocked()
1072 struct rb_node **p = &proc->refs_by_node.rb_node; in binder_get_ref_for_node_olocked()
1081 if (node < ref->node) in binder_get_ref_for_node_olocked()
1082 p = &(*p)->rb_left; in binder_get_ref_for_node_olocked()
1083 else if (node > ref->node) in binder_get_ref_for_node_olocked()
1084 p = &(*p)->rb_right; in binder_get_ref_for_node_olocked()
1092 new_ref->data.debug_id = atomic_inc_return(&binder_last_id); in binder_get_ref_for_node_olocked()
1093 new_ref->proc = proc; in binder_get_ref_for_node_olocked()
1094 new_ref->node = node; in binder_get_ref_for_node_olocked()
1095 rb_link_node(&new_ref->rb_node_node, parent, p); in binder_get_ref_for_node_olocked()
1096 rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); in binder_get_ref_for_node_olocked()
1098 new_ref->data.desc = (node == context->binder_context_mgr_node) ? 0 : 1; in binder_get_ref_for_node_olocked()
1099 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { in binder_get_ref_for_node_olocked()
1101 if (ref->data.desc > new_ref->data.desc) in binder_get_ref_for_node_olocked()
1103 new_ref->data.desc = ref->data.desc + 1; in binder_get_ref_for_node_olocked()
1106 p = &proc->refs_by_desc.rb_node; in binder_get_ref_for_node_olocked()
1111 if (new_ref->data.desc < ref->data.desc) in binder_get_ref_for_node_olocked()
1112 p = &(*p)->rb_left; in binder_get_ref_for_node_olocked()
1113 else if (new_ref->data.desc > ref->data.desc) in binder_get_ref_for_node_olocked()
1114 p = &(*p)->rb_right; in binder_get_ref_for_node_olocked()
1118 rb_link_node(&new_ref->rb_node_desc, parent, p); in binder_get_ref_for_node_olocked()
1119 rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); in binder_get_ref_for_node_olocked()
1122 hlist_add_head(&new_ref->node_entry, &node->refs); in binder_get_ref_for_node_olocked()
1126 proc->pid, new_ref->data.debug_id, new_ref->data.desc, in binder_get_ref_for_node_olocked()
1127 node->debug_id); in binder_get_ref_for_node_olocked()
1138 ref->proc->pid, ref->data.debug_id, ref->data.desc, in binder_cleanup_ref_olocked()
1139 ref->node->debug_id); in binder_cleanup_ref_olocked()
1141 rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); in binder_cleanup_ref_olocked()
1142 rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); in binder_cleanup_ref_olocked()
1144 binder_node_inner_lock(ref->node); in binder_cleanup_ref_olocked()
1145 if (ref->data.strong) in binder_cleanup_ref_olocked()
1146 binder_dec_node_nilocked(ref->node, 1, 1); in binder_cleanup_ref_olocked()
1148 hlist_del(&ref->node_entry); in binder_cleanup_ref_olocked()
1149 delete_node = binder_dec_node_nilocked(ref->node, 0, 1); in binder_cleanup_ref_olocked()
1150 binder_node_inner_unlock(ref->node); in binder_cleanup_ref_olocked()
1152 * Clear ref->node unless we want the caller to free the node in binder_cleanup_ref_olocked()
1156 * The caller uses ref->node to determine in binder_cleanup_ref_olocked()
1160 ref->node = NULL; in binder_cleanup_ref_olocked()
1163 if (ref->death) { in binder_cleanup_ref_olocked()
1166 ref->proc->pid, ref->data.debug_id, in binder_cleanup_ref_olocked()
1167 ref->data.desc); in binder_cleanup_ref_olocked()
1168 binder_dequeue_work(ref->proc, &ref->death->work); in binder_cleanup_ref_olocked()
1175 * binder_inc_ref_olocked() - increment the ref for given handle
1180 * Increment the ref. @ref->proc->outer_lock must be held on entry
1190 if (ref->data.strong == 0) { in binder_inc_ref_olocked()
1191 ret = binder_inc_node(ref->node, 1, 1, target_list); in binder_inc_ref_olocked()
1195 ref->data.strong++; in binder_inc_ref_olocked()
1197 if (ref->data.weak == 0) { in binder_inc_ref_olocked()
1198 ret = binder_inc_node(ref->node, 0, 1, target_list); in binder_inc_ref_olocked()
1202 ref->data.weak++; in binder_inc_ref_olocked()
1208 * binder_dec_ref_olocked() - dec the ref for given handle
1219 if (ref->data.strong == 0) { in binder_dec_ref_olocked()
1221 ref->proc->pid, ref->data.debug_id, in binder_dec_ref_olocked()
1222 ref->data.desc, ref->data.strong, in binder_dec_ref_olocked()
1223 ref->data.weak); in binder_dec_ref_olocked()
1226 ref->data.strong--; in binder_dec_ref_olocked()
1227 if (ref->data.strong == 0) in binder_dec_ref_olocked()
1228 binder_dec_node(ref->node, strong, 1); in binder_dec_ref_olocked()
1230 if (ref->data.weak == 0) { in binder_dec_ref_olocked()
1232 ref->proc->pid, ref->data.debug_id, in binder_dec_ref_olocked()
1233 ref->data.desc, ref->data.strong, in binder_dec_ref_olocked()
1234 ref->data.weak); in binder_dec_ref_olocked()
1237 ref->data.weak--; in binder_dec_ref_olocked()
1239 if (ref->data.strong == 0 && ref->data.weak == 0) { in binder_dec_ref_olocked()
1247 * binder_get_node_from_ref() - get the node from the given proc/desc
1269 node = ref->node; in binder_get_node_from_ref()
1276 *rdata = ref->data; in binder_get_node_from_ref()
1287 * binder_free_ref() - free the binder_ref
1290 * Free the binder_ref. Free the binder_node indicated by ref->node
1291 * (if non-NULL) and the binder_ref_death indicated by ref->death.
1295 if (ref->node) in binder_free_ref()
1296 binder_free_node(ref->node); in binder_free_ref()
1297 kfree(ref->death); in binder_free_ref()
1302 * binder_update_ref_for_handle() - inc/dec the ref for given handle
1325 ret = -EINVAL; in binder_update_ref_for_handle()
1334 *rdata = ref->data; in binder_update_ref_for_handle()
1347 * binder_dec_ref_for_handle() - dec the ref for given handle
1365 * binder_inc_ref_for_node() - increment the ref for given proc/node
1393 return -ENOMEM; in binder_inc_ref_for_node()
1398 *rdata = ref->data; in binder_inc_ref_for_node()
1425 assert_spin_locked(&target_thread->proc->inner_lock); in binder_pop_transaction_ilocked()
1426 BUG_ON(target_thread->transaction_stack != t); in binder_pop_transaction_ilocked()
1427 BUG_ON(target_thread->transaction_stack->from != target_thread); in binder_pop_transaction_ilocked()
1428 target_thread->transaction_stack = in binder_pop_transaction_ilocked()
1429 target_thread->transaction_stack->from_parent; in binder_pop_transaction_ilocked()
1430 t->from = NULL; in binder_pop_transaction_ilocked()
1434 * binder_thread_dec_tmpref() - decrement thread->tmp_ref
1439 * extract t->from from a binder_transaction and keep the thread
1440 * indicated by t->from from being freed. When done with that
1449 * it cannot reach zero or thread->is_dead is false in binder_thread_dec_tmpref()
1451 binder_inner_proc_lock(thread->proc); in binder_thread_dec_tmpref()
1452 atomic_dec(&thread->tmp_ref); in binder_thread_dec_tmpref()
1453 if (thread->is_dead && !atomic_read(&thread->tmp_ref)) { in binder_thread_dec_tmpref()
1454 binder_inner_proc_unlock(thread->proc); in binder_thread_dec_tmpref()
1458 binder_inner_proc_unlock(thread->proc); in binder_thread_dec_tmpref()
1462 * binder_proc_dec_tmpref() - decrement proc->tmp_ref
1466 * handle a transaction. proc->tmp_ref is incremented when
1467 * creating a new transaction or the binder_proc is currently in-use
1471 * been released and not currenly in-use to process a transaction).
1476 proc->tmp_ref--; in binder_proc_dec_tmpref()
1477 if (proc->is_dead && RB_EMPTY_ROOT(&proc->threads) && in binder_proc_dec_tmpref()
1478 !proc->tmp_ref) { in binder_proc_dec_tmpref()
1487 * binder_get_txn_from() - safely extract the "from" thread in transaction
1488 * @t: binder transaction for t->from
1494 * Return: the value of t->from
1501 spin_lock(&t->lock); in binder_get_txn_from()
1502 from = t->from; in binder_get_txn_from()
1504 atomic_inc(&from->tmp_ref); in binder_get_txn_from()
1505 spin_unlock(&t->lock); in binder_get_txn_from()
1510 * binder_get_txn_from_and_acq_inner() - get t->from and acquire inner lock
1511 * @t: binder transaction for t->from
1513 * Same as binder_get_txn_from() except it also acquires the proc->inner_lock
1518 * Return: the value of t->from
1522 __acquires(&t->from->proc->inner_lock) in binder_get_txn_from_and_acq_inner()
1528 __acquire(&from->proc->inner_lock); in binder_get_txn_from_and_acq_inner()
1531 binder_inner_proc_lock(from->proc); in binder_get_txn_from_and_acq_inner()
1532 if (t->from) { in binder_get_txn_from_and_acq_inner()
1533 BUG_ON(from != t->from); in binder_get_txn_from_and_acq_inner()
1536 binder_inner_proc_unlock(from->proc); in binder_get_txn_from_and_acq_inner()
1537 __acquire(&from->proc->inner_lock); in binder_get_txn_from_and_acq_inner()
1543 * binder_free_txn_fixups() - free unprocessed fd fixups
1544 * @t: binder transaction for t->from
1550 * processed -- in that case, the list will be empty.
1556 list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { in binder_free_txn_fixups()
1557 fput(fixup->file); in binder_free_txn_fixups()
1558 if (fixup->target_fd >= 0) in binder_free_txn_fixups()
1559 put_unused_fd(fixup->target_fd); in binder_free_txn_fixups()
1560 list_del(&fixup->fixup_entry); in binder_free_txn_fixups()
1569 spin_lock(&t->lock); in binder_txn_latency_free()
1570 from_proc = t->from ? t->from->proc->pid : 0; in binder_txn_latency_free()
1571 from_thread = t->from ? t->from->pid : 0; in binder_txn_latency_free()
1572 to_proc = t->to_proc ? t->to_proc->pid : 0; in binder_txn_latency_free()
1573 to_thread = t->to_thread ? t->to_thread->pid : 0; in binder_txn_latency_free()
1574 spin_unlock(&t->lock); in binder_txn_latency_free()
1581 struct binder_proc *target_proc = t->to_proc; in binder_free_transaction()
1585 target_proc->outstanding_txns--; in binder_free_transaction()
1586 if (target_proc->outstanding_txns < 0) in binder_free_transaction()
1588 __func__, target_proc->outstanding_txns); in binder_free_transaction()
1589 if (!target_proc->outstanding_txns && target_proc->is_frozen) in binder_free_transaction()
1590 wake_up_interruptible_all(&target_proc->freeze_wait); in binder_free_transaction()
1591 if (t->buffer) in binder_free_transaction()
1592 t->buffer->transaction = NULL; in binder_free_transaction()
1599 * t->buffer->transaction has already been cleared. in binder_free_transaction()
1612 BUG_ON(t->flags & TF_ONE_WAY); in binder_send_failed_reply()
1618 t->debug_id, in binder_send_failed_reply()
1619 target_thread->proc->pid, in binder_send_failed_reply()
1620 target_thread->pid); in binder_send_failed_reply()
1623 if (target_thread->reply_error.cmd == BR_OK) { in binder_send_failed_reply()
1624 target_thread->reply_error.cmd = error_code; in binder_send_failed_reply()
1627 &target_thread->reply_error.work); in binder_send_failed_reply()
1628 wake_up_interruptible(&target_thread->wait); in binder_send_failed_reply()
1637 target_thread->reply_error.cmd); in binder_send_failed_reply()
1639 binder_inner_proc_unlock(target_thread->proc); in binder_send_failed_reply()
1644 __release(&target_thread->proc->inner_lock); in binder_send_failed_reply()
1645 next = t->from_parent; in binder_send_failed_reply()
1649 t->debug_id); in binder_send_failed_reply()
1659 "reply failed, no target thread -- retry %d\n", in binder_send_failed_reply()
1660 t->debug_id); in binder_send_failed_reply()
1665 * binder_cleanup_transaction() - cleans up undelivered transaction
1674 if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) { in binder_cleanup_transaction()
1679 t->debug_id, reason); in binder_cleanup_transaction()
1685 * binder_get_object() - gets object and checks for valid metadata
1710 read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); in binder_get_object()
1711 if (offset > buffer->data_size || read_size < sizeof(*hdr)) in binder_get_object()
1717 if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, in binder_get_object()
1723 hdr = &object->hdr; in binder_get_object()
1724 switch (hdr->type) { in binder_get_object()
1743 if (offset <= buffer->data_size - object_size && in binder_get_object()
1744 buffer->data_size >= object_size) in binder_get_object()
1751 * binder_validate_ptr() - validates binder_buffer_object in a binder_buffer.
1769 * If @object_offsetp is non-NULL, then the offset within
1789 if (binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, in binder_validate_ptr()
1794 if (!object_size || object->hdr.type != BINDER_TYPE_PTR) in binder_validate_ptr()
1799 return &object->bbo; in binder_validate_ptr()
1803 * binder_validate_fixup() - validates pointer/fd fixups happen in order.
1869 if ((last_bbo->flags & BINDER_BUFFER_FLAG_HAS_PARENT) == 0) in binder_validate_fixup()
1871 last_min_offset = last_bbo->parent_offset + sizeof(uintptr_t); in binder_validate_fixup()
1873 sizeof(binder_size_t) * last_bbo->parent; in binder_validate_fixup()
1874 if (binder_alloc_copy_from_buffer(&proc->alloc, in binder_validate_fixup()
1884 * struct binder_task_work_cb - for deferred close
1898 * binder_do_fd_close() - close list of file descriptors
1915 fput(twcb->file); in binder_do_fd_close()
1920 * binder_deferred_fd_close() - schedule a close for the given file-descriptor
1921 * @fd: file-descriptor to close
1924 * a file-descriptor to be closed after returning from binder_ioctl().
1933 init_task_work(&twcb->twork, binder_do_fd_close); in binder_deferred_fd_close()
1934 twcb->file = file_close_fd(fd); in binder_deferred_fd_close()
1935 if (twcb->file) { in binder_deferred_fd_close()
1937 get_file(twcb->file); in binder_deferred_fd_close()
1938 filp_close(twcb->file, current->files); in binder_deferred_fd_close()
1939 task_work_add(current, &twcb->twork, TWA_RESUME); in binder_deferred_fd_close()
1951 int debug_id = buffer->debug_id; in binder_transaction_buffer_release()
1955 "%d buffer release %d, size %zd-%zd, failed at %llx\n", in binder_transaction_buffer_release()
1956 proc->pid, buffer->debug_id, in binder_transaction_buffer_release()
1957 buffer->data_size, buffer->offsets_size, in binder_transaction_buffer_release()
1960 if (buffer->target_node) in binder_transaction_buffer_release()
1961 binder_dec_node(buffer->target_node, 1, 0); in binder_transaction_buffer_release()
1963 off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); in binder_transaction_buffer_release()
1972 if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, in binder_transaction_buffer_release()
1979 debug_id, (u64)object_offset, buffer->data_size); in binder_transaction_buffer_release()
1983 switch (hdr->type) { in binder_transaction_buffer_release()
1990 node = binder_get_node(proc, fp->binder); in binder_transaction_buffer_release()
1993 debug_id, (u64)fp->binder); in binder_transaction_buffer_release()
1998 node->debug_id, (u64)node->ptr); in binder_transaction_buffer_release()
1999 binder_dec_node(node, hdr->type == BINDER_TYPE_BINDER, in binder_transaction_buffer_release()
2010 ret = binder_dec_ref_for_handle(proc, fp->handle, in binder_transaction_buffer_release()
2011 hdr->type == BINDER_TYPE_HANDLE, &rdata); in binder_transaction_buffer_release()
2015 debug_id, fp->handle, ret); in binder_transaction_buffer_release()
2025 * No need to close the file here since user-space in binder_transaction_buffer_release()
2057 num_valid = (buffer_offset - off_start_offset) / in binder_transaction_buffer_release()
2061 fda->parent, in binder_transaction_buffer_release()
2070 fd_buf_size = sizeof(u32) * fda->num_fds; in binder_transaction_buffer_release()
2071 if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { in binder_transaction_buffer_release()
2073 debug_id, (u64)fda->num_fds); in binder_transaction_buffer_release()
2076 if (fd_buf_size > parent->length || in binder_transaction_buffer_release()
2077 fda->parent_offset > parent->length - fd_buf_size) { in binder_transaction_buffer_release()
2080 debug_id, (u64)fda->num_fds); in binder_transaction_buffer_release()
2085 * to user-space and the @buffer element is the user in binder_transaction_buffer_release()
2090 fda_offset = parent->buffer - buffer->user_data + in binder_transaction_buffer_release()
2091 fda->parent_offset; in binder_transaction_buffer_release()
2092 for (fd_index = 0; fd_index < fda->num_fds; in binder_transaction_buffer_release()
2100 &proc->alloc, &fd, buffer, in binder_transaction_buffer_release()
2111 thread->looper_need_return = true; in binder_transaction_buffer_release()
2117 debug_id, hdr->type); in binder_transaction_buffer_release()
2131 off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); in binder_release_entire_buffer()
2132 off_end_offset += buffer->offsets_size; in binder_release_entire_buffer()
2143 struct binder_proc *proc = thread->proc; in binder_translate_binder()
2144 struct binder_proc *target_proc = t->to_proc; in binder_translate_binder()
2148 node = binder_get_node(proc, fp->binder); in binder_translate_binder()
2152 return -ENOMEM; in binder_translate_binder()
2154 if (fp->cookie != node->cookie) { in binder_translate_binder()
2156 proc->pid, thread->pid, (u64)fp->binder, in binder_translate_binder()
2157 node->debug_id, (u64)fp->cookie, in binder_translate_binder()
2158 (u64)node->cookie); in binder_translate_binder()
2159 ret = -EINVAL; in binder_translate_binder()
2162 if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { in binder_translate_binder()
2163 ret = -EPERM; in binder_translate_binder()
2168 fp->hdr.type == BINDER_TYPE_BINDER, in binder_translate_binder()
2169 &thread->todo, &rdata); in binder_translate_binder()
2173 if (fp->hdr.type == BINDER_TYPE_BINDER) in binder_translate_binder()
2174 fp->hdr.type = BINDER_TYPE_HANDLE; in binder_translate_binder()
2176 fp->hdr.type = BINDER_TYPE_WEAK_HANDLE; in binder_translate_binder()
2177 fp->binder = 0; in binder_translate_binder()
2178 fp->handle = rdata.desc; in binder_translate_binder()
2179 fp->cookie = 0; in binder_translate_binder()
2183 " node %d u%016llx -> ref %d desc %d\n", in binder_translate_binder()
2184 node->debug_id, (u64)node->ptr, in binder_translate_binder()
2195 struct binder_proc *proc = thread->proc; in binder_translate_handle()
2196 struct binder_proc *target_proc = t->to_proc; in binder_translate_handle()
2201 node = binder_get_node_from_ref(proc, fp->handle, in binder_translate_handle()
2202 fp->hdr.type == BINDER_TYPE_HANDLE, &src_rdata); in binder_translate_handle()
2205 proc->pid, thread->pid, fp->handle); in binder_translate_handle()
2206 return -EINVAL; in binder_translate_handle()
2208 if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { in binder_translate_handle()
2209 ret = -EPERM; in binder_translate_handle()
2214 if (node->proc == target_proc) { in binder_translate_handle()
2215 if (fp->hdr.type == BINDER_TYPE_HANDLE) in binder_translate_handle()
2216 fp->hdr.type = BINDER_TYPE_BINDER; in binder_translate_handle()
2218 fp->hdr.type = BINDER_TYPE_WEAK_BINDER; in binder_translate_handle()
2219 fp->binder = node->ptr; in binder_translate_handle()
2220 fp->cookie = node->cookie; in binder_translate_handle()
2221 if (node->proc) in binder_translate_handle()
2222 binder_inner_proc_lock(node->proc); in binder_translate_handle()
2224 __acquire(&node->proc->inner_lock); in binder_translate_handle()
2226 fp->hdr.type == BINDER_TYPE_BINDER, in binder_translate_handle()
2228 if (node->proc) in binder_translate_handle()
2229 binder_inner_proc_unlock(node->proc); in binder_translate_handle()
2231 __release(&node->proc->inner_lock); in binder_translate_handle()
2234 " ref %d desc %d -> node %d u%016llx\n", in binder_translate_handle()
2235 src_rdata.debug_id, src_rdata.desc, node->debug_id, in binder_translate_handle()
2236 (u64)node->ptr); in binder_translate_handle()
2243 fp->hdr.type == BINDER_TYPE_HANDLE, in binder_translate_handle()
2248 fp->binder = 0; in binder_translate_handle()
2249 fp->handle = dest_rdata.desc; in binder_translate_handle()
2250 fp->cookie = 0; in binder_translate_handle()
2254 " ref %d desc %d -> ref %d desc %d (node %d)\n", in binder_translate_handle()
2257 node->debug_id); in binder_translate_handle()
2269 struct binder_proc *proc = thread->proc; in binder_translate_fd()
2270 struct binder_proc *target_proc = t->to_proc; in binder_translate_fd()
2277 target_allows_fd = !!(in_reply_to->flags & TF_ACCEPT_FDS); in binder_translate_fd()
2279 target_allows_fd = t->buffer->target_node->accept_fds; in binder_translate_fd()
2282 proc->pid, thread->pid, in binder_translate_fd()
2285 ret = -EPERM; in binder_translate_fd()
2292 proc->pid, thread->pid, fd); in binder_translate_fd()
2293 ret = -EBADF; in binder_translate_fd()
2296 ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); in binder_translate_fd()
2298 ret = -EPERM; in binder_translate_fd()
2309 ret = -ENOMEM; in binder_translate_fd()
2312 fixup->file = file; in binder_translate_fd()
2313 fixup->offset = fd_offset; in binder_translate_fd()
2314 fixup->target_fd = -1; in binder_translate_fd()
2315 trace_binder_transaction_fd_send(t, fd, fixup->offset); in binder_translate_fd()
2316 list_add_tail(&fixup->fixup_entry, &t->fd_fixups); in binder_translate_fd()
2329 * struct binder_ptr_fixup - data to be fixed-up in target buffer
2349 * struct binder_sg_copy - scatter-gather data to be copied
2369 * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
2372 * @sgc_head: list_head of scatter-gather copy list
2376 * and copying the scatter-gather data from the source process' user
2381 * Return: 0=success, else -errno
2398 while (bytes_copied < sgc->length) { in binder_do_deferred_txn_copies()
2400 size_t bytes_left = sgc->length - bytes_copied; in binder_do_deferred_txn_copies()
2401 size_t offset = sgc->offset + bytes_copied; in binder_do_deferred_txn_copies()
2406 copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset) in binder_do_deferred_txn_copies()
2412 sgc->sender_uaddr + bytes_copied, in binder_do_deferred_txn_copies()
2418 if (pf->skip_size) { in binder_do_deferred_txn_copies()
2425 bytes_copied += pf->skip_size; in binder_do_deferred_txn_copies()
2431 pf->offset, in binder_do_deferred_txn_copies()
2432 &pf->fixup_data, in binder_do_deferred_txn_copies()
2433 sizeof(pf->fixup_data)); in binder_do_deferred_txn_copies()
2434 bytes_copied += sizeof(pf->fixup_data); in binder_do_deferred_txn_copies()
2436 list_del(&pf->node); in binder_do_deferred_txn_copies()
2442 list_del(&sgc->node); in binder_do_deferred_txn_copies()
2446 BUG_ON(pf->skip_size == 0); in binder_do_deferred_txn_copies()
2447 list_del(&pf->node); in binder_do_deferred_txn_copies()
2452 return ret > 0 ? -EINVAL : ret; in binder_do_deferred_txn_copies()
2456 * binder_cleanup_deferred_txn_lists() - free specified lists
2457 * @sgc_head: list_head of scatter-gather copy list
2470 list_del(&sgc->node); in binder_cleanup_deferred_txn_lists()
2474 list_del(&pf->node); in binder_cleanup_deferred_txn_lists()
2480 * binder_defer_copy() - queue a scatter-gather buffer for copy
2481 * @sgc_head: list_head of scatter-gather copy list
2486 * Specify a scatter-gather block to be copied. The actual copy must
2488 * Then the copy and fixups are done together so un-translated values
2495 * Return: 0=success, else -errno
2503 return -ENOMEM; in binder_defer_copy()
2505 bc->offset = offset; in binder_defer_copy()
2506 bc->sender_uaddr = sender_uaddr; in binder_defer_copy()
2507 bc->length = length; in binder_defer_copy()
2508 INIT_LIST_HEAD(&bc->node); in binder_defer_copy()
2511 * We are guaranteed that the deferred copies are in-order in binder_defer_copy()
2514 list_add_tail(&bc->node, sgc_head); in binder_defer_copy()
2520 * binder_add_fixup() - queue a fixup to be applied to sg copy
2527 * the scatter-gather buffers, the fixup will be copied instead of
2534 * exceptions. Since out-of-order inserts are relatively uncommon,
2538 * Return: 0=success, else -errno
2547 return -ENOMEM; in binder_add_fixup()
2549 pf->offset = offset; in binder_add_fixup()
2550 pf->fixup_data = fixup; in binder_add_fixup()
2551 pf->skip_size = skip_size; in binder_add_fixup()
2552 INIT_LIST_HEAD(&pf->node); in binder_add_fixup()
2554 /* Fixups are *mostly* added in-order, but there are some in binder_add_fixup()
2558 if (tmppf->offset < pf->offset) { in binder_add_fixup()
2559 list_add(&pf->node, &tmppf->node); in binder_add_fixup()
2567 list_add(&pf->node, pf_head); in binder_add_fixup()
2583 struct binder_proc *proc = thread->proc; in binder_translate_fd_array()
2586 if (fda->num_fds == 0) in binder_translate_fd_array()
2589 fd_buf_size = sizeof(u32) * fda->num_fds; in binder_translate_fd_array()
2590 if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { in binder_translate_fd_array()
2592 proc->pid, thread->pid, (u64)fda->num_fds); in binder_translate_fd_array()
2593 return -EINVAL; in binder_translate_fd_array()
2595 if (fd_buf_size > parent->length || in binder_translate_fd_array()
2596 fda->parent_offset > parent->length - fd_buf_size) { in binder_translate_fd_array()
2599 proc->pid, thread->pid, (u64)fda->num_fds); in binder_translate_fd_array()
2600 return -EINVAL; in binder_translate_fd_array()
2604 * to user-space and the @buffer element is the user in binder_translate_fd_array()
2609 fda_offset = parent->buffer - t->buffer->user_data + in binder_translate_fd_array()
2610 fda->parent_offset; in binder_translate_fd_array()
2611 sender_ufda_base = (void __user *)(uintptr_t)sender_uparent->buffer + in binder_translate_fd_array()
2612 fda->parent_offset; in binder_translate_fd_array()
2617 proc->pid, thread->pid); in binder_translate_fd_array()
2618 return -EINVAL; in binder_translate_fd_array()
2620 ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32)); in binder_translate_fd_array()
2624 for (fdi = 0; fdi < fda->num_fds; fdi++) { in binder_translate_fd_array()
2634 return ret > 0 ? -EINVAL : ret; in binder_translate_fd_array()
2649 struct binder_buffer *b = t->buffer; in binder_fixup_parent()
2650 struct binder_proc *proc = thread->proc; in binder_fixup_parent()
2651 struct binder_proc *target_proc = t->to_proc; in binder_fixup_parent()
2656 if (!(bp->flags & BINDER_BUFFER_FLAG_HAS_PARENT)) in binder_fixup_parent()
2659 parent = binder_validate_ptr(target_proc, b, &object, bp->parent, in binder_fixup_parent()
2664 proc->pid, thread->pid); in binder_fixup_parent()
2665 return -EINVAL; in binder_fixup_parent()
2669 parent_offset, bp->parent_offset, in binder_fixup_parent()
2672 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n", in binder_fixup_parent()
2673 proc->pid, thread->pid); in binder_fixup_parent()
2674 return -EINVAL; in binder_fixup_parent()
2677 if (parent->length < sizeof(binder_uintptr_t) || in binder_fixup_parent()
2678 bp->parent_offset > parent->length - sizeof(binder_uintptr_t)) { in binder_fixup_parent()
2681 proc->pid, thread->pid); in binder_fixup_parent()
2682 return -EINVAL; in binder_fixup_parent()
2685 buffer_offset = bp->parent_offset + parent->buffer - b->user_data; in binder_fixup_parent()
2687 return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0); in binder_fixup_parent()
2691 * binder_can_update_transaction() - Can a txn be superseded by an updated one?
2692 * @t1: the pending async txn in the frozen process
2693 * @t2: the new async txn to supersede the outdated pending one
2701 if ((t1->flags & t2->flags & (TF_ONE_WAY | TF_UPDATE_TXN)) != in binder_can_update_transaction()
2702 (TF_ONE_WAY | TF_UPDATE_TXN) || !t1->to_proc || !t2->to_proc) in binder_can_update_transaction()
2704 if (t1->to_proc->tsk == t2->to_proc->tsk && t1->code == t2->code && in binder_can_update_transaction()
2705 t1->flags == t2->flags && t1->buffer->pid == t2->buffer->pid && in binder_can_update_transaction()
2706 t1->buffer->target_node->ptr == t2->buffer->target_node->ptr && in binder_can_update_transaction()
2707 t1->buffer->target_node->cookie == t2->buffer->target_node->cookie) in binder_can_update_transaction()
2713 * binder_find_outdated_transaction_ilocked() - Find the outdated transaction
2714 * @t: new async transaction
2720 * Requires the proc->inner_lock to be held.
2731 if (w->type != BINDER_WORK_TRANSACTION) in binder_find_outdated_transaction_ilocked()
2741 * binder_proc_transaction() - sends a transaction to a process and wakes it up
2759 * and the async transaction was successfully queued
2765 struct binder_node *node = t->buffer->target_node; in binder_proc_transaction()
2766 bool oneway = !!(t->flags & TF_ONE_WAY); in binder_proc_transaction()
2775 if (node->has_async_transaction) in binder_proc_transaction()
2778 node->has_async_transaction = true; in binder_proc_transaction()
2782 if (proc->is_frozen) { in binder_proc_transaction()
2784 proc->sync_recv |= !oneway; in binder_proc_transaction()
2785 proc->async_recv |= oneway; in binder_proc_transaction()
2788 if ((frozen && !oneway) || proc->is_dead || in binder_proc_transaction()
2789 (thread && thread->is_dead)) { in binder_proc_transaction()
2799 binder_enqueue_thread_work_ilocked(thread, &t->work); in binder_proc_transaction()
2801 binder_enqueue_work_ilocked(&t->work, &proc->todo); in binder_proc_transaction()
2803 if ((t->flags & TF_UPDATE_TXN) && frozen) { in binder_proc_transaction()
2805 &node->async_todo); in binder_proc_transaction()
2809 t->debug_id, t_outdated->debug_id); in binder_proc_transaction()
2810 list_del_init(&t_outdated->work.entry); in binder_proc_transaction()
2811 proc->outstanding_txns--; in binder_proc_transaction()
2814 binder_enqueue_work_ilocked(&t->work, &node->async_todo); in binder_proc_transaction()
2820 proc->outstanding_txns++; in binder_proc_transaction()
2829 struct binder_buffer *buffer = t_outdated->buffer; in binder_proc_transaction()
2831 t_outdated->buffer = NULL; in binder_proc_transaction()
2832 buffer->transaction = NULL; in binder_proc_transaction()
2835 binder_alloc_free_buf(&proc->alloc, buffer); in binder_proc_transaction()
2847 * binder_get_node_refs_for_txn() - Get required refs on node for txn
2849 * @procp: returns @node->proc if valid
2852 * User-space normally keeps the node alive when creating a transaction
2858 * Since user-space can cause the local strong ref to go away, we also take
2863 * Return: The target_node with refs taken or NULL if no @node->proc is NULL.
2864 * Also sets @procp if valid. If the @node->proc is NULL indicating that the
2875 if (node->proc) { in binder_get_node_refs_for_txn()
2879 node->proc->tmp_ref++; in binder_get_node_refs_for_txn()
2880 *procp = node->proc; in binder_get_node_refs_for_txn()
2895 __release(&from->proc->inner_lock); in binder_set_txn_from_error()
2900 if (from->ee.command == BR_OK) in binder_set_txn_from_error()
2901 binder_set_extended_error(&from->ee, id, command, param); in binder_set_txn_from_error()
2902 binder_inner_proc_unlock(from->proc); in binder_set_txn_from_error()
2930 struct binder_context *context = proc->context; in binder_transaction()
2938 (uintptr_t)tr->data.ptr.buffer; in binder_transaction()
2943 e->debug_id = t_debug_id; in binder_transaction()
2944 e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); in binder_transaction()
2945 e->from_proc = proc->pid; in binder_transaction()
2946 e->from_thread = thread->pid; in binder_transaction()
2947 e->target_handle = tr->target.handle; in binder_transaction()
2948 e->data_size = tr->data_size; in binder_transaction()
2949 e->offsets_size = tr->offsets_size; in binder_transaction()
2950 strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME); in binder_transaction()
2953 binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0); in binder_transaction()
2958 in_reply_to = thread->transaction_stack; in binder_transaction()
2962 proc->pid, thread->pid); in binder_transaction()
2964 return_error_param = -EPROTO; in binder_transaction()
2968 if (in_reply_to->to_thread != thread) { in binder_transaction()
2969 spin_lock(&in_reply_to->lock); in binder_transaction()
2971 proc->pid, thread->pid, in_reply_to->debug_id, in binder_transaction()
2972 in_reply_to->to_proc ? in binder_transaction()
2973 in_reply_to->to_proc->pid : 0, in binder_transaction()
2974 in_reply_to->to_thread ? in binder_transaction()
2975 in_reply_to->to_thread->pid : 0); in binder_transaction()
2976 spin_unlock(&in_reply_to->lock); in binder_transaction()
2979 return_error_param = -EPROTO; in binder_transaction()
2984 thread->transaction_stack = in_reply_to->to_parent; in binder_transaction()
2986 binder_set_nice(in_reply_to->saved_priority); in binder_transaction()
2990 __release(&target_thread->proc->inner_lock); in binder_transaction()
2992 thread->pid, proc->pid); in binder_transaction()
2997 if (target_thread->transaction_stack != in_reply_to) { in binder_transaction()
2999 proc->pid, thread->pid, in binder_transaction()
3000 target_thread->transaction_stack ? in binder_transaction()
3001 target_thread->transaction_stack->debug_id : 0, in binder_transaction()
3002 in_reply_to->debug_id); in binder_transaction()
3003 binder_inner_proc_unlock(target_thread->proc); in binder_transaction()
3005 return_error_param = -EPROTO; in binder_transaction()
3011 target_proc = target_thread->proc; in binder_transaction()
3012 target_proc->tmp_ref++; in binder_transaction()
3013 binder_inner_proc_unlock(target_thread->proc); in binder_transaction()
3015 if (tr->target.handle) { in binder_transaction()
3026 ref = binder_get_ref_olocked(proc, tr->target.handle, in binder_transaction()
3030 ref->node, &target_proc, in binder_transaction()
3034 proc->pid, thread->pid, tr->target.handle); in binder_transaction()
3039 mutex_lock(&context->context_mgr_node_lock); in binder_transaction()
3040 target_node = context->binder_context_mgr_node; in binder_transaction()
3047 mutex_unlock(&context->context_mgr_node_lock); in binder_transaction()
3048 if (target_node && target_proc->pid == proc->pid) { in binder_transaction()
3050 proc->pid, thread->pid); in binder_transaction()
3052 return_error_param = -EINVAL; in binder_transaction()
3059 thread->pid, proc->pid); in binder_transaction()
3063 return_error_param = -EINVAL; in binder_transaction()
3067 e->to_node = target_node->debug_id; in binder_transaction()
3070 thread->pid, proc->pid); in binder_transaction()
3072 return_error_param = -EINVAL; in binder_transaction()
3076 if (security_binder_transaction(proc->cred, in binder_transaction()
3077 target_proc->cred) < 0) { in binder_transaction()
3079 thread->pid, proc->pid); in binder_transaction()
3081 return_error_param = -EPERM; in binder_transaction()
3087 w = list_first_entry_or_null(&thread->todo, in binder_transaction()
3089 if (!(tr->flags & TF_ONE_WAY) && w && in binder_transaction()
3090 w->type == BINDER_WORK_TRANSACTION) { in binder_transaction()
3096 * thread from proc->waiting_threads to enqueue in binder_transaction()
3101 proc->pid, thread->pid); in binder_transaction()
3104 return_error_param = -EPROTO; in binder_transaction()
3109 if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { in binder_transaction()
3112 tmp = thread->transaction_stack; in binder_transaction()
3113 if (tmp->to_thread != thread) { in binder_transaction()
3114 spin_lock(&tmp->lock); in binder_transaction()
3116 proc->pid, thread->pid, tmp->debug_id, in binder_transaction()
3117 tmp->to_proc ? tmp->to_proc->pid : 0, in binder_transaction()
3118 tmp->to_thread ? in binder_transaction()
3119 tmp->to_thread->pid : 0); in binder_transaction()
3120 spin_unlock(&tmp->lock); in binder_transaction()
3123 return_error_param = -EPROTO; in binder_transaction()
3130 spin_lock(&tmp->lock); in binder_transaction()
3131 from = tmp->from; in binder_transaction()
3132 if (from && from->proc == target_proc) { in binder_transaction()
3133 atomic_inc(&from->tmp_ref); in binder_transaction()
3135 spin_unlock(&tmp->lock); in binder_transaction()
3138 spin_unlock(&tmp->lock); in binder_transaction()
3139 tmp = tmp->from_parent; in binder_transaction()
3145 e->to_thread = target_thread->pid; in binder_transaction()
3146 e->to_proc = target_proc->pid; in binder_transaction()
3152 thread->pid, proc->pid); in binder_transaction()
3154 return_error_param = -ENOMEM; in binder_transaction()
3158 INIT_LIST_HEAD(&t->fd_fixups); in binder_transaction()
3160 spin_lock_init(&t->lock); in binder_transaction()
3165 thread->pid, proc->pid); in binder_transaction()
3167 return_error_param = -ENOMEM; in binder_transaction()
3173 t->debug_id = t_debug_id; in binder_transaction()
3174 t->start_time = t_start_time; in binder_transaction()
3178 "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n", in binder_transaction()
3179 proc->pid, thread->pid, t->debug_id, in binder_transaction()
3180 target_proc->pid, target_thread->pid, in binder_transaction()
3181 (u64)tr->data.ptr.buffer, in binder_transaction()
3182 (u64)tr->data.ptr.offsets, in binder_transaction()
3183 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3187 "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n", in binder_transaction()
3188 proc->pid, thread->pid, t->debug_id, in binder_transaction()
3189 target_proc->pid, target_node->debug_id, in binder_transaction()
3190 (u64)tr->data.ptr.buffer, in binder_transaction()
3191 (u64)tr->data.ptr.offsets, in binder_transaction()
3192 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3195 if (!reply && !(tr->flags & TF_ONE_WAY)) in binder_transaction()
3196 t->from = thread; in binder_transaction()
3198 t->from = NULL; in binder_transaction()
3199 t->from_pid = proc->pid; in binder_transaction()
3200 t->from_tid = thread->pid; in binder_transaction()
3201 t->sender_euid = task_euid(proc->tsk); in binder_transaction()
3202 t->to_proc = target_proc; in binder_transaction()
3203 t->to_thread = target_thread; in binder_transaction()
3204 t->code = tr->code; in binder_transaction()
3205 t->flags = tr->flags; in binder_transaction()
3206 t->priority = task_nice(current); in binder_transaction()
3208 if (target_node && target_node->txn_security_ctx) { in binder_transaction()
3212 security_cred_getsecid(proc->cred, &secid); in binder_transaction()
3216 thread->pid, proc->pid); in binder_transaction()
3226 thread->pid, proc->pid); in binder_transaction()
3228 return_error_param = -EINVAL; in binder_transaction()
3236 t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size, in binder_transaction()
3237 tr->offsets_size, extra_buffers_size, in binder_transaction()
3238 !reply && (t->flags & TF_ONE_WAY)); in binder_transaction()
3239 if (IS_ERR(t->buffer)) { in binder_transaction()
3242 ret = PTR_ERR(t->buffer); in binder_transaction()
3243 s = (ret == -ESRCH) ? ": vma cleared, target dead or dying" in binder_transaction()
3244 : (ret == -ENOSPC) ? ": no space left" in binder_transaction()
3245 : (ret == -ENOMEM) ? ": memory allocation failed" in binder_transaction()
3249 return_error_param = PTR_ERR(t->buffer); in binder_transaction()
3250 return_error = return_error_param == -ESRCH ? in binder_transaction()
3253 t->buffer = NULL; in binder_transaction()
3258 size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + in binder_transaction()
3259 ALIGN(tr->offsets_size, sizeof(void *)) + in binder_transaction()
3260 ALIGN(extra_buffers_size, sizeof(void *)) - in binder_transaction()
3263 t->security_ctx = t->buffer->user_data + buf_offset; in binder_transaction()
3264 err = binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3265 t->buffer, buf_offset, in binder_transaction()
3268 t->security_ctx = 0; in binder_transaction()
3274 t->buffer->debug_id = t->debug_id; in binder_transaction()
3275 t->buffer->transaction = t; in binder_transaction()
3276 t->buffer->target_node = target_node; in binder_transaction()
3277 t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); in binder_transaction()
3278 trace_binder_transaction_alloc_buf(t->buffer); in binder_transaction()
3281 &target_proc->alloc, in binder_transaction()
3282 t->buffer, in binder_transaction()
3283 ALIGN(tr->data_size, sizeof(void *)), in binder_transaction()
3285 (uintptr_t)tr->data.ptr.offsets, in binder_transaction()
3286 tr->offsets_size)) { in binder_transaction()
3288 proc->pid, thread->pid); in binder_transaction()
3290 return_error_param = -EFAULT; in binder_transaction()
3294 if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) { in binder_transaction()
3296 proc->pid, thread->pid, (u64)tr->offsets_size); in binder_transaction()
3298 return_error_param = -EINVAL; in binder_transaction()
3304 proc->pid, thread->pid, in binder_transaction()
3307 return_error_param = -EINVAL; in binder_transaction()
3311 off_start_offset = ALIGN(tr->data_size, sizeof(void *)); in binder_transaction()
3313 off_end_offset = off_start_offset + tr->offsets_size; in binder_transaction()
3315 sg_buf_end_offset = sg_buf_offset + extra_buffers_size - in binder_transaction()
3326 if (binder_alloc_copy_from_buffer(&target_proc->alloc, in binder_transaction()
3328 t->buffer, in binder_transaction()
3332 thread->pid, proc->pid); in binder_transaction()
3334 return_error_param = -EINVAL; in binder_transaction()
3343 copy_size = object_offset - user_offset; in binder_transaction()
3346 &target_proc->alloc, in binder_transaction()
3347 t->buffer, user_offset, in binder_transaction()
3351 proc->pid, thread->pid); in binder_transaction()
3353 return_error_param = -EFAULT; in binder_transaction()
3358 t->buffer, object_offset, &object); in binder_transaction()
3361 proc->pid, thread->pid, in binder_transaction()
3364 (u64)t->buffer->data_size); in binder_transaction()
3366 return_error_param = -EINVAL; in binder_transaction()
3378 switch (hdr->type) { in binder_transaction()
3387 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3388 t->buffer, in binder_transaction()
3392 thread->pid, proc->pid); in binder_transaction()
3406 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3407 t->buffer, in binder_transaction()
3411 thread->pid, proc->pid); in binder_transaction()
3422 (uintptr_t)&fp->fd - (uintptr_t)fp; in binder_transaction()
3423 int ret = binder_translate_fd(fp->fd, fd_offset, t, in binder_transaction()
3426 fp->pad_binder = 0; in binder_transaction()
3428 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3429 t->buffer, in binder_transaction()
3433 thread->pid, proc->pid); in binder_transaction()
3447 size_t num_valid = (buffer_offset - off_start_offset) / in binder_transaction()
3450 binder_validate_ptr(target_proc, t->buffer, in binder_transaction()
3451 &ptr_object, fda->parent, in binder_transaction()
3457 proc->pid, thread->pid); in binder_transaction()
3459 return_error_param = -EINVAL; in binder_transaction()
3463 if (!binder_validate_fixup(target_proc, t->buffer, in binder_transaction()
3466 fda->parent_offset, in binder_transaction()
3469 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n", in binder_transaction()
3470 proc->pid, thread->pid); in binder_transaction()
3472 return_error_param = -EINVAL; in binder_transaction()
3481 binder_get_object(proc, user_buffer, t->buffer, in binder_transaction()
3485 proc->pid, thread->pid, in binder_transaction()
3489 return_error_param = -EINVAL; in binder_transaction()
3498 ret = binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3499 t->buffer, in binder_transaction()
3504 thread->pid, proc->pid); in binder_transaction()
3506 return_error_param = ret > 0 ? -EINVAL : ret; in binder_transaction()
3512 fda->parent_offset + sizeof(u32) * fda->num_fds; in binder_transaction()
3517 size_t buf_left = sg_buf_end_offset - sg_buf_offset; in binder_transaction()
3520 if (bp->length > buf_left) { in binder_transaction()
3522 proc->pid, thread->pid); in binder_transaction()
3524 return_error_param = -EINVAL; in binder_transaction()
3529 (const void __user *)(uintptr_t)bp->buffer, in binder_transaction()
3530 bp->length); in binder_transaction()
3533 thread->pid, proc->pid); in binder_transaction()
3540 bp->buffer = t->buffer->user_data + sg_buf_offset; in binder_transaction()
3541 sg_buf_offset += ALIGN(bp->length, sizeof(u64)); in binder_transaction()
3543 num_valid = (buffer_offset - off_start_offset) / in binder_transaction()
3552 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3553 t->buffer, in binder_transaction()
3557 thread->pid, proc->pid); in binder_transaction()
3568 proc->pid, thread->pid, hdr->type); in binder_transaction()
3570 return_error_param = -EINVAL; in binder_transaction()
3577 &target_proc->alloc, in binder_transaction()
3578 t->buffer, user_offset, in binder_transaction()
3580 tr->data_size - user_offset)) { in binder_transaction()
3582 proc->pid, thread->pid); in binder_transaction()
3584 return_error_param = -EFAULT; in binder_transaction()
3589 ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer, in binder_transaction()
3593 proc->pid, thread->pid); in binder_transaction()
3599 if (t->buffer->oneway_spam_suspect) in binder_transaction()
3600 tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; in binder_transaction()
3602 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; in binder_transaction()
3603 t->work.type = BINDER_WORK_TRANSACTION; in binder_transaction()
3608 if (target_thread->is_dead) { in binder_transaction()
3613 BUG_ON(t->buffer->async_transaction != 0); in binder_transaction()
3615 binder_enqueue_thread_work_ilocked(target_thread, &t->work); in binder_transaction()
3616 target_proc->outstanding_txns++; in binder_transaction()
3618 wake_up_interruptible_sync(&target_thread->wait); in binder_transaction()
3620 } else if (!(t->flags & TF_ONE_WAY)) { in binder_transaction()
3621 BUG_ON(t->buffer->async_transaction != 0); in binder_transaction()
3631 t->need_reply = 1; in binder_transaction()
3632 t->from_parent = thread->transaction_stack; in binder_transaction()
3633 thread->transaction_stack = t; in binder_transaction()
3645 BUG_ON(t->buffer->async_transaction != 1); in binder_transaction()
3648 * Let the caller know when async transaction reaches a frozen in binder_transaction()
3653 tcomplete->type = BINDER_WORK_TRANSACTION_PENDING; in binder_transaction()
3669 WRITE_ONCE(e->debug_id_done, t_debug_id); in binder_transaction()
3674 thread->pid, proc->pid); in binder_transaction()
3684 trace_binder_transaction_failed_buffer_release(t->buffer); in binder_transaction()
3685 binder_transaction_buffer_release(target_proc, NULL, t->buffer, in binder_transaction()
3690 t->buffer->transaction = NULL; in binder_transaction()
3691 binder_alloc_free_buf(&target_proc->alloc, t->buffer); in binder_transaction()
3716 "%d:%d transaction %s to %d:%d failed %d/%d/%d, size %lld-%lld line %d\n", in binder_transaction()
3717 proc->pid, thread->pid, reply ? "reply" : in binder_transaction()
3718 (tr->flags & TF_ONE_WAY ? "async" : "call"), in binder_transaction()
3719 target_proc ? target_proc->pid : 0, in binder_transaction()
3720 target_thread ? target_thread->pid : 0, in binder_transaction()
3722 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3733 e->return_error = return_error; in binder_transaction()
3734 e->return_error_param = return_error_param; in binder_transaction()
3735 e->return_error_line = return_error_line; in binder_transaction()
3743 WRITE_ONCE(e->debug_id_done, t_debug_id); in binder_transaction()
3744 WRITE_ONCE(fe->debug_id_done, t_debug_id); in binder_transaction()
3747 BUG_ON(thread->return_error.cmd != BR_OK); in binder_transaction()
3751 thread->return_error.cmd = BR_TRANSACTION_COMPLETE; in binder_transaction()
3752 binder_enqueue_thread_work(thread, &thread->return_error.work); in binder_transaction()
3756 binder_set_extended_error(&thread->ee, t_debug_id, in binder_transaction()
3759 thread->return_error.cmd = return_error; in binder_transaction()
3760 binder_enqueue_thread_work(thread, &thread->return_error.work); in binder_transaction()
3765 * binder_free_buf() - free the specified buffer
3770 * If buffer for an async transaction, enqueue the next async
3781 if (buffer->transaction) { in binder_free_buf()
3782 buffer->transaction->buffer = NULL; in binder_free_buf()
3783 buffer->transaction = NULL; in binder_free_buf()
3786 if (buffer->async_transaction && buffer->target_node) { in binder_free_buf()
3790 buf_node = buffer->target_node; in binder_free_buf()
3792 BUG_ON(!buf_node->has_async_transaction); in binder_free_buf()
3793 BUG_ON(buf_node->proc != proc); in binder_free_buf()
3795 &buf_node->async_todo); in binder_free_buf()
3797 buf_node->has_async_transaction = false; in binder_free_buf()
3800 w, &proc->todo); in binder_free_buf()
3807 binder_alloc_free_buf(&proc->alloc, buffer); in binder_free_buf()
3816 struct binder_context *context = proc->context; in binder_thread_write()
3821 while (ptr < end && thread->return_error.cmd == BR_OK) { in binder_thread_write()
3825 return -EFAULT; in binder_thread_write()
3830 atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]); in binder_thread_write()
3831 atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]); in binder_thread_write()
3845 return -EFAULT; in binder_thread_write()
3848 ret = -1; in binder_thread_write()
3852 mutex_lock(&context->context_mgr_node_lock); in binder_thread_write()
3853 ctx_mgr_node = context->binder_context_mgr_node; in binder_thread_write()
3855 if (ctx_mgr_node->proc == proc) { in binder_thread_write()
3857 proc->pid, thread->pid); in binder_thread_write()
3858 mutex_unlock(&context->context_mgr_node_lock); in binder_thread_write()
3859 return -EINVAL; in binder_thread_write()
3865 mutex_unlock(&context->context_mgr_node_lock); in binder_thread_write()
3873 proc->pid, thread->pid, in binder_thread_write()
3893 proc->pid, thread->pid, debug_string, in binder_thread_write()
3899 proc->pid, thread->pid, debug_string, in binder_thread_write()
3912 return -EFAULT; in binder_thread_write()
3915 return -EFAULT; in binder_thread_write()
3920 proc->pid, thread->pid, in binder_thread_write()
3927 if (cookie != node->cookie) { in binder_thread_write()
3929 proc->pid, thread->pid, in binder_thread_write()
3932 (u64)node_ptr, node->debug_id, in binder_thread_write()
3933 (u64)cookie, (u64)node->cookie); in binder_thread_write()
3939 if (node->pending_strong_ref == 0) { in binder_thread_write()
3941 proc->pid, thread->pid, in binder_thread_write()
3942 node->debug_id); in binder_thread_write()
3947 node->pending_strong_ref = 0; in binder_thread_write()
3949 if (node->pending_weak_ref == 0) { in binder_thread_write()
3951 proc->pid, thread->pid, in binder_thread_write()
3952 node->debug_id); in binder_thread_write()
3957 node->pending_weak_ref = 0; in binder_thread_write()
3964 proc->pid, thread->pid, in binder_thread_write()
3966 node->debug_id, node->local_strong_refs, in binder_thread_write()
3967 node->local_weak_refs, node->tmp_refs); in binder_thread_write()
3974 return -EINVAL; in binder_thread_write()
3977 return -EINVAL; in binder_thread_write()
3984 return -EFAULT; in binder_thread_write()
3987 buffer = binder_alloc_prepare_to_free(&proc->alloc, in binder_thread_write()
3990 if (PTR_ERR(buffer) == -EPERM) { in binder_thread_write()
3993 proc->pid, thread->pid, in binder_thread_write()
3998 proc->pid, thread->pid, in binder_thread_write()
4005 proc->pid, thread->pid, (u64)data_ptr, in binder_thread_write()
4006 buffer->debug_id, in binder_thread_write()
4007 buffer->transaction ? "active" : "finished"); in binder_thread_write()
4017 return -EFAULT; in binder_thread_write()
4028 return -EFAULT; in binder_thread_write()
4038 proc->pid, thread->pid); in binder_thread_write()
4040 if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { in binder_thread_write()
4041 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4043 proc->pid, thread->pid); in binder_thread_write()
4044 } else if (proc->requested_threads == 0) { in binder_thread_write()
4045 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4047 proc->pid, thread->pid); in binder_thread_write()
4049 proc->requested_threads--; in binder_thread_write()
4050 proc->requested_threads_started++; in binder_thread_write()
4052 thread->looper |= BINDER_LOOPER_STATE_REGISTERED; in binder_thread_write()
4058 proc->pid, thread->pid); in binder_thread_write()
4059 if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { in binder_thread_write()
4060 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4062 proc->pid, thread->pid); in binder_thread_write()
4064 thread->looper |= BINDER_LOOPER_STATE_ENTERED; in binder_thread_write()
4069 proc->pid, thread->pid); in binder_thread_write()
4070 thread->looper |= BINDER_LOOPER_STATE_EXITED; in binder_thread_write()
4081 return -EFAULT; in binder_thread_write()
4084 return -EFAULT; in binder_thread_write()
4093 WARN_ON(thread->return_error.cmd != in binder_thread_write()
4095 thread->return_error.cmd = BR_ERROR; in binder_thread_write()
4098 &thread->return_error.work); in binder_thread_write()
4102 proc->pid, thread->pid); in binder_thread_write()
4110 proc->pid, thread->pid, in binder_thread_write()
4122 proc->pid, thread->pid, in binder_thread_write()
4126 (u64)cookie, ref->data.debug_id, in binder_thread_write()
4127 ref->data.desc, ref->data.strong, in binder_thread_write()
4128 ref->data.weak, ref->node->debug_id); in binder_thread_write()
4130 binder_node_lock(ref->node); in binder_thread_write()
4132 if (ref->death) { in binder_thread_write()
4134 proc->pid, thread->pid); in binder_thread_write()
4135 binder_node_unlock(ref->node); in binder_thread_write()
4141 INIT_LIST_HEAD(&death->work.entry); in binder_thread_write()
4142 death->cookie = cookie; in binder_thread_write()
4143 ref->death = death; in binder_thread_write()
4144 if (ref->node->proc == NULL) { in binder_thread_write()
4145 ref->death->work.type = BINDER_WORK_DEAD_BINDER; in binder_thread_write()
4149 &ref->death->work, &proc->todo); in binder_thread_write()
4154 if (ref->death == NULL) { in binder_thread_write()
4156 proc->pid, thread->pid); in binder_thread_write()
4157 binder_node_unlock(ref->node); in binder_thread_write()
4161 death = ref->death; in binder_thread_write()
4162 if (death->cookie != cookie) { in binder_thread_write()
4164 proc->pid, thread->pid, in binder_thread_write()
4165 (u64)death->cookie, in binder_thread_write()
4167 binder_node_unlock(ref->node); in binder_thread_write()
4171 ref->death = NULL; in binder_thread_write()
4173 if (list_empty(&death->work.entry)) { in binder_thread_write()
4174 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; in binder_thread_write()
4175 if (thread->looper & in binder_thread_write()
4180 &death->work); in binder_thread_write()
4183 &death->work, in binder_thread_write()
4184 &proc->todo); in binder_thread_write()
4189 BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); in binder_thread_write()
4190 death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; in binder_thread_write()
4194 binder_node_unlock(ref->node); in binder_thread_write()
4203 return -EFAULT; in binder_thread_write()
4207 list_for_each_entry(w, &proc->delivered_death, in binder_thread_write()
4214 if (tmp_death->cookie == cookie) { in binder_thread_write()
4221 proc->pid, thread->pid, (u64)cookie, in binder_thread_write()
4225 proc->pid, thread->pid, (u64)cookie); in binder_thread_write()
4229 binder_dequeue_work_ilocked(&death->work); in binder_thread_write()
4230 if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { in binder_thread_write()
4231 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; in binder_thread_write()
4232 if (thread->looper & in binder_thread_write()
4236 thread, &death->work); in binder_thread_write()
4239 &death->work, in binder_thread_write()
4240 &proc->todo); in binder_thread_write()
4249 proc->pid, thread->pid, cmd); in binder_thread_write()
4250 return -EINVAL; in binder_thread_write()
4252 *consumed = ptr - buffer; in binder_thread_write()
4263 atomic_inc(&proc->stats.br[_IOC_NR(cmd)]); in binder_stat_br()
4264 atomic_inc(&thread->stats.br[_IOC_NR(cmd)]); in binder_stat_br()
4279 return -EFAULT; in binder_put_node_cmd()
4283 return -EFAULT; in binder_put_node_cmd()
4287 return -EFAULT; in binder_put_node_cmd()
4292 proc->pid, thread->pid, cmd_name, node_debug_id, in binder_put_node_cmd()
4303 struct binder_proc *proc = thread->proc; in binder_wait_for_work()
4308 prepare_to_wait(&thread->wait, &wait, TASK_INTERRUPTIBLE|TASK_FREEZABLE); in binder_wait_for_work()
4312 list_add(&thread->waiting_thread_node, in binder_wait_for_work()
4313 &proc->waiting_threads); in binder_wait_for_work()
4317 list_del_init(&thread->waiting_thread_node); in binder_wait_for_work()
4319 ret = -EINTR; in binder_wait_for_work()
4323 finish_wait(&thread->wait, &wait); in binder_wait_for_work()
4330 * binder_apply_fd_fixups() - finish fd translation
4331 * @proc: binder_proc associated @t->buffer
4348 list_for_each_entry(fixup, &t->fd_fixups, fixup_entry) { in binder_apply_fd_fixups()
4354 t->debug_id, fd); in binder_apply_fd_fixups()
4355 ret = -ENOMEM; in binder_apply_fd_fixups()
4360 t->debug_id, fd); in binder_apply_fd_fixups()
4361 trace_binder_transaction_fd_recv(t, fd, fixup->offset); in binder_apply_fd_fixups()
4362 fixup->target_fd = fd; in binder_apply_fd_fixups()
4363 if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer, in binder_apply_fd_fixups()
4364 fixup->offset, &fd, in binder_apply_fd_fixups()
4366 ret = -EINVAL; in binder_apply_fd_fixups()
4370 list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { in binder_apply_fd_fixups()
4371 fd_install(fixup->target_fd, fixup->file); in binder_apply_fd_fixups()
4372 list_del(&fixup->fixup_entry); in binder_apply_fd_fixups()
4397 return -EFAULT; in binder_thread_read()
4406 thread->looper |= BINDER_LOOPER_STATE_WAITING; in binder_thread_read()
4409 !!thread->transaction_stack, in binder_thread_read()
4410 !binder_worklist_empty(proc, &thread->todo)); in binder_thread_read()
4412 if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | in binder_thread_read()
4415 proc->pid, thread->pid, thread->looper); in binder_thread_read()
4419 binder_set_nice(proc->default_priority); in binder_thread_read()
4424 ret = -EAGAIN; in binder_thread_read()
4429 thread->looper &= ~BINDER_LOOPER_STATE_WAITING; in binder_thread_read()
4445 if (!binder_worklist_empty_ilocked(&thread->todo)) in binder_thread_read()
4446 list = &thread->todo; in binder_thread_read()
4447 else if (!binder_worklist_empty_ilocked(&proc->todo) && in binder_thread_read()
4449 list = &proc->todo; in binder_thread_read()
4454 if (ptr - buffer == 4 && !thread->looper_need_return) in binder_thread_read()
4459 if (end - ptr < sizeof(tr) + 4) { in binder_thread_read()
4464 if (binder_worklist_empty_ilocked(&thread->todo)) in binder_thread_read()
4465 thread->process_todo = false; in binder_thread_read()
4467 switch (w->type) { in binder_thread_read()
4476 WARN_ON(e->cmd == BR_OK); in binder_thread_read()
4478 if (put_user(e->cmd, (uint32_t __user *)ptr)) in binder_thread_read()
4479 return -EFAULT; in binder_thread_read()
4480 cmd = e->cmd; in binder_thread_read()
4481 e->cmd = BR_OK; in binder_thread_read()
4489 if (proc->oneway_spam_detection_enabled && in binder_thread_read()
4490 w->type == BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT) in binder_thread_read()
4492 else if (w->type == BINDER_WORK_TRANSACTION_PENDING) in binder_thread_read()
4500 return -EFAULT; in binder_thread_read()
4506 proc->pid, thread->pid); in binder_thread_read()
4511 binder_uintptr_t node_ptr = node->ptr; in binder_thread_read()
4512 binder_uintptr_t node_cookie = node->cookie; in binder_thread_read()
4513 int node_debug_id = node->debug_id; in binder_thread_read()
4518 BUG_ON(proc != node->proc); in binder_thread_read()
4519 strong = node->internal_strong_refs || in binder_thread_read()
4520 node->local_strong_refs; in binder_thread_read()
4521 weak = !hlist_empty(&node->refs) || in binder_thread_read()
4522 node->local_weak_refs || in binder_thread_read()
4523 node->tmp_refs || strong; in binder_thread_read()
4524 has_strong_ref = node->has_strong_ref; in binder_thread_read()
4525 has_weak_ref = node->has_weak_ref; in binder_thread_read()
4528 node->has_weak_ref = 1; in binder_thread_read()
4529 node->pending_weak_ref = 1; in binder_thread_read()
4530 node->local_weak_refs++; in binder_thread_read()
4533 node->has_strong_ref = 1; in binder_thread_read()
4534 node->pending_strong_ref = 1; in binder_thread_read()
4535 node->local_strong_refs++; in binder_thread_read()
4538 node->has_strong_ref = 0; in binder_thread_read()
4540 node->has_weak_ref = 0; in binder_thread_read()
4544 proc->pid, thread->pid, in binder_thread_read()
4548 rb_erase(&node->rb_node, &proc->nodes); in binder_thread_read()
4588 proc->pid, thread->pid, in binder_thread_read()
4603 if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) in binder_thread_read()
4607 cookie = death->cookie; in binder_thread_read()
4611 proc->pid, thread->pid, in binder_thread_read()
4616 if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { in binder_thread_read()
4622 w, &proc->delivered_death); in binder_thread_read()
4626 return -EFAULT; in binder_thread_read()
4630 return -EFAULT; in binder_thread_read()
4639 proc->pid, thread->pid, w->type); in binder_thread_read()
4646 BUG_ON(t->buffer == NULL); in binder_thread_read()
4647 if (t->buffer->target_node) { in binder_thread_read()
4648 struct binder_node *target_node = t->buffer->target_node; in binder_thread_read()
4650 trd->target.ptr = target_node->ptr; in binder_thread_read()
4651 trd->cookie = target_node->cookie; in binder_thread_read()
4652 t->saved_priority = task_nice(current); in binder_thread_read()
4653 if (t->priority < target_node->min_priority && in binder_thread_read()
4654 !(t->flags & TF_ONE_WAY)) in binder_thread_read()
4655 binder_set_nice(t->priority); in binder_thread_read()
4656 else if (!(t->flags & TF_ONE_WAY) || in binder_thread_read()
4657 t->saved_priority > target_node->min_priority) in binder_thread_read()
4658 binder_set_nice(target_node->min_priority); in binder_thread_read()
4661 trd->target.ptr = 0; in binder_thread_read()
4662 trd->cookie = 0; in binder_thread_read()
4665 trd->code = t->code; in binder_thread_read()
4666 trd->flags = t->flags; in binder_thread_read()
4667 trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid); in binder_thread_read()
4671 struct task_struct *sender = t_from->proc->tsk; in binder_thread_read()
4673 trd->sender_pid = in binder_thread_read()
4677 trd->sender_pid = 0; in binder_thread_read()
4682 struct binder_buffer *buffer = t->buffer; in binder_thread_read()
4683 bool oneway = !!(t->flags & TF_ONE_WAY); in binder_thread_read()
4684 int tid = t->debug_id; in binder_thread_read()
4688 buffer->transaction = NULL; in binder_thread_read()
4694 proc->pid, thread->pid, in binder_thread_read()
4695 oneway ? "async " : in binder_thread_read()
4701 return -EFAULT; in binder_thread_read()
4708 trd->data_size = t->buffer->data_size; in binder_thread_read()
4709 trd->offsets_size = t->buffer->offsets_size; in binder_thread_read()
4710 trd->data.ptr.buffer = t->buffer->user_data; in binder_thread_read()
4711 trd->data.ptr.offsets = trd->data.ptr.buffer + in binder_thread_read()
4712 ALIGN(t->buffer->data_size, in binder_thread_read()
4715 tr.secctx = t->security_ctx; in binder_thread_read()
4716 if (t->security_ctx) { in binder_thread_read()
4727 return -EFAULT; in binder_thread_read()
4737 return -EFAULT; in binder_thread_read()
4744 "%d:%d %s %d %d:%d, cmd %u size %zd-%zd ptr %016llx-%016llx\n", in binder_thread_read()
4745 proc->pid, thread->pid, in binder_thread_read()
4749 t->debug_id, t_from ? t_from->proc->pid : 0, in binder_thread_read()
4750 t_from ? t_from->pid : 0, cmd, in binder_thread_read()
4751 t->buffer->data_size, t->buffer->offsets_size, in binder_thread_read()
4752 (u64)trd->data.ptr.buffer, in binder_thread_read()
4753 (u64)trd->data.ptr.offsets); in binder_thread_read()
4757 t->buffer->allow_user_free = 1; in binder_thread_read()
4758 if (cmd != BR_REPLY && !(t->flags & TF_ONE_WAY)) { in binder_thread_read()
4759 binder_inner_proc_lock(thread->proc); in binder_thread_read()
4760 t->to_parent = thread->transaction_stack; in binder_thread_read()
4761 t->to_thread = thread; in binder_thread_read()
4762 thread->transaction_stack = t; in binder_thread_read()
4763 binder_inner_proc_unlock(thread->proc); in binder_thread_read()
4772 *consumed = ptr - buffer; in binder_thread_read()
4774 if (proc->requested_threads == 0 && in binder_thread_read()
4775 list_empty(&thread->proc->waiting_threads) && in binder_thread_read()
4776 proc->requested_threads_started < proc->max_threads && in binder_thread_read()
4777 (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | in binder_thread_read()
4778 BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ in binder_thread_read()
4780 proc->requested_threads++; in binder_thread_read()
4784 proc->pid, thread->pid); in binder_thread_read()
4786 return -EFAULT; in binder_thread_read()
4802 wtype = w ? w->type : 0; in binder_release_work()
4822 e->cmd); in binder_release_work()
4839 (u64)death->cookie); in binder_release_work()
4859 struct rb_node **p = &proc->threads.rb_node; in binder_get_thread_ilocked()
4865 if (current->pid < thread->pid) in binder_get_thread_ilocked()
4866 p = &(*p)->rb_left; in binder_get_thread_ilocked()
4867 else if (current->pid > thread->pid) in binder_get_thread_ilocked()
4868 p = &(*p)->rb_right; in binder_get_thread_ilocked()
4876 thread->proc = proc; in binder_get_thread_ilocked()
4877 thread->pid = current->pid; in binder_get_thread_ilocked()
4878 atomic_set(&thread->tmp_ref, 0); in binder_get_thread_ilocked()
4879 init_waitqueue_head(&thread->wait); in binder_get_thread_ilocked()
4880 INIT_LIST_HEAD(&thread->todo); in binder_get_thread_ilocked()
4881 rb_link_node(&thread->rb_node, parent, p); in binder_get_thread_ilocked()
4882 rb_insert_color(&thread->rb_node, &proc->threads); in binder_get_thread_ilocked()
4883 thread->looper_need_return = true; in binder_get_thread_ilocked()
4884 thread->return_error.work.type = BINDER_WORK_RETURN_ERROR; in binder_get_thread_ilocked()
4885 thread->return_error.cmd = BR_OK; in binder_get_thread_ilocked()
4886 thread->reply_error.work.type = BINDER_WORK_RETURN_ERROR; in binder_get_thread_ilocked()
4887 thread->reply_error.cmd = BR_OK; in binder_get_thread_ilocked()
4888 thread->ee.command = BR_OK; in binder_get_thread_ilocked()
4889 INIT_LIST_HEAD(&new_thread->waiting_thread_node); in binder_get_thread_ilocked()
4918 BUG_ON(!list_empty(&proc->todo)); in binder_free_proc()
4919 BUG_ON(!list_empty(&proc->delivered_death)); in binder_free_proc()
4920 if (proc->outstanding_txns) in binder_free_proc()
4922 __func__, proc->outstanding_txns); in binder_free_proc()
4923 device = container_of(proc->context, struct binder_device, context); in binder_free_proc()
4924 if (refcount_dec_and_test(&device->ref)) { in binder_free_proc()
4925 kfree(proc->context->name); in binder_free_proc()
4928 binder_alloc_deferred_release(&proc->alloc); in binder_free_proc()
4929 put_task_struct(proc->tsk); in binder_free_proc()
4930 put_cred(proc->cred); in binder_free_proc()
4937 BUG_ON(!list_empty(&thread->todo)); in binder_free_thread()
4939 binder_proc_dec_tmpref(thread->proc); in binder_free_thread()
4951 binder_inner_proc_lock(thread->proc); in binder_thread_release()
4954 * after we remove this thread from proc->threads. in binder_thread_release()
4958 proc->tmp_ref++; in binder_thread_release()
4963 atomic_inc(&thread->tmp_ref); in binder_thread_release()
4964 rb_erase(&thread->rb_node, &proc->threads); in binder_thread_release()
4965 t = thread->transaction_stack; in binder_thread_release()
4967 spin_lock(&t->lock); in binder_thread_release()
4968 if (t->to_thread == thread) in binder_thread_release()
4971 __acquire(&t->lock); in binder_thread_release()
4973 thread->is_dead = true; in binder_thread_release()
4980 proc->pid, thread->pid, in binder_thread_release()
4981 t->debug_id, in binder_thread_release()
4982 (t->to_thread == thread) ? "in" : "out"); in binder_thread_release()
4984 if (t->to_thread == thread) { in binder_thread_release()
4985 thread->proc->outstanding_txns--; in binder_thread_release()
4986 t->to_proc = NULL; in binder_thread_release()
4987 t->to_thread = NULL; in binder_thread_release()
4988 if (t->buffer) { in binder_thread_release()
4989 t->buffer->transaction = NULL; in binder_thread_release()
4990 t->buffer = NULL; in binder_thread_release()
4992 t = t->to_parent; in binder_thread_release()
4993 } else if (t->from == thread) { in binder_thread_release()
4994 t->from = NULL; in binder_thread_release()
4995 t = t->from_parent; in binder_thread_release()
4998 spin_unlock(&last_t->lock); in binder_thread_release()
5000 spin_lock(&t->lock); in binder_thread_release()
5002 __acquire(&t->lock); in binder_thread_release()
5005 __release(&t->lock); in binder_thread_release()
5011 if (thread->looper & BINDER_LOOPER_STATE_POLL) in binder_thread_release()
5012 wake_up_pollfree(&thread->wait); in binder_thread_release()
5014 binder_inner_proc_unlock(thread->proc); in binder_thread_release()
5023 if (thread->looper & BINDER_LOOPER_STATE_POLL) in binder_thread_release()
5028 binder_release_work(proc, &thread->todo); in binder_thread_release()
5036 struct binder_proc *proc = filp->private_data; in binder_poll()
5044 binder_inner_proc_lock(thread->proc); in binder_poll()
5045 thread->looper |= BINDER_LOOPER_STATE_POLL; in binder_poll()
5048 binder_inner_proc_unlock(thread->proc); in binder_poll()
5050 poll_wait(filp, &thread->wait, wait); in binder_poll()
5062 struct binder_proc *proc = filp->private_data; in binder_ioctl_write_read()
5067 ret = -EFAULT; in binder_ioctl_write_read()
5072 proc->pid, thread->pid, in binder_ioctl_write_read()
5085 ret = -EFAULT; in binder_ioctl_write_read()
5093 filp->f_flags & O_NONBLOCK); in binder_ioctl_write_read()
5096 if (!binder_worklist_empty_ilocked(&proc->todo)) in binder_ioctl_write_read()
5101 ret = -EFAULT; in binder_ioctl_write_read()
5107 proc->pid, thread->pid, in binder_ioctl_write_read()
5111 ret = -EFAULT; in binder_ioctl_write_read()
5122 struct binder_proc *proc = filp->private_data; in binder_ioctl_set_ctx_mgr()
5123 struct binder_context *context = proc->context; in binder_ioctl_set_ctx_mgr()
5127 mutex_lock(&context->context_mgr_node_lock); in binder_ioctl_set_ctx_mgr()
5128 if (context->binder_context_mgr_node) { in binder_ioctl_set_ctx_mgr()
5130 ret = -EBUSY; in binder_ioctl_set_ctx_mgr()
5133 ret = security_binder_set_context_mgr(proc->cred); in binder_ioctl_set_ctx_mgr()
5136 if (uid_valid(context->binder_context_mgr_uid)) { in binder_ioctl_set_ctx_mgr()
5137 if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) { in binder_ioctl_set_ctx_mgr()
5141 context->binder_context_mgr_uid)); in binder_ioctl_set_ctx_mgr()
5142 ret = -EPERM; in binder_ioctl_set_ctx_mgr()
5146 context->binder_context_mgr_uid = curr_euid; in binder_ioctl_set_ctx_mgr()
5150 ret = -ENOMEM; in binder_ioctl_set_ctx_mgr()
5154 new_node->local_weak_refs++; in binder_ioctl_set_ctx_mgr()
5155 new_node->local_strong_refs++; in binder_ioctl_set_ctx_mgr()
5156 new_node->has_strong_ref = 1; in binder_ioctl_set_ctx_mgr()
5157 new_node->has_weak_ref = 1; in binder_ioctl_set_ctx_mgr()
5158 context->binder_context_mgr_node = new_node; in binder_ioctl_set_ctx_mgr()
5162 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_set_ctx_mgr()
5170 struct binder_context *context = proc->context; in binder_ioctl_get_node_info_for_ref()
5171 __u32 handle = info->handle; in binder_ioctl_get_node_info_for_ref()
5173 if (info->strong_count || info->weak_count || info->reserved1 || in binder_ioctl_get_node_info_for_ref()
5174 info->reserved2 || info->reserved3) { in binder_ioctl_get_node_info_for_ref()
5175 binder_user_error("%d BINDER_GET_NODE_INFO_FOR_REF: only handle may be non-zero.", in binder_ioctl_get_node_info_for_ref()
5176 proc->pid); in binder_ioctl_get_node_info_for_ref()
5177 return -EINVAL; in binder_ioctl_get_node_info_for_ref()
5181 mutex_lock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5182 if (!context->binder_context_mgr_node || in binder_ioctl_get_node_info_for_ref()
5183 context->binder_context_mgr_node->proc != proc) { in binder_ioctl_get_node_info_for_ref()
5184 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5185 return -EPERM; in binder_ioctl_get_node_info_for_ref()
5187 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5191 return -EINVAL; in binder_ioctl_get_node_info_for_ref()
5193 info->strong_count = node->local_strong_refs + in binder_ioctl_get_node_info_for_ref()
5194 node->internal_strong_refs; in binder_ioctl_get_node_info_for_ref()
5195 info->weak_count = node->local_weak_refs; in binder_ioctl_get_node_info_for_ref()
5206 binder_uintptr_t ptr = info->ptr; in binder_ioctl_get_node_debug_info()
5211 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in binder_ioctl_get_node_debug_info()
5214 if (node->ptr > ptr) { in binder_ioctl_get_node_debug_info()
5215 info->ptr = node->ptr; in binder_ioctl_get_node_debug_info()
5216 info->cookie = node->cookie; in binder_ioctl_get_node_debug_info()
5217 info->has_strong_ref = node->has_strong_ref; in binder_ioctl_get_node_debug_info()
5218 info->has_weak_ref = node->has_weak_ref; in binder_ioctl_get_node_debug_info()
5232 if (proc->outstanding_txns > 0) in binder_txns_pending_ilocked()
5235 for (n = rb_first(&proc->threads); n; n = rb_next(n)) { in binder_txns_pending_ilocked()
5237 if (thread->transaction_stack) in binder_txns_pending_ilocked()
5248 if (!info->enable) { in binder_ioctl_freeze()
5250 target_proc->sync_recv = false; in binder_ioctl_freeze()
5251 target_proc->async_recv = false; in binder_ioctl_freeze()
5252 target_proc->is_frozen = false; in binder_ioctl_freeze()
5263 target_proc->sync_recv = false; in binder_ioctl_freeze()
5264 target_proc->async_recv = false; in binder_ioctl_freeze()
5265 target_proc->is_frozen = true; in binder_ioctl_freeze()
5268 if (info->timeout_ms > 0) in binder_ioctl_freeze()
5270 target_proc->freeze_wait, in binder_ioctl_freeze()
5271 (!target_proc->outstanding_txns), in binder_ioctl_freeze()
5272 msecs_to_jiffies(info->timeout_ms)); in binder_ioctl_freeze()
5278 ret = -EAGAIN; in binder_ioctl_freeze()
5284 target_proc->is_frozen = false; in binder_ioctl_freeze()
5298 info->sync_recv = 0; in binder_ioctl_get_freezer_info()
5299 info->async_recv = 0; in binder_ioctl_get_freezer_info()
5303 if (target_proc->pid == info->pid) { in binder_ioctl_get_freezer_info()
5307 info->sync_recv |= target_proc->sync_recv | in binder_ioctl_get_freezer_info()
5309 info->async_recv |= target_proc->async_recv; in binder_ioctl_get_freezer_info()
5316 return -EINVAL; in binder_ioctl_get_freezer_info()
5326 binder_inner_proc_lock(thread->proc); in binder_ioctl_get_extended_error()
5327 ee = thread->ee; in binder_ioctl_get_extended_error()
5328 binder_set_extended_error(&thread->ee, 0, BR_OK, 0); in binder_ioctl_get_extended_error()
5329 binder_inner_proc_unlock(thread->proc); in binder_ioctl_get_extended_error()
5332 return -EFAULT; in binder_ioctl_get_extended_error()
5340 struct binder_proc *proc = filp->private_data; in binder_ioctl()
5345 proc->pid, current->pid, cmd, arg);*/ in binder_ioctl()
5347 binder_selftest_alloc(&proc->alloc); in binder_ioctl()
5357 ret = -ENOMEM; in binder_ioctl()
5372 ret = -EINVAL; in binder_ioctl()
5376 proc->max_threads = max_threads; in binder_ioctl()
5384 ret = -EINVAL; in binder_ioctl()
5399 proc->pid, thread->pid); in binder_ioctl()
5407 &ver->protocol_version)) { in binder_ioctl()
5408 ret = -EINVAL; in binder_ioctl()
5417 ret = -EFAULT; in binder_ioctl()
5426 ret = -EFAULT; in binder_ioctl()
5436 ret = -EFAULT; in binder_ioctl()
5445 ret = -EFAULT; in binder_ioctl()
5458 ret = -EFAULT; in binder_ioctl()
5464 if (target_proc->pid == info.pid) in binder_ioctl()
5470 ret = -EINVAL; in binder_ioctl()
5480 ret = -ENOMEM; in binder_ioctl()
5485 if (target_proc->pid != info.pid) in binder_ioctl()
5489 target_proc->tmp_ref++; in binder_ioctl()
5514 ret = -EFAULT; in binder_ioctl()
5523 ret = -EFAULT; in binder_ioctl()
5532 ret = -EFAULT; in binder_ioctl()
5536 proc->oneway_spam_detection_enabled = (bool)enable; in binder_ioctl()
5546 ret = -EINVAL; in binder_ioctl()
5552 thread->looper_need_return = false; in binder_ioctl()
5554 if (ret && ret != -EINTR) in binder_ioctl()
5555 pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); in binder_ioctl()
5563 struct binder_proc *proc = vma->vm_private_data; in binder_vma_open()
5566 "%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_vma_open()
5567 proc->pid, vma->vm_start, vma->vm_end, in binder_vma_open()
5568 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_vma_open()
5569 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_vma_open()
5574 struct binder_proc *proc = vma->vm_private_data; in binder_vma_close()
5577 "%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_vma_close()
5578 proc->pid, vma->vm_start, vma->vm_end, in binder_vma_close()
5579 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_vma_close()
5580 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_vma_close()
5581 binder_alloc_vma_close(&proc->alloc); in binder_vma_close()
5597 struct binder_proc *proc = filp->private_data; in binder_mmap()
5599 if (proc->tsk != current->group_leader) in binder_mmap()
5600 return -EINVAL; in binder_mmap()
5603 "%s: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_mmap()
5604 __func__, proc->pid, vma->vm_start, vma->vm_end, in binder_mmap()
5605 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_mmap()
5606 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_mmap()
5608 if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { in binder_mmap()
5609 pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, in binder_mmap()
5610 proc->pid, vma->vm_start, vma->vm_end, "bad vm_flags", -EPERM); in binder_mmap()
5611 return -EPERM; in binder_mmap()
5615 vma->vm_ops = &binder_vm_ops; in binder_mmap()
5616 vma->vm_private_data = proc; in binder_mmap()
5618 return binder_alloc_mmap_handler(&proc->alloc, vma); in binder_mmap()
5630 current->group_leader->pid, current->pid); in binder_open()
5634 return -ENOMEM; in binder_open()
5635 spin_lock_init(&proc->inner_lock); in binder_open()
5636 spin_lock_init(&proc->outer_lock); in binder_open()
5637 get_task_struct(current->group_leader); in binder_open()
5638 proc->tsk = current->group_leader; in binder_open()
5639 proc->cred = get_cred(filp->f_cred); in binder_open()
5640 INIT_LIST_HEAD(&proc->todo); in binder_open()
5641 init_waitqueue_head(&proc->freeze_wait); in binder_open()
5642 proc->default_priority = task_nice(current); in binder_open()
5645 binder_dev = nodp->i_private; in binder_open()
5646 info = nodp->i_sb->s_fs_info; in binder_open()
5647 binder_binderfs_dir_entry_proc = info->proc_log_dir; in binder_open()
5649 binder_dev = container_of(filp->private_data, in binder_open()
5652 refcount_inc(&binder_dev->ref); in binder_open()
5653 proc->context = &binder_dev->context; in binder_open()
5654 binder_alloc_init(&proc->alloc); in binder_open()
5657 proc->pid = current->group_leader->pid; in binder_open()
5658 INIT_LIST_HEAD(&proc->delivered_death); in binder_open()
5659 INIT_LIST_HEAD(&proc->waiting_threads); in binder_open()
5660 filp->private_data = proc; in binder_open()
5664 if (itr->pid == proc->pid) { in binder_open()
5669 hlist_add_head(&proc->proc_node, &binder_procs); in binder_open()
5675 snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); in binder_open()
5682 proc->debugfs_entry = debugfs_create_file(strbuf, 0444, in binder_open()
5684 (void *)(unsigned long)proc->pid, in binder_open()
5692 snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); in binder_open()
5700 strbuf, &proc_fops, (void *)(unsigned long)proc->pid); in binder_open()
5702 proc->binderfs_entry = binderfs_entry; in binder_open()
5717 struct binder_proc *proc = filp->private_data; in binder_flush()
5730 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in binder_deferred_flush()
5733 thread->looper_need_return = true; in binder_deferred_flush()
5734 if (thread->looper & BINDER_LOOPER_STATE_WAITING) { in binder_deferred_flush()
5735 wake_up_interruptible(&thread->wait); in binder_deferred_flush()
5742 "binder_flush: %d woke %d threads\n", proc->pid, in binder_deferred_flush()
5748 struct binder_proc *proc = filp->private_data; in binder_release()
5750 debugfs_remove(proc->debugfs_entry); in binder_release()
5752 if (proc->binderfs_entry) { in binder_release()
5753 binderfs_remove_file(proc->binderfs_entry); in binder_release()
5754 proc->binderfs_entry = NULL; in binder_release()
5766 struct binder_proc *proc = node->proc; in binder_node_release()
5768 binder_release_work(proc, &node->async_todo); in binder_node_release()
5772 binder_dequeue_work_ilocked(&node->work); in binder_node_release()
5776 BUG_ON(!node->tmp_refs); in binder_node_release()
5777 if (hlist_empty(&node->refs) && node->tmp_refs == 1) { in binder_node_release()
5785 node->proc = NULL; in binder_node_release()
5786 node->local_strong_refs = 0; in binder_node_release()
5787 node->local_weak_refs = 0; in binder_node_release()
5791 hlist_add_head(&node->dead_node, &binder_dead_nodes); in binder_node_release()
5794 hlist_for_each_entry(ref, &node->refs, node_entry) { in binder_node_release()
5802 binder_inner_proc_lock(ref->proc); in binder_node_release()
5803 if (!ref->death) { in binder_node_release()
5804 binder_inner_proc_unlock(ref->proc); in binder_node_release()
5810 BUG_ON(!list_empty(&ref->death->work.entry)); in binder_node_release()
5811 ref->death->work.type = BINDER_WORK_DEAD_BINDER; in binder_node_release()
5812 binder_enqueue_work_ilocked(&ref->death->work, in binder_node_release()
5813 &ref->proc->todo); in binder_node_release()
5814 binder_wakeup_proc_ilocked(ref->proc); in binder_node_release()
5815 binder_inner_proc_unlock(ref->proc); in binder_node_release()
5820 node->debug_id, refs, death); in binder_node_release()
5829 struct binder_context *context = proc->context; in binder_deferred_release()
5834 hlist_del(&proc->proc_node); in binder_deferred_release()
5837 mutex_lock(&context->context_mgr_node_lock); in binder_deferred_release()
5838 if (context->binder_context_mgr_node && in binder_deferred_release()
5839 context->binder_context_mgr_node->proc == proc) { in binder_deferred_release()
5842 __func__, proc->pid); in binder_deferred_release()
5843 context->binder_context_mgr_node = NULL; in binder_deferred_release()
5845 mutex_unlock(&context->context_mgr_node_lock); in binder_deferred_release()
5851 proc->tmp_ref++; in binder_deferred_release()
5853 proc->is_dead = true; in binder_deferred_release()
5854 proc->is_frozen = false; in binder_deferred_release()
5855 proc->sync_recv = false; in binder_deferred_release()
5856 proc->async_recv = false; in binder_deferred_release()
5859 while ((n = rb_first(&proc->threads))) { in binder_deferred_release()
5871 while ((n = rb_first(&proc->nodes))) { in binder_deferred_release()
5882 rb_erase(&node->rb_node, &proc->nodes); in binder_deferred_release()
5891 while ((n = rb_first(&proc->refs_by_desc))) { in binder_deferred_release()
5903 binder_release_work(proc, &proc->todo); in binder_deferred_release()
5904 binder_release_work(proc, &proc->delivered_death); in binder_deferred_release()
5908 __func__, proc->pid, threads, nodes, incoming_refs, in binder_deferred_release()
5925 hlist_del_init(&proc->deferred_work_node); in binder_deferred_func()
5926 defer = proc->deferred_work; in binder_deferred_func()
5927 proc->deferred_work = 0; in binder_deferred_func()
5947 proc->deferred_work |= defer; in binder_defer_work()
5948 if (hlist_unhashed(&proc->deferred_work_node)) { in binder_defer_work()
5949 hlist_add_head(&proc->deferred_work_node, in binder_defer_work()
5958 const char *prefix, in print_binder_transaction_ilocked() argument
5962 struct binder_buffer *buffer = t->buffer; in print_binder_transaction_ilocked()
5965 spin_lock(&t->lock); in print_binder_transaction_ilocked()
5966 to_proc = t->to_proc; in print_binder_transaction_ilocked()
5969 prefix, t->debug_id, t, in print_binder_transaction_ilocked()
5970 t->from_pid, in print_binder_transaction_ilocked()
5971 t->from_tid, in print_binder_transaction_ilocked()
5972 to_proc ? to_proc->pid : 0, in print_binder_transaction_ilocked()
5973 t->to_thread ? t->to_thread->pid : 0, in print_binder_transaction_ilocked()
5974 t->code, t->flags, t->priority, t->need_reply, in print_binder_transaction_ilocked()
5975 ktime_ms_delta(current_time, t->start_time)); in print_binder_transaction_ilocked()
5976 spin_unlock(&t->lock); in print_binder_transaction_ilocked()
5991 if (buffer->target_node) in print_binder_transaction_ilocked()
5992 seq_printf(m, " node %d", buffer->target_node->debug_id); in print_binder_transaction_ilocked()
5994 buffer->data_size, buffer->offsets_size, in print_binder_transaction_ilocked()
5995 proc->alloc.buffer - buffer->user_data); in print_binder_transaction_ilocked()
6000 const char *prefix, in print_binder_work_ilocked() argument
6007 switch (w->type) { in print_binder_work_ilocked()
6018 prefix, e->cmd); in print_binder_work_ilocked()
6021 seq_printf(m, "%stransaction complete\n", prefix); in print_binder_work_ilocked()
6026 prefix, node->debug_id, in print_binder_work_ilocked()
6027 (u64)node->ptr, (u64)node->cookie); in print_binder_work_ilocked()
6030 seq_printf(m, "%shas dead binder\n", prefix); in print_binder_work_ilocked()
6033 seq_printf(m, "%shas cleared dead binder\n", prefix); in print_binder_work_ilocked()
6036 seq_printf(m, "%shas cleared death notification\n", prefix); in print_binder_work_ilocked()
6039 seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); in print_binder_work_ilocked()
6050 size_t start_pos = m->count; in print_binder_thread_ilocked()
6054 thread->pid, thread->looper, in print_binder_thread_ilocked()
6055 thread->looper_need_return, in print_binder_thread_ilocked()
6056 atomic_read(&thread->tmp_ref)); in print_binder_thread_ilocked()
6057 header_pos = m->count; in print_binder_thread_ilocked()
6058 t = thread->transaction_stack; in print_binder_thread_ilocked()
6060 if (t->from == thread) { in print_binder_thread_ilocked()
6061 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6063 t = t->from_parent; in print_binder_thread_ilocked()
6064 } else if (t->to_thread == thread) { in print_binder_thread_ilocked()
6065 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6067 t = t->to_parent; in print_binder_thread_ilocked()
6069 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6074 list_for_each_entry(w, &thread->todo, entry) { in print_binder_thread_ilocked()
6075 print_binder_work_ilocked(m, thread->proc, " ", in print_binder_thread_ilocked()
6078 if (!print_always && m->count == header_pos) in print_binder_thread_ilocked()
6079 m->count = start_pos; in print_binder_thread_ilocked()
6090 hlist_for_each_entry(ref, &node->refs, node_entry) in print_binder_node_nilocked()
6094 node->debug_id, (u64)node->ptr, (u64)node->cookie, in print_binder_node_nilocked()
6095 node->has_strong_ref, node->has_weak_ref, in print_binder_node_nilocked()
6096 node->local_strong_refs, node->local_weak_refs, in print_binder_node_nilocked()
6097 node->internal_strong_refs, count, node->tmp_refs); in print_binder_node_nilocked()
6100 hlist_for_each_entry(ref, &node->refs, node_entry) in print_binder_node_nilocked()
6101 seq_printf(m, " %d", ref->proc->pid); in print_binder_node_nilocked()
6104 if (node->proc) { in print_binder_node_nilocked()
6105 list_for_each_entry(w, &node->async_todo, entry) in print_binder_node_nilocked()
6106 print_binder_work_ilocked(m, node->proc, " ", in print_binder_node_nilocked()
6107 " pending async transaction", w); in print_binder_node_nilocked()
6114 binder_node_lock(ref->node); in print_binder_ref_olocked()
6116 ref->data.debug_id, ref->data.desc, in print_binder_ref_olocked()
6117 ref->node->proc ? "" : "dead ", in print_binder_ref_olocked()
6118 ref->node->debug_id, ref->data.strong, in print_binder_ref_olocked()
6119 ref->data.weak, ref->death); in print_binder_ref_olocked()
6120 binder_node_unlock(ref->node); in print_binder_ref_olocked()
6128 size_t start_pos = m->count; in print_binder_proc()
6132 seq_printf(m, "proc %d\n", proc->pid); in print_binder_proc()
6133 seq_printf(m, "context %s\n", proc->context->name); in print_binder_proc()
6134 header_pos = m->count; in print_binder_proc()
6137 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) in print_binder_proc()
6141 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in print_binder_proc()
6144 if (!print_all && !node->has_async_transaction) in print_binder_proc()
6169 for (n = rb_first(&proc->refs_by_desc); in print_binder_proc()
6177 binder_alloc_print_allocated(m, &proc->alloc); in print_binder_proc()
6179 list_for_each_entry(w, &proc->todo, entry) in print_binder_proc()
6182 list_for_each_entry(w, &proc->delivered_death, entry) { in print_binder_proc()
6187 if (!print_all && m->count == header_pos) in print_binder_proc()
6188 m->count = start_pos; in print_binder_proc()
6247 static void print_binder_stats(struct seq_file *m, const char *prefix, in print_binder_stats() argument
6252 BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != in print_binder_stats()
6254 for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { in print_binder_stats()
6255 int temp = atomic_read(&stats->bc[i]); in print_binder_stats()
6258 seq_printf(m, "%s%s: %d\n", prefix, in print_binder_stats()
6262 BUILD_BUG_ON(ARRAY_SIZE(stats->br) != in print_binder_stats()
6264 for (i = 0; i < ARRAY_SIZE(stats->br); i++) { in print_binder_stats()
6265 int temp = atomic_read(&stats->br[i]); in print_binder_stats()
6268 seq_printf(m, "%s%s: %d\n", prefix, in print_binder_stats()
6272 BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != in print_binder_stats()
6274 BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != in print_binder_stats()
6275 ARRAY_SIZE(stats->obj_deleted)); in print_binder_stats()
6276 for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { in print_binder_stats()
6277 int created = atomic_read(&stats->obj_created[i]); in print_binder_stats()
6278 int deleted = atomic_read(&stats->obj_deleted[i]); in print_binder_stats()
6282 prefix, in print_binder_stats()
6284 created - deleted, in print_binder_stats()
6297 binder_alloc_get_free_async_space(&proc->alloc); in print_binder_proc_stats()
6299 seq_printf(m, "proc %d\n", proc->pid); in print_binder_proc_stats()
6300 seq_printf(m, "context %s\n", proc->context->name); in print_binder_proc_stats()
6304 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) in print_binder_proc_stats()
6307 list_for_each_entry(thread, &proc->waiting_threads, waiting_thread_node) in print_binder_proc_stats()
6313 " free async space %zd\n", proc->requested_threads, in print_binder_proc_stats()
6314 proc->requested_threads_started, proc->max_threads, in print_binder_proc_stats()
6318 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) in print_binder_proc_stats()
6326 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { in print_binder_proc_stats()
6330 strong += ref->data.strong; in print_binder_proc_stats()
6331 weak += ref->data.weak; in print_binder_proc_stats()
6336 count = binder_alloc_get_allocated_count(&proc->alloc); in print_binder_proc_stats()
6339 binder_alloc_print_pages(m, &proc->alloc); in print_binder_proc_stats()
6343 list_for_each_entry(w, &proc->todo, entry) { in print_binder_proc_stats()
6344 if (w->type == BINDER_WORK_TRANSACTION) in print_binder_proc_stats()
6350 print_binder_stats(m, " ", &proc->stats); in print_binder_proc_stats()
6370 node->tmp_refs++; in state_show()
6424 int pid = (unsigned long)m->private; in proc_show()
6428 if (itr->pid == pid) { in proc_show()
6441 int debug_id = READ_ONCE(e->debug_id_done); in print_binder_transaction_log_entry()
6449 e->debug_id, (e->call_type == 2) ? "reply" : in print_binder_transaction_log_entry()
6450 ((e->call_type == 1) ? "async" : "call "), e->from_proc, in print_binder_transaction_log_entry()
6451 e->from_thread, e->to_proc, e->to_thread, e->context_name, in print_binder_transaction_log_entry()
6452 e->to_node, e->target_handle, e->data_size, e->offsets_size, in print_binder_transaction_log_entry()
6453 e->return_error, e->return_error_param, in print_binder_transaction_log_entry()
6454 e->return_error_line); in print_binder_transaction_log_entry()
6456 * read-barrier to guarantee read of debug_id_done after in print_binder_transaction_log_entry()
6460 seq_printf(m, debug_id && debug_id == READ_ONCE(e->debug_id_done) ? in print_binder_transaction_log_entry()
6466 struct binder_transaction_log *log = m->private; in transaction_log_show()
6467 unsigned int log_cur = atomic_read(&log->cur); in transaction_log_show()
6473 cur = count < ARRAY_SIZE(log->entry) && !log->full ? in transaction_log_show()
6474 0 : count % ARRAY_SIZE(log->entry); in transaction_log_show()
6475 if (count > ARRAY_SIZE(log->entry) || log->full) in transaction_log_show()
6476 count = ARRAY_SIZE(log->entry); in transaction_log_show()
6478 unsigned int index = cur++ % ARRAY_SIZE(log->entry); in transaction_log_show()
6480 print_binder_transaction_log_entry(m, &log->entry[index]); in transaction_log_show()
6542 return -ENOMEM; in init_binder_device()
6544 binder_device->miscdev.fops = &binder_fops; in init_binder_device()
6545 binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; in init_binder_device()
6546 binder_device->miscdev.name = name; in init_binder_device()
6548 refcount_set(&binder_device->ref, 1); in init_binder_device()
6549 binder_device->context.binder_context_mgr_uid = INVALID_UID; in init_binder_device()
6550 binder_device->context.name = name; in init_binder_device()
6551 mutex_init(&binder_device->context.context_mgr_node_lock); in init_binder_device()
6553 ret = misc_register(&binder_device->miscdev); in init_binder_device()
6559 hlist_add_head(&binder_device->hlist, &binder_devices); in init_binder_device()
6583 debugfs_create_file(db_entry->name, in binder_init()
6584 db_entry->mode, in binder_init()
6586 db_entry->data, in binder_init()
6587 db_entry->fops); in binder_init()
6596 * tokenize it in-place. in binder_init()
6600 ret = -ENOMEM; in binder_init()
6620 misc_deregister(&device->miscdev); in binder_init()
6621 hlist_del(&device->hlist); in binder_init()