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
226 unsigned int cur = atomic_inc_return(&log->cur); in binder_transaction_log_add()
228 if (cur >= ARRAY_SIZE(log->entry)) in binder_transaction_log_add()
229 log->full = true; in binder_transaction_log_add()
230 e = &log->entry[cur % ARRAY_SIZE(log->entry)]; in binder_transaction_log_add()
231 WRITE_ONCE(e->debug_id_done, 0); in binder_transaction_log_add()
233 * write-barrier to synchronize access to e->debug_id_done. in binder_transaction_log_add()
243 * struct binder_work - work enqueued on a worklist
247 * There are separate work lists for proc, thread, and node (async).
269 * struct binder_node - binder node bookkeeping
274 * (protected by @proc->inner_lock)
275 * @rb_node: element for proc->nodes tree
276 * (protected by @proc->inner_lock)
285 * (protected by @proc->inner_lock if @proc
288 * (protected by @proc->inner_lock if @proc
291 * (protected by @proc->inner_lock if @proc
294 * (protected by @proc->inner_lock while @proc
304 * (protected by @proc->inner_lock if @proc
307 * (protected by @proc->inner_lock if @proc
310 * (protected by @proc->inner_lock if @proc
313 * (protected by @proc->inner_lock if @proc
315 * @has_async_transaction: async transaction to node in progress
323 * @async_todo: list of async work items
324 * (protected by @proc->inner_lock)
377 * struct binder_ref_data - binder_ref counts and id
396 * struct binder_ref - struct to track references on nodes
400 * @node_entry: list entry for node->refs list in target node
401 * (protected by @node->lock)
404 * ref for deletion in binder_cleanup_ref, a non-NULL
407 * (protected by @node->lock)
410 * structure is unsafe to access without holding @proc->outer_lock.
432 * struct binder_proc - binder process bookkeeping
437 * this proc ordered by node->ptr
439 * @refs_by_desc: rbtree of refs ordered by ref->desc
441 * @refs_by_node: rbtree of refs ordered by ref->node
461 * @stats: per-process binder statistics
484 * @binderfs_entry: process-specific binderfs log file
528 * struct binder_thread - binder thread bookkeeping
531 * @rb_node: element for proc->threads rbtree
532 * (protected by @proc->inner_lock)
533 * @waiting_thread_node: element for @proc->waiting_threads list
534 * (protected by @proc->inner_lock)
541 * @transaction_stack: stack of in-progress transactions for this thread
542 * (protected by @proc->inner_lock)
544 * (protected by @proc->inner_lock)
546 * (protected by @proc->inner_lock)
550 * (protected by @proc->inner_lock)
552 * @stats: per-thread statistics
555 * (atomic since @proc->inner_lock cannot
559 * (protected by @proc->inner_lock)
588 * struct binder_txn_fd_fixup - transaction fd fixup list element
642 * struct binder_object - union of flat binder object types
649 * Used for type-independent object copies
662 * binder_proc_lock() - Acquire outer lock for given binder_proc
665 * Acquires proc->outer_lock. Used to protect binder_ref
671 __acquires(&proc->outer_lock) in _binder_proc_lock()
675 spin_lock(&proc->outer_lock); in _binder_proc_lock()
679 * binder_proc_unlock() - Release spinlock for given binder_proc
687 __releases(&proc->outer_lock) in _binder_proc_unlock()
691 spin_unlock(&proc->outer_lock); in _binder_proc_unlock()
695 * binder_inner_proc_lock() - Acquire inner lock for given binder_proc
698 * Acquires proc->inner_lock. Used to protect todo lists
703 __acquires(&proc->inner_lock) in _binder_inner_proc_lock()
707 spin_lock(&proc->inner_lock); in _binder_inner_proc_lock()
711 * binder_inner_proc_unlock() - Release inner lock for given binder_proc
719 __releases(&proc->inner_lock) in _binder_inner_proc_unlock()
723 spin_unlock(&proc->inner_lock); in _binder_inner_proc_unlock()
727 * binder_node_lock() - Acquire spinlock for given binder_node
730 * Acquires node->lock. Used to protect binder_node fields
735 __acquires(&node->lock) in _binder_node_lock()
739 spin_lock(&node->lock); in _binder_node_lock()
743 * binder_node_unlock() - Release spinlock for given binder_proc
751 __releases(&node->lock) in _binder_node_unlock()
755 spin_unlock(&node->lock); in _binder_node_unlock()
759 * binder_node_inner_lock() - Acquire node and inner locks
762 * Acquires node->lock. If node->proc also acquires
763 * proc->inner_lock. Used to protect binder_node fields
768 __acquires(&node->lock) __acquires(&node->proc->inner_lock) in _binder_node_inner_lock()
772 spin_lock(&node->lock); in _binder_node_inner_lock()
773 if (node->proc) in _binder_node_inner_lock()
774 binder_inner_proc_lock(node->proc); in _binder_node_inner_lock()
777 __acquire(&node->proc->inner_lock); in _binder_node_inner_lock()
781 * binder_node_unlock() - Release node and inner locks
789 __releases(&node->lock) __releases(&node->proc->inner_lock) in _binder_node_inner_unlock()
791 struct binder_proc *proc = node->proc; in _binder_node_inner_unlock()
799 __release(&node->proc->inner_lock); in _binder_node_inner_unlock()
800 spin_unlock(&node->lock); in _binder_node_inner_unlock()
809 * binder_worklist_empty() - Check if no items on the work list
827 * binder_enqueue_work_ilocked() - Add an item to the work list
834 * Requires the proc->inner_lock to be held.
841 BUG_ON(work->entry.next && !list_empty(&work->entry)); in binder_enqueue_work_ilocked()
842 list_add_tail(&work->entry, target_list); in binder_enqueue_work_ilocked()
846 * binder_enqueue_deferred_thread_work_ilocked() - Add deferred thread work
854 * Requires the proc->inner_lock to be held.
860 WARN_ON(!list_empty(&thread->waiting_thread_node)); in binder_enqueue_deferred_thread_work_ilocked()
861 binder_enqueue_work_ilocked(work, &thread->todo); in binder_enqueue_deferred_thread_work_ilocked()
865 * binder_enqueue_thread_work_ilocked() - Add an item to the thread work list
872 * Requires the proc->inner_lock to be held.
878 WARN_ON(!list_empty(&thread->waiting_thread_node)); in binder_enqueue_thread_work_ilocked()
879 binder_enqueue_work_ilocked(work, &thread->todo); in binder_enqueue_thread_work_ilocked()
881 /* (e)poll-based threads require an explicit wakeup signal when in binder_enqueue_thread_work_ilocked()
886 if (thread->looper & BINDER_LOOPER_STATE_POLL && in binder_enqueue_thread_work_ilocked()
887 thread->pid == current->pid && !thread->process_todo) in binder_enqueue_thread_work_ilocked()
888 wake_up_interruptible_sync(&thread->wait); in binder_enqueue_thread_work_ilocked()
890 thread->process_todo = true; in binder_enqueue_thread_work_ilocked()
894 * binder_enqueue_thread_work() - Add an item to the thread work list
905 binder_inner_proc_lock(thread->proc); in binder_enqueue_thread_work()
907 binder_inner_proc_unlock(thread->proc); in binder_enqueue_thread_work()
913 list_del_init(&work->entry); in binder_dequeue_work_ilocked()
917 * binder_dequeue_work() - Removes an item from the work list
939 list_del_init(&w->entry); in binder_dequeue_work_head_ilocked()
962 return thread->process_todo || in binder_has_work_ilocked()
963 thread->looper_need_return || in binder_has_work_ilocked()
965 !binder_worklist_empty_ilocked(&thread->proc->todo)); in binder_has_work_ilocked()
972 binder_inner_proc_lock(thread->proc); in binder_has_work()
974 binder_inner_proc_unlock(thread->proc); in binder_has_work()
981 return !thread->transaction_stack && in binder_available_for_proc_work_ilocked()
982 binder_worklist_empty_ilocked(&thread->todo) && in binder_available_for_proc_work_ilocked()
983 (thread->looper & (BINDER_LOOPER_STATE_ENTERED | in binder_available_for_proc_work_ilocked()
993 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in binder_wakeup_poll_threads_ilocked()
995 if (thread->looper & BINDER_LOOPER_STATE_POLL && in binder_wakeup_poll_threads_ilocked()
998 wake_up_interruptible_sync(&thread->wait); in binder_wakeup_poll_threads_ilocked()
1000 wake_up_interruptible(&thread->wait); in binder_wakeup_poll_threads_ilocked()
1006 * binder_select_thread_ilocked() - selects a thread for doing proc work.
1022 assert_spin_locked(&proc->inner_lock); in binder_select_thread_ilocked()
1023 thread = list_first_entry_or_null(&proc->waiting_threads, in binder_select_thread_ilocked()
1028 list_del_init(&thread->waiting_thread_node); in binder_select_thread_ilocked()
1034 * binder_wakeup_thread_ilocked() - wakes up a thread for doing proc work.
1036 * @thread: specific thread to wake-up (may be NULL)
1037 * @sync: whether to do a synchronous wake-up
1040 * The caller may provide a specific thread to wake-up in
1053 assert_spin_locked(&proc->inner_lock); in binder_wakeup_thread_ilocked()
1057 wake_up_interruptible_sync(&thread->wait); in binder_wakeup_thread_ilocked()
1059 wake_up_interruptible(&thread->wait); in binder_wakeup_thread_ilocked()
1073 * a thread that called into (e)poll is handling non-binder in binder_wakeup_thread_ilocked()
1097 current->pid, nice, min_nice); in binder_set_nice()
1101 binder_user_error("%d RLIMIT_NICE not set\n", current->pid); in binder_set_nice()
1107 struct rb_node *n = proc->nodes.rb_node; in binder_get_node_ilocked()
1110 assert_spin_locked(&proc->inner_lock); in binder_get_node_ilocked()
1115 if (ptr < node->ptr) in binder_get_node_ilocked()
1116 n = n->rb_left; in binder_get_node_ilocked()
1117 else if (ptr > node->ptr) in binder_get_node_ilocked()
1118 n = n->rb_right; in binder_get_node_ilocked()
1148 struct rb_node **p = &proc->nodes.rb_node; in binder_init_node_ilocked()
1151 binder_uintptr_t ptr = fp ? fp->binder : 0; in binder_init_node_ilocked()
1152 binder_uintptr_t cookie = fp ? fp->cookie : 0; in binder_init_node_ilocked()
1153 __u32 flags = fp ? fp->flags : 0; in binder_init_node_ilocked()
1155 assert_spin_locked(&proc->inner_lock); in binder_init_node_ilocked()
1162 if (ptr < node->ptr) in binder_init_node_ilocked()
1163 p = &(*p)->rb_left; in binder_init_node_ilocked()
1164 else if (ptr > node->ptr) in binder_init_node_ilocked()
1165 p = &(*p)->rb_right; in binder_init_node_ilocked()
1178 node->tmp_refs++; in binder_init_node_ilocked()
1179 rb_link_node(&node->rb_node, parent, p); in binder_init_node_ilocked()
1180 rb_insert_color(&node->rb_node, &proc->nodes); in binder_init_node_ilocked()
1181 node->debug_id = atomic_inc_return(&binder_last_id); in binder_init_node_ilocked()
1182 node->proc = proc; in binder_init_node_ilocked()
1183 node->ptr = ptr; in binder_init_node_ilocked()
1184 node->cookie = cookie; in binder_init_node_ilocked()
1185 node->work.type = BINDER_WORK_NODE; in binder_init_node_ilocked()
1186 node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK; in binder_init_node_ilocked()
1187 node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); in binder_init_node_ilocked()
1188 node->txn_security_ctx = !!(flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX); in binder_init_node_ilocked()
1189 spin_lock_init(&node->lock); in binder_init_node_ilocked()
1190 INIT_LIST_HEAD(&node->work.entry); in binder_init_node_ilocked()
1191 INIT_LIST_HEAD(&node->async_todo); in binder_init_node_ilocked()
1194 proc->pid, current->pid, node->debug_id, in binder_init_node_ilocked()
1195 (u64)node->ptr, (u64)node->cookie); in binder_init_node_ilocked()
1230 struct binder_proc *proc = node->proc; in binder_inc_node_nilocked()
1232 assert_spin_locked(&node->lock); in binder_inc_node_nilocked()
1234 assert_spin_locked(&proc->inner_lock); in binder_inc_node_nilocked()
1238 node->internal_strong_refs == 0 && in binder_inc_node_nilocked()
1239 !(node->proc && in binder_inc_node_nilocked()
1240 node == node->proc->context->binder_context_mgr_node && in binder_inc_node_nilocked()
1241 node->has_strong_ref)) { in binder_inc_node_nilocked()
1243 node->debug_id); in binder_inc_node_nilocked()
1244 return -EINVAL; in binder_inc_node_nilocked()
1246 node->internal_strong_refs++; in binder_inc_node_nilocked()
1248 node->local_strong_refs++; in binder_inc_node_nilocked()
1249 if (!node->has_strong_ref && target_list) { in binder_inc_node_nilocked()
1252 binder_dequeue_work_ilocked(&node->work); in binder_inc_node_nilocked()
1253 BUG_ON(&thread->todo != target_list); in binder_inc_node_nilocked()
1255 &node->work); in binder_inc_node_nilocked()
1259 node->local_weak_refs++; in binder_inc_node_nilocked()
1260 if (!node->has_weak_ref && list_empty(&node->work.entry)) { in binder_inc_node_nilocked()
1263 node->debug_id); in binder_inc_node_nilocked()
1264 return -EINVAL; in binder_inc_node_nilocked()
1269 binder_enqueue_work_ilocked(&node->work, target_list); in binder_inc_node_nilocked()
1290 struct binder_proc *proc = node->proc; in binder_dec_node_nilocked()
1292 assert_spin_locked(&node->lock); in binder_dec_node_nilocked()
1294 assert_spin_locked(&proc->inner_lock); in binder_dec_node_nilocked()
1297 node->internal_strong_refs--; in binder_dec_node_nilocked()
1299 node->local_strong_refs--; in binder_dec_node_nilocked()
1300 if (node->local_strong_refs || node->internal_strong_refs) in binder_dec_node_nilocked()
1304 node->local_weak_refs--; in binder_dec_node_nilocked()
1305 if (node->local_weak_refs || node->tmp_refs || in binder_dec_node_nilocked()
1306 !hlist_empty(&node->refs)) in binder_dec_node_nilocked()
1310 if (proc && (node->has_strong_ref || node->has_weak_ref)) { in binder_dec_node_nilocked()
1311 if (list_empty(&node->work.entry)) { in binder_dec_node_nilocked()
1312 binder_enqueue_work_ilocked(&node->work, &proc->todo); in binder_dec_node_nilocked()
1316 if (hlist_empty(&node->refs) && !node->local_strong_refs && in binder_dec_node_nilocked()
1317 !node->local_weak_refs && !node->tmp_refs) { in binder_dec_node_nilocked()
1319 binder_dequeue_work_ilocked(&node->work); in binder_dec_node_nilocked()
1320 rb_erase(&node->rb_node, &proc->nodes); in binder_dec_node_nilocked()
1323 node->debug_id); in binder_dec_node_nilocked()
1325 BUG_ON(!list_empty(&node->work.entry)); in binder_dec_node_nilocked()
1331 if (node->tmp_refs) { in binder_dec_node_nilocked()
1335 hlist_del(&node->dead_node); in binder_dec_node_nilocked()
1339 node->debug_id); in binder_dec_node_nilocked()
1365 node->tmp_refs++; in binder_inc_node_tmpref_ilocked()
1369 * binder_inc_node_tmpref() - take a temporary reference on node
1376 * (node->proc is NULL), use binder_dead_nodes_lock to protect
1377 * node->tmp_refs against dead-node-only cases where the node
1384 if (node->proc) in binder_inc_node_tmpref()
1385 binder_inner_proc_lock(node->proc); in binder_inc_node_tmpref()
1389 if (node->proc) in binder_inc_node_tmpref()
1390 binder_inner_proc_unlock(node->proc); in binder_inc_node_tmpref()
1397 * binder_dec_node_tmpref() - remove a temporary reference on node
1407 if (!node->proc) in binder_dec_node_tmpref()
1411 node->tmp_refs--; in binder_dec_node_tmpref()
1412 BUG_ON(node->tmp_refs < 0); in binder_dec_node_tmpref()
1413 if (!node->proc) in binder_dec_node_tmpref()
1437 struct rb_node *n = proc->refs_by_desc.rb_node; in binder_get_ref_olocked()
1443 if (desc < ref->data.desc) { in binder_get_ref_olocked()
1444 n = n->rb_left; in binder_get_ref_olocked()
1445 } else if (desc > ref->data.desc) { in binder_get_ref_olocked()
1446 n = n->rb_right; in binder_get_ref_olocked()
1447 } else if (need_strong_ref && !ref->data.strong) { in binder_get_ref_olocked()
1458 * binder_get_ref_for_node_olocked() - get the ref associated with given node
1471 * returned ref would be different than the passed-in
1480 struct binder_context *context = proc->context; in binder_get_ref_for_node_olocked()
1481 struct rb_node **p = &proc->refs_by_node.rb_node; in binder_get_ref_for_node_olocked()
1490 if (node < ref->node) in binder_get_ref_for_node_olocked()
1491 p = &(*p)->rb_left; in binder_get_ref_for_node_olocked()
1492 else if (node > ref->node) in binder_get_ref_for_node_olocked()
1493 p = &(*p)->rb_right; in binder_get_ref_for_node_olocked()
1501 new_ref->data.debug_id = atomic_inc_return(&binder_last_id); in binder_get_ref_for_node_olocked()
1502 new_ref->proc = proc; in binder_get_ref_for_node_olocked()
1503 new_ref->node = node; in binder_get_ref_for_node_olocked()
1504 rb_link_node(&new_ref->rb_node_node, parent, p); in binder_get_ref_for_node_olocked()
1505 rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); in binder_get_ref_for_node_olocked()
1507 new_ref->data.desc = (node == context->binder_context_mgr_node) ? 0 : 1; in binder_get_ref_for_node_olocked()
1508 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { in binder_get_ref_for_node_olocked()
1510 if (ref->data.desc > new_ref->data.desc) in binder_get_ref_for_node_olocked()
1512 new_ref->data.desc = ref->data.desc + 1; in binder_get_ref_for_node_olocked()
1515 p = &proc->refs_by_desc.rb_node; in binder_get_ref_for_node_olocked()
1520 if (new_ref->data.desc < ref->data.desc) in binder_get_ref_for_node_olocked()
1521 p = &(*p)->rb_left; in binder_get_ref_for_node_olocked()
1522 else if (new_ref->data.desc > ref->data.desc) in binder_get_ref_for_node_olocked()
1523 p = &(*p)->rb_right; in binder_get_ref_for_node_olocked()
1527 rb_link_node(&new_ref->rb_node_desc, parent, p); in binder_get_ref_for_node_olocked()
1528 rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); in binder_get_ref_for_node_olocked()
1531 hlist_add_head(&new_ref->node_entry, &node->refs); in binder_get_ref_for_node_olocked()
1535 proc->pid, new_ref->data.debug_id, new_ref->data.desc, in binder_get_ref_for_node_olocked()
1536 node->debug_id); in binder_get_ref_for_node_olocked()
1547 ref->proc->pid, ref->data.debug_id, ref->data.desc, in binder_cleanup_ref_olocked()
1548 ref->node->debug_id); in binder_cleanup_ref_olocked()
1550 rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); in binder_cleanup_ref_olocked()
1551 rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); in binder_cleanup_ref_olocked()
1553 binder_node_inner_lock(ref->node); in binder_cleanup_ref_olocked()
1554 if (ref->data.strong) in binder_cleanup_ref_olocked()
1555 binder_dec_node_nilocked(ref->node, 1, 1); in binder_cleanup_ref_olocked()
1557 hlist_del(&ref->node_entry); in binder_cleanup_ref_olocked()
1558 delete_node = binder_dec_node_nilocked(ref->node, 0, 1); in binder_cleanup_ref_olocked()
1559 binder_node_inner_unlock(ref->node); in binder_cleanup_ref_olocked()
1561 * Clear ref->node unless we want the caller to free the node in binder_cleanup_ref_olocked()
1565 * The caller uses ref->node to determine in binder_cleanup_ref_olocked()
1569 ref->node = NULL; in binder_cleanup_ref_olocked()
1572 if (ref->death) { in binder_cleanup_ref_olocked()
1575 ref->proc->pid, ref->data.debug_id, in binder_cleanup_ref_olocked()
1576 ref->data.desc); in binder_cleanup_ref_olocked()
1577 binder_dequeue_work(ref->proc, &ref->death->work); in binder_cleanup_ref_olocked()
1584 * binder_inc_ref_olocked() - increment the ref for given handle
1589 * Increment the ref. @ref->proc->outer_lock must be held on entry
1599 if (ref->data.strong == 0) { in binder_inc_ref_olocked()
1600 ret = binder_inc_node(ref->node, 1, 1, target_list); in binder_inc_ref_olocked()
1604 ref->data.strong++; in binder_inc_ref_olocked()
1606 if (ref->data.weak == 0) { in binder_inc_ref_olocked()
1607 ret = binder_inc_node(ref->node, 0, 1, target_list); in binder_inc_ref_olocked()
1611 ref->data.weak++; in binder_inc_ref_olocked()
1617 * binder_dec_ref() - dec the ref for given handle
1628 if (ref->data.strong == 0) { in binder_dec_ref_olocked()
1630 ref->proc->pid, ref->data.debug_id, in binder_dec_ref_olocked()
1631 ref->data.desc, ref->data.strong, in binder_dec_ref_olocked()
1632 ref->data.weak); in binder_dec_ref_olocked()
1635 ref->data.strong--; in binder_dec_ref_olocked()
1636 if (ref->data.strong == 0) in binder_dec_ref_olocked()
1637 binder_dec_node(ref->node, strong, 1); in binder_dec_ref_olocked()
1639 if (ref->data.weak == 0) { in binder_dec_ref_olocked()
1641 ref->proc->pid, ref->data.debug_id, in binder_dec_ref_olocked()
1642 ref->data.desc, ref->data.strong, in binder_dec_ref_olocked()
1643 ref->data.weak); in binder_dec_ref_olocked()
1646 ref->data.weak--; in binder_dec_ref_olocked()
1648 if (ref->data.strong == 0 && ref->data.weak == 0) { in binder_dec_ref_olocked()
1656 * binder_get_node_from_ref() - get the node from the given proc/desc
1678 node = ref->node; in binder_get_node_from_ref()
1685 *rdata = ref->data; in binder_get_node_from_ref()
1696 * binder_free_ref() - free the binder_ref
1699 * Free the binder_ref. Free the binder_node indicated by ref->node
1700 * (if non-NULL) and the binder_ref_death indicated by ref->death.
1704 if (ref->node) in binder_free_ref()
1705 binder_free_node(ref->node); in binder_free_ref()
1706 kfree(ref->death); in binder_free_ref()
1711 * binder_update_ref_for_handle() - inc/dec the ref for given handle
1734 ret = -EINVAL; in binder_update_ref_for_handle()
1743 *rdata = ref->data; in binder_update_ref_for_handle()
1756 * binder_dec_ref_for_handle() - dec the ref for given handle
1774 * binder_inc_ref_for_node() - increment the ref for given proc/node
1802 return -ENOMEM; in binder_inc_ref_for_node()
1807 *rdata = ref->data; in binder_inc_ref_for_node()
1834 assert_spin_locked(&target_thread->proc->inner_lock); in binder_pop_transaction_ilocked()
1835 BUG_ON(target_thread->transaction_stack != t); in binder_pop_transaction_ilocked()
1836 BUG_ON(target_thread->transaction_stack->from != target_thread); in binder_pop_transaction_ilocked()
1837 target_thread->transaction_stack = in binder_pop_transaction_ilocked()
1838 target_thread->transaction_stack->from_parent; in binder_pop_transaction_ilocked()
1839 t->from = NULL; in binder_pop_transaction_ilocked()
1843 * binder_thread_dec_tmpref() - decrement thread->tmp_ref
1848 * extract t->from from a binder_transaction and keep the thread
1849 * indicated by t->from from being freed. When done with that
1858 * it cannot reach zero or thread->is_dead is false in binder_thread_dec_tmpref()
1860 binder_inner_proc_lock(thread->proc); in binder_thread_dec_tmpref()
1861 atomic_dec(&thread->tmp_ref); in binder_thread_dec_tmpref()
1862 if (thread->is_dead && !atomic_read(&thread->tmp_ref)) { in binder_thread_dec_tmpref()
1863 binder_inner_proc_unlock(thread->proc); in binder_thread_dec_tmpref()
1867 binder_inner_proc_unlock(thread->proc); in binder_thread_dec_tmpref()
1871 * binder_proc_dec_tmpref() - decrement proc->tmp_ref
1875 * handle a transaction. proc->tmp_ref is incremented when
1876 * creating a new transaction or the binder_proc is currently in-use
1880 * been released and not currenly in-use to process a transaction).
1885 proc->tmp_ref--; in binder_proc_dec_tmpref()
1886 if (proc->is_dead && RB_EMPTY_ROOT(&proc->threads) && in binder_proc_dec_tmpref()
1887 !proc->tmp_ref) { in binder_proc_dec_tmpref()
1896 * binder_get_txn_from() - safely extract the "from" thread in transaction
1897 * @t: binder transaction for t->from
1903 * Return: the value of t->from
1910 spin_lock(&t->lock); in binder_get_txn_from()
1911 from = t->from; in binder_get_txn_from()
1913 atomic_inc(&from->tmp_ref); in binder_get_txn_from()
1914 spin_unlock(&t->lock); in binder_get_txn_from()
1919 * binder_get_txn_from_and_acq_inner() - get t->from and acquire inner lock
1920 * @t: binder transaction for t->from
1922 * Same as binder_get_txn_from() except it also acquires the proc->inner_lock
1927 * Return: the value of t->from
1931 __acquires(&t->from->proc->inner_lock) in binder_get_txn_from_and_acq_inner()
1937 __acquire(&from->proc->inner_lock); in binder_get_txn_from_and_acq_inner()
1940 binder_inner_proc_lock(from->proc); in binder_get_txn_from_and_acq_inner()
1941 if (t->from) { in binder_get_txn_from_and_acq_inner()
1942 BUG_ON(from != t->from); in binder_get_txn_from_and_acq_inner()
1945 binder_inner_proc_unlock(from->proc); in binder_get_txn_from_and_acq_inner()
1946 __acquire(&from->proc->inner_lock); in binder_get_txn_from_and_acq_inner()
1952 * binder_free_txn_fixups() - free unprocessed fd fixups
1953 * @t: binder transaction for t->from
1959 * processed -- in that case, the list will be empty.
1965 list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { in binder_free_txn_fixups()
1966 fput(fixup->file); in binder_free_txn_fixups()
1967 list_del(&fixup->fixup_entry); in binder_free_txn_fixups()
1974 struct binder_proc *target_proc = t->to_proc; in binder_free_transaction()
1978 if (t->buffer) in binder_free_transaction()
1979 t->buffer->transaction = NULL; in binder_free_transaction()
1984 * t->buffer->transaction has already been cleared. in binder_free_transaction()
1997 BUG_ON(t->flags & TF_ONE_WAY); in binder_send_failed_reply()
2003 t->debug_id, in binder_send_failed_reply()
2004 target_thread->proc->pid, in binder_send_failed_reply()
2005 target_thread->pid); in binder_send_failed_reply()
2008 if (target_thread->reply_error.cmd == BR_OK) { in binder_send_failed_reply()
2009 target_thread->reply_error.cmd = error_code; in binder_send_failed_reply()
2012 &target_thread->reply_error.work); in binder_send_failed_reply()
2013 wake_up_interruptible(&target_thread->wait); in binder_send_failed_reply()
2022 target_thread->reply_error.cmd); in binder_send_failed_reply()
2024 binder_inner_proc_unlock(target_thread->proc); in binder_send_failed_reply()
2029 __release(&target_thread->proc->inner_lock); in binder_send_failed_reply()
2030 next = t->from_parent; in binder_send_failed_reply()
2034 t->debug_id); in binder_send_failed_reply()
2044 "reply failed, no target thread -- retry %d\n", in binder_send_failed_reply()
2045 t->debug_id); in binder_send_failed_reply()
2050 * binder_cleanup_transaction() - cleans up undelivered transaction
2059 if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) { in binder_cleanup_transaction()
2064 t->debug_id, reason); in binder_cleanup_transaction()
2070 * binder_get_object() - gets object and checks for valid metadata
2095 read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); in binder_get_object()
2096 if (offset > buffer->data_size || read_size < sizeof(*hdr) || in binder_get_object()
2104 if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, in binder_get_object()
2110 hdr = &object->hdr; in binder_get_object()
2111 switch (hdr->type) { in binder_get_object()
2130 if (offset <= buffer->data_size - object_size && in binder_get_object()
2131 buffer->data_size >= object_size) in binder_get_object()
2138 * binder_validate_ptr() - validates binder_buffer_object in a binder_buffer.
2156 * If @object_offsetp is non-NULL, then the offset within
2176 if (binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, in binder_validate_ptr()
2181 if (!object_size || object->hdr.type != BINDER_TYPE_PTR) in binder_validate_ptr()
2186 return &object->bbo; in binder_validate_ptr()
2190 * binder_validate_fixup() - validates pointer/fd fixups happen in order.
2256 if ((last_bbo->flags & BINDER_BUFFER_FLAG_HAS_PARENT) == 0) in binder_validate_fixup()
2258 last_min_offset = last_bbo->parent_offset + sizeof(uintptr_t); in binder_validate_fixup()
2260 sizeof(binder_size_t) * last_bbo->parent; in binder_validate_fixup()
2261 if (binder_alloc_copy_from_buffer(&proc->alloc, in binder_validate_fixup()
2271 * struct binder_task_work_cb - for deferred close
2285 * binder_do_fd_close() - close list of file descriptors
2302 fput(twcb->file); in binder_do_fd_close()
2307 * binder_deferred_fd_close() - schedule a close for the given file-descriptor
2308 * @fd: file-descriptor to close
2311 * a file-descriptor to be closed after returning from binder_ioctl().
2320 init_task_work(&twcb->twork, binder_do_fd_close); in binder_deferred_fd_close()
2321 close_fd_get_file(fd, &twcb->file); in binder_deferred_fd_close()
2322 if (twcb->file) { in binder_deferred_fd_close()
2323 filp_close(twcb->file, current->files); in binder_deferred_fd_close()
2324 task_work_add(current, &twcb->twork, TWA_RESUME); in binder_deferred_fd_close()
2336 int debug_id = buffer->debug_id; in binder_transaction_buffer_release()
2340 "%d buffer release %d, size %zd-%zd, failed at %llx\n", in binder_transaction_buffer_release()
2341 proc->pid, buffer->debug_id, in binder_transaction_buffer_release()
2342 buffer->data_size, buffer->offsets_size, in binder_transaction_buffer_release()
2345 if (buffer->target_node) in binder_transaction_buffer_release()
2346 binder_dec_node(buffer->target_node, 1, 0); in binder_transaction_buffer_release()
2348 off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); in binder_transaction_buffer_release()
2357 if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, in binder_transaction_buffer_release()
2364 debug_id, (u64)object_offset, buffer->data_size); in binder_transaction_buffer_release()
2368 switch (hdr->type) { in binder_transaction_buffer_release()
2375 node = binder_get_node(proc, fp->binder); in binder_transaction_buffer_release()
2378 debug_id, (u64)fp->binder); in binder_transaction_buffer_release()
2383 node->debug_id, (u64)node->ptr); in binder_transaction_buffer_release()
2384 binder_dec_node(node, hdr->type == BINDER_TYPE_BINDER, in binder_transaction_buffer_release()
2395 ret = binder_dec_ref_for_handle(proc, fp->handle, in binder_transaction_buffer_release()
2396 hdr->type == BINDER_TYPE_HANDLE, &rdata); in binder_transaction_buffer_release()
2400 debug_id, fp->handle, ret); in binder_transaction_buffer_release()
2410 * No need to close the file here since user-space in binder_transaction_buffer_release()
2442 num_valid = (buffer_offset - off_start_offset) / in binder_transaction_buffer_release()
2446 fda->parent, in binder_transaction_buffer_release()
2455 fd_buf_size = sizeof(u32) * fda->num_fds; in binder_transaction_buffer_release()
2456 if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { in binder_transaction_buffer_release()
2458 debug_id, (u64)fda->num_fds); in binder_transaction_buffer_release()
2461 if (fd_buf_size > parent->length || in binder_transaction_buffer_release()
2462 fda->parent_offset > parent->length - fd_buf_size) { in binder_transaction_buffer_release()
2465 debug_id, (u64)fda->num_fds); in binder_transaction_buffer_release()
2470 * to user-space and the @buffer element is the user in binder_transaction_buffer_release()
2476 (parent->buffer - (uintptr_t)buffer->user_data) + in binder_transaction_buffer_release()
2477 fda->parent_offset; in binder_transaction_buffer_release()
2478 for (fd_index = 0; fd_index < fda->num_fds; in binder_transaction_buffer_release()
2486 &proc->alloc, &fd, buffer, in binder_transaction_buffer_release()
2497 thread->looper_need_return = true; in binder_transaction_buffer_release()
2503 debug_id, hdr->type); in binder_transaction_buffer_release()
2517 off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); in binder_release_entire_buffer()
2518 off_end_offset += buffer->offsets_size; in binder_release_entire_buffer()
2529 struct binder_proc *proc = thread->proc; in binder_translate_binder()
2530 struct binder_proc *target_proc = t->to_proc; in binder_translate_binder()
2534 node = binder_get_node(proc, fp->binder); in binder_translate_binder()
2538 return -ENOMEM; in binder_translate_binder()
2540 if (fp->cookie != node->cookie) { in binder_translate_binder()
2542 proc->pid, thread->pid, (u64)fp->binder, in binder_translate_binder()
2543 node->debug_id, (u64)fp->cookie, in binder_translate_binder()
2544 (u64)node->cookie); in binder_translate_binder()
2545 ret = -EINVAL; in binder_translate_binder()
2548 if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { in binder_translate_binder()
2549 ret = -EPERM; in binder_translate_binder()
2554 fp->hdr.type == BINDER_TYPE_BINDER, in binder_translate_binder()
2555 &thread->todo, &rdata); in binder_translate_binder()
2559 if (fp->hdr.type == BINDER_TYPE_BINDER) in binder_translate_binder()
2560 fp->hdr.type = BINDER_TYPE_HANDLE; in binder_translate_binder()
2562 fp->hdr.type = BINDER_TYPE_WEAK_HANDLE; in binder_translate_binder()
2563 fp->binder = 0; in binder_translate_binder()
2564 fp->handle = rdata.desc; in binder_translate_binder()
2565 fp->cookie = 0; in binder_translate_binder()
2569 " node %d u%016llx -> ref %d desc %d\n", in binder_translate_binder()
2570 node->debug_id, (u64)node->ptr, in binder_translate_binder()
2581 struct binder_proc *proc = thread->proc; in binder_translate_handle()
2582 struct binder_proc *target_proc = t->to_proc; in binder_translate_handle()
2587 node = binder_get_node_from_ref(proc, fp->handle, in binder_translate_handle()
2588 fp->hdr.type == BINDER_TYPE_HANDLE, &src_rdata); in binder_translate_handle()
2591 proc->pid, thread->pid, fp->handle); in binder_translate_handle()
2592 return -EINVAL; in binder_translate_handle()
2594 if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { in binder_translate_handle()
2595 ret = -EPERM; in binder_translate_handle()
2600 if (node->proc == target_proc) { in binder_translate_handle()
2601 if (fp->hdr.type == BINDER_TYPE_HANDLE) in binder_translate_handle()
2602 fp->hdr.type = BINDER_TYPE_BINDER; in binder_translate_handle()
2604 fp->hdr.type = BINDER_TYPE_WEAK_BINDER; in binder_translate_handle()
2605 fp->binder = node->ptr; in binder_translate_handle()
2606 fp->cookie = node->cookie; in binder_translate_handle()
2607 if (node->proc) in binder_translate_handle()
2608 binder_inner_proc_lock(node->proc); in binder_translate_handle()
2610 __acquire(&node->proc->inner_lock); in binder_translate_handle()
2612 fp->hdr.type == BINDER_TYPE_BINDER, in binder_translate_handle()
2614 if (node->proc) in binder_translate_handle()
2615 binder_inner_proc_unlock(node->proc); in binder_translate_handle()
2617 __release(&node->proc->inner_lock); in binder_translate_handle()
2620 " ref %d desc %d -> node %d u%016llx\n", in binder_translate_handle()
2621 src_rdata.debug_id, src_rdata.desc, node->debug_id, in binder_translate_handle()
2622 (u64)node->ptr); in binder_translate_handle()
2629 fp->hdr.type == BINDER_TYPE_HANDLE, in binder_translate_handle()
2634 fp->binder = 0; in binder_translate_handle()
2635 fp->handle = dest_rdata.desc; in binder_translate_handle()
2636 fp->cookie = 0; in binder_translate_handle()
2640 " ref %d desc %d -> ref %d desc %d (node %d)\n", in binder_translate_handle()
2643 node->debug_id); in binder_translate_handle()
2655 struct binder_proc *proc = thread->proc; in binder_translate_fd()
2656 struct binder_proc *target_proc = t->to_proc; in binder_translate_fd()
2663 target_allows_fd = !!(in_reply_to->flags & TF_ACCEPT_FDS); in binder_translate_fd()
2665 target_allows_fd = t->buffer->target_node->accept_fds; in binder_translate_fd()
2668 proc->pid, thread->pid, in binder_translate_fd()
2671 ret = -EPERM; in binder_translate_fd()
2678 proc->pid, thread->pid, fd); in binder_translate_fd()
2679 ret = -EBADF; in binder_translate_fd()
2682 ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); in binder_translate_fd()
2684 ret = -EPERM; in binder_translate_fd()
2695 ret = -ENOMEM; in binder_translate_fd()
2698 fixup->file = file; in binder_translate_fd()
2699 fixup->offset = fd_offset; in binder_translate_fd()
2700 trace_binder_transaction_fd_send(t, fd, fixup->offset); in binder_translate_fd()
2701 list_add_tail(&fixup->fixup_entry, &t->fd_fixups); in binder_translate_fd()
2714 * struct binder_ptr_fixup - data to be fixed-up in target buffer
2734 * struct binder_sg_copy - scatter-gather data to be copied
2754 * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data
2757 * @sgc_head: list_head of scatter-gather copy list
2761 * and copying the scatter-gather data from the source process' user
2766 * Return: 0=success, else -errno
2783 while (bytes_copied < sgc->length) { in binder_do_deferred_txn_copies()
2785 size_t bytes_left = sgc->length - bytes_copied; in binder_do_deferred_txn_copies()
2786 size_t offset = sgc->offset + bytes_copied; in binder_do_deferred_txn_copies()
2791 copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset) in binder_do_deferred_txn_copies()
2797 sgc->sender_uaddr + bytes_copied, in binder_do_deferred_txn_copies()
2803 if (pf->skip_size) { in binder_do_deferred_txn_copies()
2810 bytes_copied += pf->skip_size; in binder_do_deferred_txn_copies()
2816 pf->offset, in binder_do_deferred_txn_copies()
2817 &pf->fixup_data, in binder_do_deferred_txn_copies()
2818 sizeof(pf->fixup_data)); in binder_do_deferred_txn_copies()
2819 bytes_copied += sizeof(pf->fixup_data); in binder_do_deferred_txn_copies()
2821 list_del(&pf->node); in binder_do_deferred_txn_copies()
2827 list_del(&sgc->node); in binder_do_deferred_txn_copies()
2831 BUG_ON(pf->skip_size == 0); in binder_do_deferred_txn_copies()
2832 list_del(&pf->node); in binder_do_deferred_txn_copies()
2837 return ret > 0 ? -EINVAL : ret; in binder_do_deferred_txn_copies()
2841 * binder_cleanup_deferred_txn_lists() - free specified lists
2842 * @sgc_head: list_head of scatter-gather copy list
2855 list_del(&sgc->node); in binder_cleanup_deferred_txn_lists()
2859 list_del(&pf->node); in binder_cleanup_deferred_txn_lists()
2865 * binder_defer_copy() - queue a scatter-gather buffer for copy
2866 * @sgc_head: list_head of scatter-gather copy list
2871 * Specify a scatter-gather block to be copied. The actual copy must
2873 * Then the copy and fixups are done together so un-translated values
2880 * Return: 0=success, else -errno
2888 return -ENOMEM; in binder_defer_copy()
2890 bc->offset = offset; in binder_defer_copy()
2891 bc->sender_uaddr = sender_uaddr; in binder_defer_copy()
2892 bc->length = length; in binder_defer_copy()
2893 INIT_LIST_HEAD(&bc->node); in binder_defer_copy()
2896 * We are guaranteed that the deferred copies are in-order in binder_defer_copy()
2899 list_add_tail(&bc->node, sgc_head); in binder_defer_copy()
2905 * binder_add_fixup() - queue a fixup to be applied to sg copy
2912 * the scatter-gather buffers, the fixup will be copied instead of
2919 * exceptions. Since out-of-order inserts are relatively uncommon,
2923 * Return: 0=success, else -errno
2932 return -ENOMEM; in binder_add_fixup()
2934 pf->offset = offset; in binder_add_fixup()
2935 pf->fixup_data = fixup; in binder_add_fixup()
2936 pf->skip_size = skip_size; in binder_add_fixup()
2937 INIT_LIST_HEAD(&pf->node); in binder_add_fixup()
2939 /* Fixups are *mostly* added in-order, but there are some in binder_add_fixup()
2943 if (tmppf->offset < pf->offset) { in binder_add_fixup()
2944 list_add(&pf->node, &tmppf->node); in binder_add_fixup()
2952 list_add(&pf->node, pf_head); in binder_add_fixup()
2968 struct binder_proc *proc = thread->proc; in binder_translate_fd_array()
2971 if (fda->num_fds == 0) in binder_translate_fd_array()
2974 fd_buf_size = sizeof(u32) * fda->num_fds; in binder_translate_fd_array()
2975 if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { in binder_translate_fd_array()
2977 proc->pid, thread->pid, (u64)fda->num_fds); in binder_translate_fd_array()
2978 return -EINVAL; in binder_translate_fd_array()
2980 if (fd_buf_size > parent->length || in binder_translate_fd_array()
2981 fda->parent_offset > parent->length - fd_buf_size) { in binder_translate_fd_array()
2984 proc->pid, thread->pid, (u64)fda->num_fds); in binder_translate_fd_array()
2985 return -EINVAL; in binder_translate_fd_array()
2989 * to user-space and the @buffer element is the user in binder_translate_fd_array()
2994 fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) + in binder_translate_fd_array()
2995 fda->parent_offset; in binder_translate_fd_array()
2996 sender_ufda_base = (void __user *)(uintptr_t)sender_uparent->buffer + in binder_translate_fd_array()
2997 fda->parent_offset; in binder_translate_fd_array()
3002 proc->pid, thread->pid); in binder_translate_fd_array()
3003 return -EINVAL; in binder_translate_fd_array()
3005 ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32)); in binder_translate_fd_array()
3009 for (fdi = 0; fdi < fda->num_fds; fdi++) { in binder_translate_fd_array()
3019 return ret > 0 ? -EINVAL : ret; in binder_translate_fd_array()
3034 struct binder_buffer *b = t->buffer; in binder_fixup_parent()
3035 struct binder_proc *proc = thread->proc; in binder_fixup_parent()
3036 struct binder_proc *target_proc = t->to_proc; in binder_fixup_parent()
3041 if (!(bp->flags & BINDER_BUFFER_FLAG_HAS_PARENT)) in binder_fixup_parent()
3044 parent = binder_validate_ptr(target_proc, b, &object, bp->parent, in binder_fixup_parent()
3049 proc->pid, thread->pid); in binder_fixup_parent()
3050 return -EINVAL; in binder_fixup_parent()
3054 parent_offset, bp->parent_offset, in binder_fixup_parent()
3057 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n", in binder_fixup_parent()
3058 proc->pid, thread->pid); in binder_fixup_parent()
3059 return -EINVAL; in binder_fixup_parent()
3062 if (parent->length < sizeof(binder_uintptr_t) || in binder_fixup_parent()
3063 bp->parent_offset > parent->length - sizeof(binder_uintptr_t)) { in binder_fixup_parent()
3066 proc->pid, thread->pid); in binder_fixup_parent()
3067 return -EINVAL; in binder_fixup_parent()
3069 buffer_offset = bp->parent_offset + in binder_fixup_parent()
3070 (uintptr_t)parent->buffer - (uintptr_t)b->user_data; in binder_fixup_parent()
3071 return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0); in binder_fixup_parent()
3075 * binder_proc_transaction() - sends a transaction to a process and wakes it up
3095 struct binder_node *node = t->buffer->target_node; in binder_proc_transaction()
3096 bool oneway = !!(t->flags & TF_ONE_WAY); in binder_proc_transaction()
3103 if (node->has_async_transaction) in binder_proc_transaction()
3106 node->has_async_transaction = true; in binder_proc_transaction()
3111 if (proc->is_dead || (thread && thread->is_dead)) { in binder_proc_transaction()
3121 binder_enqueue_thread_work_ilocked(thread, &t->work); in binder_proc_transaction()
3123 binder_enqueue_work_ilocked(&t->work, &proc->todo); in binder_proc_transaction()
3125 binder_enqueue_work_ilocked(&t->work, &node->async_todo); in binder_proc_transaction()
3137 * binder_get_node_refs_for_txn() - Get required refs on node for txn
3139 * @proc: returns @node->proc if valid
3142 * User-space normally keeps the node alive when creating a transaction
3148 * Since user-space can cause the local strong ref to go away, we also take
3153 * Return: The target_node with refs taken or NULL if no @node->proc is NULL.
3154 * Also sets @proc if valid. If the @node->proc is NULL indicating that the
3165 if (node->proc) { in binder_get_node_refs_for_txn()
3169 node->proc->tmp_ref++; in binder_get_node_refs_for_txn()
3170 *procp = node->proc; in binder_get_node_refs_for_txn()
3202 struct binder_context *context = proc->context; in binder_transaction()
3209 (uintptr_t)tr->data.ptr.buffer; in binder_transaction()
3214 e->debug_id = t_debug_id; in binder_transaction()
3215 e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); in binder_transaction()
3216 e->from_proc = proc->pid; in binder_transaction()
3217 e->from_thread = thread->pid; in binder_transaction()
3218 e->target_handle = tr->target.handle; in binder_transaction()
3219 e->data_size = tr->data_size; in binder_transaction()
3220 e->offsets_size = tr->offsets_size; in binder_transaction()
3221 strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME); in binder_transaction()
3225 in_reply_to = thread->transaction_stack; in binder_transaction()
3229 proc->pid, thread->pid); in binder_transaction()
3231 return_error_param = -EPROTO; in binder_transaction()
3235 if (in_reply_to->to_thread != thread) { in binder_transaction()
3236 spin_lock(&in_reply_to->lock); in binder_transaction()
3238 proc->pid, thread->pid, in_reply_to->debug_id, in binder_transaction()
3239 in_reply_to->to_proc ? in binder_transaction()
3240 in_reply_to->to_proc->pid : 0, in binder_transaction()
3241 in_reply_to->to_thread ? in binder_transaction()
3242 in_reply_to->to_thread->pid : 0); in binder_transaction()
3243 spin_unlock(&in_reply_to->lock); in binder_transaction()
3246 return_error_param = -EPROTO; in binder_transaction()
3251 thread->transaction_stack = in_reply_to->to_parent; in binder_transaction()
3253 binder_set_nice(in_reply_to->saved_priority); in binder_transaction()
3257 __release(&target_thread->proc->inner_lock); in binder_transaction()
3262 if (target_thread->transaction_stack != in_reply_to) { in binder_transaction()
3264 proc->pid, thread->pid, in binder_transaction()
3265 target_thread->transaction_stack ? in binder_transaction()
3266 target_thread->transaction_stack->debug_id : 0, in binder_transaction()
3267 in_reply_to->debug_id); in binder_transaction()
3268 binder_inner_proc_unlock(target_thread->proc); in binder_transaction()
3270 return_error_param = -EPROTO; in binder_transaction()
3276 target_proc = target_thread->proc; in binder_transaction()
3277 target_proc->tmp_ref++; in binder_transaction()
3278 binder_inner_proc_unlock(target_thread->proc); in binder_transaction()
3280 if (tr->target.handle) { in binder_transaction()
3291 ref = binder_get_ref_olocked(proc, tr->target.handle, in binder_transaction()
3295 ref->node, &target_proc, in binder_transaction()
3299 proc->pid, thread->pid); in binder_transaction()
3304 mutex_lock(&context->context_mgr_node_lock); in binder_transaction()
3305 target_node = context->binder_context_mgr_node; in binder_transaction()
3312 mutex_unlock(&context->context_mgr_node_lock); in binder_transaction()
3313 if (target_node && target_proc->pid == proc->pid) { in binder_transaction()
3315 proc->pid, thread->pid); in binder_transaction()
3317 return_error_param = -EINVAL; in binder_transaction()
3326 return_error_param = -EINVAL; in binder_transaction()
3330 e->to_node = target_node->debug_id; in binder_transaction()
3333 return_error_param = -EINVAL; in binder_transaction()
3337 if (security_binder_transaction(proc->cred, in binder_transaction()
3338 target_proc->cred) < 0) { in binder_transaction()
3340 return_error_param = -EPERM; in binder_transaction()
3346 w = list_first_entry_or_null(&thread->todo, in binder_transaction()
3348 if (!(tr->flags & TF_ONE_WAY) && w && in binder_transaction()
3349 w->type == BINDER_WORK_TRANSACTION) { in binder_transaction()
3355 * thread from proc->waiting_threads to enqueue in binder_transaction()
3360 proc->pid, thread->pid); in binder_transaction()
3363 return_error_param = -EPROTO; in binder_transaction()
3368 if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { in binder_transaction()
3371 tmp = thread->transaction_stack; in binder_transaction()
3372 if (tmp->to_thread != thread) { in binder_transaction()
3373 spin_lock(&tmp->lock); in binder_transaction()
3375 proc->pid, thread->pid, tmp->debug_id, in binder_transaction()
3376 tmp->to_proc ? tmp->to_proc->pid : 0, in binder_transaction()
3377 tmp->to_thread ? in binder_transaction()
3378 tmp->to_thread->pid : 0); in binder_transaction()
3379 spin_unlock(&tmp->lock); in binder_transaction()
3382 return_error_param = -EPROTO; in binder_transaction()
3389 spin_lock(&tmp->lock); in binder_transaction()
3390 from = tmp->from; in binder_transaction()
3391 if (from && from->proc == target_proc) { in binder_transaction()
3392 atomic_inc(&from->tmp_ref); in binder_transaction()
3394 spin_unlock(&tmp->lock); in binder_transaction()
3397 spin_unlock(&tmp->lock); in binder_transaction()
3398 tmp = tmp->from_parent; in binder_transaction()
3404 e->to_thread = target_thread->pid; in binder_transaction()
3405 e->to_proc = target_proc->pid; in binder_transaction()
3411 return_error_param = -ENOMEM; in binder_transaction()
3415 INIT_LIST_HEAD(&t->fd_fixups); in binder_transaction()
3417 spin_lock_init(&t->lock); in binder_transaction()
3422 return_error_param = -ENOMEM; in binder_transaction()
3428 t->debug_id = t_debug_id; in binder_transaction()
3432 "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld\n", in binder_transaction()
3433 proc->pid, thread->pid, t->debug_id, in binder_transaction()
3434 target_proc->pid, target_thread->pid, in binder_transaction()
3435 (u64)tr->data.ptr.buffer, in binder_transaction()
3436 (u64)tr->data.ptr.offsets, in binder_transaction()
3437 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3441 "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld\n", in binder_transaction()
3442 proc->pid, thread->pid, t->debug_id, in binder_transaction()
3443 target_proc->pid, target_node->debug_id, in binder_transaction()
3444 (u64)tr->data.ptr.buffer, in binder_transaction()
3445 (u64)tr->data.ptr.offsets, in binder_transaction()
3446 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3449 if (!reply && !(tr->flags & TF_ONE_WAY)) { in binder_transaction()
3450 t->from = thread; in binder_transaction()
3452 t->async_from_pid = -1; in binder_transaction()
3453 t->async_from_tid = -1; in binder_transaction()
3456 t->from = NULL; in binder_transaction()
3458 t->async_from_pid = thread->proc->pid; in binder_transaction()
3459 t->async_from_tid = thread->pid; in binder_transaction()
3462 t->sender_euid = task_euid(proc->tsk); in binder_transaction()
3464 t->sender_tokenid = current->token; in binder_transaction()
3465 t->first_tokenid = current->ftoken; in binder_transaction()
3467 t->to_proc = target_proc; in binder_transaction()
3468 t->to_thread = target_thread; in binder_transaction()
3469 t->code = tr->code; in binder_transaction()
3470 t->flags = tr->flags; in binder_transaction()
3471 t->priority = task_nice(current); in binder_transaction()
3473 if (target_node && target_node->txn_security_ctx) { in binder_transaction()
3477 security_cred_getsecid(proc->cred, &secid); in binder_transaction()
3498 t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size, in binder_transaction()
3499 tr->offsets_size, extra_buffers_size, in binder_transaction()
3500 !reply && (t->flags & TF_ONE_WAY), current->tgid); in binder_transaction()
3501 if (IS_ERR(t->buffer)) { in binder_transaction()
3503 * -ESRCH indicates VMA cleared. The target is dying. in binder_transaction()
3505 return_error_param = PTR_ERR(t->buffer); in binder_transaction()
3506 return_error = return_error_param == -ESRCH ? in binder_transaction()
3509 t->buffer = NULL; in binder_transaction()
3514 size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) + in binder_transaction()
3515 ALIGN(tr->offsets_size, sizeof(void *)) + in binder_transaction()
3516 ALIGN(extra_buffers_size, sizeof(void *)) - in binder_transaction()
3519 t->security_ctx = (uintptr_t)t->buffer->user_data + buf_offset; in binder_transaction()
3520 err = binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3521 t->buffer, buf_offset, in binder_transaction()
3524 t->security_ctx = 0; in binder_transaction()
3530 t->buffer->debug_id = t->debug_id; in binder_transaction()
3531 t->buffer->transaction = t; in binder_transaction()
3532 t->buffer->target_node = target_node; in binder_transaction()
3533 t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); in binder_transaction()
3534 trace_binder_transaction_alloc_buf(t->buffer); in binder_transaction()
3537 &target_proc->alloc, in binder_transaction()
3538 t->buffer, in binder_transaction()
3539 ALIGN(tr->data_size, sizeof(void *)), in binder_transaction()
3541 (uintptr_t)tr->data.ptr.offsets, in binder_transaction()
3542 tr->offsets_size)) { in binder_transaction()
3544 proc->pid, thread->pid); in binder_transaction()
3546 return_error_param = -EFAULT; in binder_transaction()
3550 if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) { in binder_transaction()
3552 proc->pid, thread->pid, (u64)tr->offsets_size); in binder_transaction()
3554 return_error_param = -EINVAL; in binder_transaction()
3560 proc->pid, thread->pid, in binder_transaction()
3563 return_error_param = -EINVAL; in binder_transaction()
3567 off_start_offset = ALIGN(tr->data_size, sizeof(void *)); in binder_transaction()
3569 off_end_offset = off_start_offset + tr->offsets_size; in binder_transaction()
3571 sg_buf_end_offset = sg_buf_offset + extra_buffers_size - in binder_transaction()
3582 if (binder_alloc_copy_from_buffer(&target_proc->alloc, in binder_transaction()
3584 t->buffer, in binder_transaction()
3588 return_error_param = -EINVAL; in binder_transaction()
3597 copy_size = object_offset - user_offset; in binder_transaction()
3599 object_offset > tr->data_size || in binder_transaction()
3601 &target_proc->alloc, in binder_transaction()
3602 t->buffer, user_offset, in binder_transaction()
3606 proc->pid, thread->pid); in binder_transaction()
3608 return_error_param = -EFAULT; in binder_transaction()
3613 t->buffer, object_offset, &object); in binder_transaction()
3616 proc->pid, thread->pid, in binder_transaction()
3619 (u64)t->buffer->data_size); in binder_transaction()
3621 return_error_param = -EINVAL; in binder_transaction()
3633 switch (hdr->type) { in binder_transaction()
3642 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3643 t->buffer, in binder_transaction()
3659 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3660 t->buffer, in binder_transaction()
3673 (uintptr_t)&fp->fd - (uintptr_t)fp; in binder_transaction()
3674 int ret = binder_translate_fd(fp->fd, fd_offset, t, in binder_transaction()
3677 fp->pad_binder = 0; in binder_transaction()
3679 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3680 t->buffer, in binder_transaction()
3696 size_t num_valid = (buffer_offset - off_start_offset) / in binder_transaction()
3699 binder_validate_ptr(target_proc, t->buffer, in binder_transaction()
3700 &ptr_object, fda->parent, in binder_transaction()
3706 proc->pid, thread->pid); in binder_transaction()
3708 return_error_param = -EINVAL; in binder_transaction()
3712 if (!binder_validate_fixup(target_proc, t->buffer, in binder_transaction()
3715 fda->parent_offset, in binder_transaction()
3718 binder_user_error("%d:%d got transaction with out-of-order buffer fixup\n", in binder_transaction()
3719 proc->pid, thread->pid); in binder_transaction()
3721 return_error_param = -EINVAL; in binder_transaction()
3730 binder_get_object(proc, user_buffer, t->buffer, in binder_transaction()
3734 proc->pid, thread->pid, in binder_transaction()
3738 return_error_param = -EINVAL; in binder_transaction()
3747 ret = binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3748 t->buffer, in binder_transaction()
3753 return_error_param = ret > 0 ? -EINVAL : ret; in binder_transaction()
3759 fda->parent_offset + sizeof(u32) * fda->num_fds; in binder_transaction()
3764 size_t buf_left = sg_buf_end_offset - sg_buf_offset; in binder_transaction()
3767 if (bp->length > buf_left) { in binder_transaction()
3769 proc->pid, thread->pid); in binder_transaction()
3771 return_error_param = -EINVAL; in binder_transaction()
3776 (const void __user *)(uintptr_t)bp->buffer, in binder_transaction()
3777 bp->length); in binder_transaction()
3785 bp->buffer = (uintptr_t) in binder_transaction()
3786 t->buffer->user_data + sg_buf_offset; in binder_transaction()
3787 sg_buf_offset += ALIGN(bp->length, sizeof(u64)); in binder_transaction()
3789 num_valid = (buffer_offset - off_start_offset) / in binder_transaction()
3798 binder_alloc_copy_to_buffer(&target_proc->alloc, in binder_transaction()
3799 t->buffer, in binder_transaction()
3812 proc->pid, thread->pid, hdr->type); in binder_transaction()
3814 return_error_param = -EINVAL; in binder_transaction()
3821 &target_proc->alloc, in binder_transaction()
3822 t->buffer, user_offset, in binder_transaction()
3824 tr->data_size - user_offset)) { in binder_transaction()
3826 proc->pid, thread->pid); in binder_transaction()
3828 return_error_param = -EFAULT; in binder_transaction()
3833 ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer, in binder_transaction()
3837 proc->pid, thread->pid); in binder_transaction()
3843 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; in binder_transaction()
3844 t->work.type = BINDER_WORK_TRANSACTION; in binder_transaction()
3849 if (target_thread->is_dead) { in binder_transaction()
3853 BUG_ON(t->buffer->async_transaction != 0); in binder_transaction()
3855 t->timestamp = in_reply_to->timestamp; in binder_transaction()
3858 binder_enqueue_thread_work_ilocked(target_thread, &t->work); in binder_transaction()
3860 wake_up_interruptible_sync(&target_thread->wait); in binder_transaction()
3862 } else if (!(t->flags & TF_ONE_WAY)) { in binder_transaction()
3863 BUG_ON(t->buffer->async_transaction != 0); in binder_transaction()
3873 t->need_reply = 1; in binder_transaction()
3874 t->from_parent = thread->transaction_stack; in binder_transaction()
3875 thread->transaction_stack = t; in binder_transaction()
3877 t->timestamp = binder_clock(); in binder_transaction()
3888 BUG_ON(t->buffer->async_transaction != 1); in binder_transaction()
3891 t->timestamp = binder_clock(); in binder_transaction()
3906 WRITE_ONCE(e->debug_id_done, t_debug_id); in binder_transaction()
3920 trace_binder_transaction_failed_buffer_release(t->buffer); in binder_transaction()
3921 binder_transaction_buffer_release(target_proc, NULL, t->buffer, in binder_transaction()
3926 t->buffer->transaction = NULL; in binder_transaction()
3927 binder_alloc_free_buf(&target_proc->alloc, t->buffer); in binder_transaction()
3954 "%d:%d transaction failed %d/%d, size %lld-%lld line %d\n", in binder_transaction()
3955 proc->pid, thread->pid, return_error, return_error_param, in binder_transaction()
3956 (u64)tr->data_size, (u64)tr->offsets_size, in binder_transaction()
3962 e->return_error = return_error; in binder_transaction()
3963 e->return_error_param = return_error_param; in binder_transaction()
3964 e->return_error_line = return_error_line; in binder_transaction()
3972 WRITE_ONCE(e->debug_id_done, t_debug_id); in binder_transaction()
3973 WRITE_ONCE(fe->debug_id_done, t_debug_id); in binder_transaction()
3976 BUG_ON(thread->return_error.cmd != BR_OK); in binder_transaction()
3978 thread->return_error.cmd = BR_TRANSACTION_COMPLETE; in binder_transaction()
3979 binder_enqueue_thread_work(thread, &thread->return_error.work); in binder_transaction()
3982 thread->return_error.cmd = return_error; in binder_transaction()
3983 binder_enqueue_thread_work(thread, &thread->return_error.work); in binder_transaction()
3988 * binder_free_buf() - free the specified buffer
3993 * If buffer for an async transaction, enqueue the next async
4004 if (buffer->transaction) { in binder_free_buf()
4005 buffer->transaction->buffer = NULL; in binder_free_buf()
4006 buffer->transaction = NULL; in binder_free_buf()
4009 if (buffer->async_transaction && buffer->target_node) { in binder_free_buf()
4013 buf_node = buffer->target_node; in binder_free_buf()
4015 BUG_ON(!buf_node->has_async_transaction); in binder_free_buf()
4016 BUG_ON(buf_node->proc != proc); in binder_free_buf()
4018 &buf_node->async_todo); in binder_free_buf()
4020 buf_node->has_async_transaction = false; in binder_free_buf()
4023 w, &proc->todo); in binder_free_buf()
4030 binder_alloc_free_buf(&proc->alloc, buffer); in binder_free_buf()
4039 struct binder_context *context = proc->context; in binder_thread_write()
4044 while (ptr < end && thread->return_error.cmd == BR_OK) { in binder_thread_write()
4048 return -EFAULT; in binder_thread_write()
4053 atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]); in binder_thread_write()
4054 atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]); in binder_thread_write()
4068 return -EFAULT; in binder_thread_write()
4071 ret = -1; in binder_thread_write()
4074 mutex_lock(&context->context_mgr_node_lock); in binder_thread_write()
4075 ctx_mgr_node = context->binder_context_mgr_node; in binder_thread_write()
4077 if (ctx_mgr_node->proc == proc) { in binder_thread_write()
4079 proc->pid, thread->pid); in binder_thread_write()
4080 mutex_unlock(&context->context_mgr_node_lock); in binder_thread_write()
4081 return -EINVAL; in binder_thread_write()
4087 mutex_unlock(&context->context_mgr_node_lock); in binder_thread_write()
4095 proc->pid, thread->pid, in binder_thread_write()
4115 proc->pid, thread->pid, debug_string, in binder_thread_write()
4121 proc->pid, thread->pid, debug_string, in binder_thread_write()
4134 return -EFAULT; in binder_thread_write()
4137 return -EFAULT; in binder_thread_write()
4142 proc->pid, thread->pid, in binder_thread_write()
4149 if (cookie != node->cookie) { in binder_thread_write()
4151 proc->pid, thread->pid, in binder_thread_write()
4154 (u64)node_ptr, node->debug_id, in binder_thread_write()
4155 (u64)cookie, (u64)node->cookie); in binder_thread_write()
4161 if (node->pending_strong_ref == 0) { in binder_thread_write()
4163 proc->pid, thread->pid, in binder_thread_write()
4164 node->debug_id); in binder_thread_write()
4169 node->pending_strong_ref = 0; in binder_thread_write()
4171 if (node->pending_weak_ref == 0) { in binder_thread_write()
4173 proc->pid, thread->pid, in binder_thread_write()
4174 node->debug_id); in binder_thread_write()
4179 node->pending_weak_ref = 0; in binder_thread_write()
4186 proc->pid, thread->pid, in binder_thread_write()
4188 node->debug_id, node->local_strong_refs, in binder_thread_write()
4189 node->local_weak_refs, node->tmp_refs); in binder_thread_write()
4196 return -EINVAL; in binder_thread_write()
4199 return -EINVAL; in binder_thread_write()
4206 return -EFAULT; in binder_thread_write()
4209 buffer = binder_alloc_prepare_to_free(&proc->alloc, in binder_thread_write()
4212 if (PTR_ERR(buffer) == -EPERM) { in binder_thread_write()
4215 proc->pid, thread->pid, in binder_thread_write()
4220 proc->pid, thread->pid, in binder_thread_write()
4227 proc->pid, thread->pid, (u64)data_ptr, in binder_thread_write()
4228 buffer->debug_id, in binder_thread_write()
4229 buffer->transaction ? "active" : "finished"); in binder_thread_write()
4239 return -EFAULT; in binder_thread_write()
4250 return -EFAULT; in binder_thread_write()
4260 proc->pid, thread->pid); in binder_thread_write()
4262 if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { in binder_thread_write()
4263 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4265 proc->pid, thread->pid); in binder_thread_write()
4266 } else if (proc->requested_threads == 0) { in binder_thread_write()
4267 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4269 proc->pid, thread->pid); in binder_thread_write()
4271 proc->requested_threads--; in binder_thread_write()
4272 proc->requested_threads_started++; in binder_thread_write()
4274 thread->looper |= BINDER_LOOPER_STATE_REGISTERED; in binder_thread_write()
4280 proc->pid, thread->pid); in binder_thread_write()
4281 if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { in binder_thread_write()
4282 thread->looper |= BINDER_LOOPER_STATE_INVALID; in binder_thread_write()
4284 proc->pid, thread->pid); in binder_thread_write()
4286 thread->looper |= BINDER_LOOPER_STATE_ENTERED; in binder_thread_write()
4291 proc->pid, thread->pid); in binder_thread_write()
4292 thread->looper |= BINDER_LOOPER_STATE_EXITED; in binder_thread_write()
4303 return -EFAULT; in binder_thread_write()
4306 return -EFAULT; in binder_thread_write()
4315 WARN_ON(thread->return_error.cmd != in binder_thread_write()
4317 thread->return_error.cmd = BR_ERROR; in binder_thread_write()
4320 &thread->return_error.work); in binder_thread_write()
4324 proc->pid, thread->pid); in binder_thread_write()
4332 proc->pid, thread->pid, in binder_thread_write()
4344 proc->pid, thread->pid, in binder_thread_write()
4348 (u64)cookie, ref->data.debug_id, in binder_thread_write()
4349 ref->data.desc, ref->data.strong, in binder_thread_write()
4350 ref->data.weak, ref->node->debug_id); in binder_thread_write()
4352 binder_node_lock(ref->node); in binder_thread_write()
4354 if (ref->death) { in binder_thread_write()
4356 proc->pid, thread->pid); in binder_thread_write()
4357 binder_node_unlock(ref->node); in binder_thread_write()
4363 INIT_LIST_HEAD(&death->work.entry); in binder_thread_write()
4364 death->cookie = cookie; in binder_thread_write()
4365 ref->death = death; in binder_thread_write()
4366 if (ref->node->proc == NULL) { in binder_thread_write()
4367 ref->death->work.type = BINDER_WORK_DEAD_BINDER; in binder_thread_write()
4371 &ref->death->work, &proc->todo); in binder_thread_write()
4376 if (ref->death == NULL) { in binder_thread_write()
4378 proc->pid, thread->pid); in binder_thread_write()
4379 binder_node_unlock(ref->node); in binder_thread_write()
4383 death = ref->death; in binder_thread_write()
4384 if (death->cookie != cookie) { in binder_thread_write()
4386 proc->pid, thread->pid, in binder_thread_write()
4387 (u64)death->cookie, in binder_thread_write()
4389 binder_node_unlock(ref->node); in binder_thread_write()
4393 ref->death = NULL; in binder_thread_write()
4395 if (list_empty(&death->work.entry)) { in binder_thread_write()
4396 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; in binder_thread_write()
4397 if (thread->looper & in binder_thread_write()
4402 &death->work); in binder_thread_write()
4405 &death->work, in binder_thread_write()
4406 &proc->todo); in binder_thread_write()
4411 BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); in binder_thread_write()
4412 death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; in binder_thread_write()
4416 binder_node_unlock(ref->node); in binder_thread_write()
4425 return -EFAULT; in binder_thread_write()
4429 list_for_each_entry(w, &proc->delivered_death, in binder_thread_write()
4436 if (tmp_death->cookie == cookie) { in binder_thread_write()
4443 proc->pid, thread->pid, (u64)cookie, in binder_thread_write()
4447 proc->pid, thread->pid, (u64)cookie); in binder_thread_write()
4451 binder_dequeue_work_ilocked(&death->work); in binder_thread_write()
4452 if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { in binder_thread_write()
4453 death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; in binder_thread_write()
4454 if (thread->looper & in binder_thread_write()
4458 thread, &death->work); in binder_thread_write()
4461 &death->work, in binder_thread_write()
4462 &proc->todo); in binder_thread_write()
4471 proc->pid, thread->pid, cmd); in binder_thread_write()
4472 return -EINVAL; in binder_thread_write()
4474 *consumed = ptr - buffer; in binder_thread_write()
4485 atomic_inc(&proc->stats.br[_IOC_NR(cmd)]); in binder_stat_br()
4486 atomic_inc(&thread->stats.br[_IOC_NR(cmd)]); in binder_stat_br()
4501 return -EFAULT; in binder_put_node_cmd()
4505 return -EFAULT; in binder_put_node_cmd()
4509 return -EFAULT; in binder_put_node_cmd()
4514 proc->pid, thread->pid, cmd_name, node_debug_id, in binder_put_node_cmd()
4525 struct binder_proc *proc = thread->proc; in binder_wait_for_work()
4531 prepare_to_wait(&thread->wait, &wait, TASK_INTERRUPTIBLE); in binder_wait_for_work()
4535 list_add(&thread->waiting_thread_node, in binder_wait_for_work()
4536 &proc->waiting_threads); in binder_wait_for_work()
4540 list_del_init(&thread->waiting_thread_node); in binder_wait_for_work()
4542 ret = -ERESTARTSYS; in binder_wait_for_work()
4546 finish_wait(&thread->wait, &wait); in binder_wait_for_work()
4554 * binder_apply_fd_fixups() - finish fd translation
4555 * @proc: binder_proc associated @t->buffer
4573 list_for_each_entry(fixup, &t->fd_fixups, fixup_entry) { in binder_apply_fd_fixups()
4579 t->debug_id, fd); in binder_apply_fd_fixups()
4580 ret = -ENOMEM; in binder_apply_fd_fixups()
4585 t->debug_id, fd); in binder_apply_fd_fixups()
4586 trace_binder_transaction_fd_recv(t, fd, fixup->offset); in binder_apply_fd_fixups()
4587 fd_install(fd, fixup->file); in binder_apply_fd_fixups()
4588 fixup->file = NULL; in binder_apply_fd_fixups()
4589 if (binder_alloc_copy_to_buffer(&proc->alloc, t->buffer, in binder_apply_fd_fixups()
4590 fixup->offset, &fd, in binder_apply_fd_fixups()
4592 ret = -EINVAL; in binder_apply_fd_fixups()
4596 list_for_each_entry_safe(fixup, tmp, &t->fd_fixups, fixup_entry) { in binder_apply_fd_fixups()
4597 if (fixup->file) { in binder_apply_fd_fixups()
4598 fput(fixup->file); in binder_apply_fd_fixups()
4603 err = binder_alloc_copy_from_buffer(&proc->alloc, &fd, in binder_apply_fd_fixups()
4604 t->buffer, in binder_apply_fd_fixups()
4605 fixup->offset, in binder_apply_fd_fixups()
4611 list_del(&fixup->fixup_entry); in binder_apply_fd_fixups()
4632 return -EFAULT; in binder_thread_read()
4641 thread->looper |= BINDER_LOOPER_STATE_WAITING; in binder_thread_read()
4644 !!thread->transaction_stack, in binder_thread_read()
4645 !binder_worklist_empty(proc, &thread->todo)); in binder_thread_read()
4647 if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | in binder_thread_read()
4650 proc->pid, thread->pid, thread->looper); in binder_thread_read()
4654 binder_set_nice(proc->default_priority); in binder_thread_read()
4659 ret = -EAGAIN; in binder_thread_read()
4664 thread->looper &= ~BINDER_LOOPER_STATE_WAITING; in binder_thread_read()
4680 if (!binder_worklist_empty_ilocked(&thread->todo)) in binder_thread_read()
4681 list = &thread->todo; in binder_thread_read()
4682 else if (!binder_worklist_empty_ilocked(&proc->todo) && in binder_thread_read()
4684 list = &proc->todo; in binder_thread_read()
4689 if (ptr - buffer == 4 && !thread->looper_need_return) in binder_thread_read()
4694 if (end - ptr < sizeof(tr) + 4) { in binder_thread_read()
4699 if (binder_worklist_empty_ilocked(&thread->todo)) in binder_thread_read()
4700 thread->process_todo = false; in binder_thread_read()
4702 switch (w->type) { in binder_thread_read()
4711 WARN_ON(e->cmd == BR_OK); in binder_thread_read()
4713 if (put_user(e->cmd, (uint32_t __user *)ptr)) in binder_thread_read()
4714 return -EFAULT; in binder_thread_read()
4715 cmd = e->cmd; in binder_thread_read()
4716 e->cmd = BR_OK; in binder_thread_read()
4727 return -EFAULT; in binder_thread_read()
4733 proc->pid, thread->pid); in binder_thread_read()
4738 binder_uintptr_t node_ptr = node->ptr; in binder_thread_read()
4739 binder_uintptr_t node_cookie = node->cookie; in binder_thread_read()
4740 int node_debug_id = node->debug_id; in binder_thread_read()
4745 BUG_ON(proc != node->proc); in binder_thread_read()
4746 strong = node->internal_strong_refs || in binder_thread_read()
4747 node->local_strong_refs; in binder_thread_read()
4748 weak = !hlist_empty(&node->refs) || in binder_thread_read()
4749 node->local_weak_refs || in binder_thread_read()
4750 node->tmp_refs || strong; in binder_thread_read()
4751 has_strong_ref = node->has_strong_ref; in binder_thread_read()
4752 has_weak_ref = node->has_weak_ref; in binder_thread_read()
4755 node->has_weak_ref = 1; in binder_thread_read()
4756 node->pending_weak_ref = 1; in binder_thread_read()
4757 node->local_weak_refs++; in binder_thread_read()
4760 node->has_strong_ref = 1; in binder_thread_read()
4761 node->pending_strong_ref = 1; in binder_thread_read()
4762 node->local_strong_refs++; in binder_thread_read()
4765 node->has_strong_ref = 0; in binder_thread_read()
4767 node->has_weak_ref = 0; in binder_thread_read()
4771 proc->pid, thread->pid, in binder_thread_read()
4775 rb_erase(&node->rb_node, &proc->nodes); in binder_thread_read()
4815 proc->pid, thread->pid, in binder_thread_read()
4830 if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) in binder_thread_read()
4834 cookie = death->cookie; in binder_thread_read()
4838 proc->pid, thread->pid, in binder_thread_read()
4843 if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { in binder_thread_read()
4849 w, &proc->delivered_death); in binder_thread_read()
4853 return -EFAULT; in binder_thread_read()
4857 return -EFAULT; in binder_thread_read()
4866 proc->pid, thread->pid, w->type); in binder_thread_read()
4873 BUG_ON(t->buffer == NULL); in binder_thread_read()
4874 if (t->buffer->target_node) { in binder_thread_read()
4875 struct binder_node *target_node = t->buffer->target_node; in binder_thread_read()
4877 trd->target.ptr = target_node->ptr; in binder_thread_read()
4878 trd->cookie = target_node->cookie; in binder_thread_read()
4879 t->saved_priority = task_nice(current); in binder_thread_read()
4880 if (t->priority < target_node->min_priority && in binder_thread_read()
4881 !(t->flags & TF_ONE_WAY)) in binder_thread_read()
4882 binder_set_nice(t->priority); in binder_thread_read()
4883 else if (!(t->flags & TF_ONE_WAY) || in binder_thread_read()
4884 t->saved_priority > target_node->min_priority) in binder_thread_read()
4885 binder_set_nice(target_node->min_priority); in binder_thread_read()
4888 trd->target.ptr = 0; in binder_thread_read()
4889 trd->cookie = 0; in binder_thread_read()
4892 trd->code = t->code; in binder_thread_read()
4893 trd->flags = t->flags; in binder_thread_read()
4894 trd->sender_euid = from_kuid(current_user_ns(), t->sender_euid); in binder_thread_read()
4898 struct task_struct *sender = t_from->proc->tsk; in binder_thread_read()
4900 trd->sender_pid = in binder_thread_read()
4904 binder_inner_proc_lock(thread->proc); in binder_thread_read()
4905 thread->sender_pid_nr = task_tgid_nr(sender); in binder_thread_read()
4906 binder_inner_proc_unlock(thread->proc); in binder_thread_read()
4909 trd->sender_pid = 0; in binder_thread_read()
4911 binder_inner_proc_lock(thread->proc); in binder_thread_read()
4912 thread->sender_pid_nr = 0; in binder_thread_read()
4913 binder_inner_proc_unlock(thread->proc); in binder_thread_read()
4919 struct binder_buffer *buffer = t->buffer; in binder_thread_read()
4920 bool oneway = !!(t->flags & TF_ONE_WAY); in binder_thread_read()
4921 int tid = t->debug_id; in binder_thread_read()
4925 buffer->transaction = NULL; in binder_thread_read()
4931 proc->pid, thread->pid, in binder_thread_read()
4932 oneway ? "async " : in binder_thread_read()
4938 return -EFAULT; in binder_thread_read()
4945 trd->data_size = t->buffer->data_size; in binder_thread_read()
4946 trd->offsets_size = t->buffer->offsets_size; in binder_thread_read()
4947 trd->data.ptr.buffer = (uintptr_t)t->buffer->user_data; in binder_thread_read()
4948 trd->data.ptr.offsets = trd->data.ptr.buffer + in binder_thread_read()
4949 ALIGN(t->buffer->data_size, in binder_thread_read()
4952 tr.secctx = t->security_ctx; in binder_thread_read()
4953 if (t->security_ctx) { in binder_thread_read()
4964 return -EFAULT; in binder_thread_read()
4974 return -EFAULT; in binder_thread_read()
4981 "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n", in binder_thread_read()
4982 proc->pid, thread->pid, in binder_thread_read()
4986 t->debug_id, t_from ? t_from->proc->pid : 0, in binder_thread_read()
4987 t_from ? t_from->pid : 0, cmd, in binder_thread_read()
4988 t->buffer->data_size, t->buffer->offsets_size, in binder_thread_read()
4989 (u64)trd->data.ptr.buffer, in binder_thread_read()
4990 (u64)trd->data.ptr.offsets); in binder_thread_read()
4994 t->buffer->allow_user_free = 1; in binder_thread_read()
4996 binder_inner_proc_lock(thread->proc); in binder_thread_read()
4997 thread->tokens.sender_tokenid = t->sender_tokenid; in binder_thread_read()
4998 thread->tokens.first_tokenid = t->first_tokenid; in binder_thread_read()
4999 binder_inner_proc_unlock(thread->proc); in binder_thread_read()
5001 if (cmd != BR_REPLY && !(t->flags & TF_ONE_WAY)) { in binder_thread_read()
5002 binder_inner_proc_lock(thread->proc); in binder_thread_read()
5003 t->to_parent = thread->transaction_stack; in binder_thread_read()
5004 t->to_thread = thread; in binder_thread_read()
5005 thread->transaction_stack = t; in binder_thread_read()
5006 binder_inner_proc_unlock(thread->proc); in binder_thread_read()
5015 *consumed = ptr - buffer; in binder_thread_read()
5017 if (proc->requested_threads == 0 && in binder_thread_read()
5018 list_empty(&thread->proc->waiting_threads) && in binder_thread_read()
5019 proc->requested_threads_started < proc->max_threads && in binder_thread_read()
5020 (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | in binder_thread_read()
5021 BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ in binder_thread_read()
5023 proc->requested_threads++; in binder_thread_read()
5027 proc->pid, thread->pid); in binder_thread_read()
5029 return -EFAULT; in binder_thread_read()
5045 wtype = w ? w->type : 0; in binder_release_work()
5065 e->cmd); in binder_release_work()
5080 (u64)death->cookie); in binder_release_work()
5100 struct rb_node **p = &proc->threads.rb_node; in binder_get_thread_ilocked()
5106 if (current->pid < thread->pid) in binder_get_thread_ilocked()
5107 p = &(*p)->rb_left; in binder_get_thread_ilocked()
5108 else if (current->pid > thread->pid) in binder_get_thread_ilocked()
5109 p = &(*p)->rb_right; in binder_get_thread_ilocked()
5117 thread->proc = proc; in binder_get_thread_ilocked()
5118 thread->pid = current->pid; in binder_get_thread_ilocked()
5119 atomic_set(&thread->tmp_ref, 0); in binder_get_thread_ilocked()
5120 init_waitqueue_head(&thread->wait); in binder_get_thread_ilocked()
5121 INIT_LIST_HEAD(&thread->todo); in binder_get_thread_ilocked()
5122 rb_link_node(&thread->rb_node, parent, p); in binder_get_thread_ilocked()
5123 rb_insert_color(&thread->rb_node, &proc->threads); in binder_get_thread_ilocked()
5124 thread->looper_need_return = true; in binder_get_thread_ilocked()
5125 thread->return_error.work.type = BINDER_WORK_RETURN_ERROR; in binder_get_thread_ilocked()
5126 thread->return_error.cmd = BR_OK; in binder_get_thread_ilocked()
5127 thread->reply_error.work.type = BINDER_WORK_RETURN_ERROR; in binder_get_thread_ilocked()
5128 thread->reply_error.cmd = BR_OK; in binder_get_thread_ilocked()
5129 INIT_LIST_HEAD(&new_thread->waiting_thread_node); in binder_get_thread_ilocked()
5158 BUG_ON(!list_empty(&proc->todo)); in binder_free_proc()
5159 BUG_ON(!list_empty(&proc->delivered_death)); in binder_free_proc()
5160 device = container_of(proc->context, struct binder_device, context); in binder_free_proc()
5161 if (refcount_dec_and_test(&device->ref)) { in binder_free_proc()
5162 kfree(proc->context->name); in binder_free_proc()
5165 binder_alloc_deferred_release(&proc->alloc); in binder_free_proc()
5166 put_task_struct(proc->tsk); in binder_free_proc()
5167 put_cred(proc->cred); in binder_free_proc()
5174 BUG_ON(!list_empty(&thread->todo)); in binder_free_thread()
5176 binder_proc_dec_tmpref(thread->proc); in binder_free_thread()
5188 binder_inner_proc_lock(thread->proc); in binder_thread_release()
5191 * after we remove this thread from proc->threads. in binder_thread_release()
5195 proc->tmp_ref++; in binder_thread_release()
5200 atomic_inc(&thread->tmp_ref); in binder_thread_release()
5201 rb_erase(&thread->rb_node, &proc->threads); in binder_thread_release()
5202 t = thread->transaction_stack; in binder_thread_release()
5204 spin_lock(&t->lock); in binder_thread_release()
5205 if (t->to_thread == thread) in binder_thread_release()
5208 __acquire(&t->lock); in binder_thread_release()
5210 thread->is_dead = true; in binder_thread_release()
5217 proc->pid, thread->pid, in binder_thread_release()
5218 t->debug_id, in binder_thread_release()
5219 (t->to_thread == thread) ? "in" : "out"); in binder_thread_release()
5221 if (t->to_thread == thread) { in binder_thread_release()
5222 t->to_proc = NULL; in binder_thread_release()
5223 t->to_thread = NULL; in binder_thread_release()
5224 if (t->buffer) { in binder_thread_release()
5225 t->buffer->transaction = NULL; in binder_thread_release()
5226 t->buffer = NULL; in binder_thread_release()
5228 t = t->to_parent; in binder_thread_release()
5229 } else if (t->from == thread) { in binder_thread_release()
5230 t->from = NULL; in binder_thread_release()
5232 t->async_from_pid = -1; in binder_thread_release()
5233 t->async_from_tid = -1; in binder_thread_release()
5235 t = t->from_parent; in binder_thread_release()
5238 spin_unlock(&last_t->lock); in binder_thread_release()
5240 spin_lock(&t->lock); in binder_thread_release()
5242 __acquire(&t->lock); in binder_thread_release()
5245 __release(&t->lock); in binder_thread_release()
5251 if (thread->looper & BINDER_LOOPER_STATE_POLL) in binder_thread_release()
5252 wake_up_pollfree(&thread->wait); in binder_thread_release()
5254 binder_inner_proc_unlock(thread->proc); in binder_thread_release()
5263 if (thread->looper & BINDER_LOOPER_STATE_POLL) in binder_thread_release()
5268 binder_release_work(proc, &thread->todo); in binder_thread_release()
5276 struct binder_proc *proc = filp->private_data; in binder_poll()
5284 binder_inner_proc_lock(thread->proc); in binder_poll()
5285 thread->looper |= BINDER_LOOPER_STATE_POLL; in binder_poll()
5288 binder_inner_proc_unlock(thread->proc); in binder_poll()
5290 poll_wait(filp, &thread->wait, wait); in binder_poll()
5303 struct binder_proc *proc = filp->private_data; in binder_ioctl_write_read()
5309 ret = -EINVAL; in binder_ioctl_write_read()
5313 ret = -EFAULT; in binder_ioctl_write_read()
5318 proc->pid, thread->pid, in binder_ioctl_write_read()
5331 ret = -EFAULT; in binder_ioctl_write_read()
5339 filp->f_flags & O_NONBLOCK); in binder_ioctl_write_read()
5342 if (!binder_worklist_empty_ilocked(&proc->todo)) in binder_ioctl_write_read()
5347 ret = -EFAULT; in binder_ioctl_write_read()
5353 proc->pid, thread->pid, in binder_ioctl_write_read()
5357 ret = -EFAULT; in binder_ioctl_write_read()
5368 struct binder_proc *proc = filp->private_data; in binder_ioctl_set_ctx_mgr()
5369 struct binder_context *context = proc->context; in binder_ioctl_set_ctx_mgr()
5373 mutex_lock(&context->context_mgr_node_lock); in binder_ioctl_set_ctx_mgr()
5374 if (context->binder_context_mgr_node) { in binder_ioctl_set_ctx_mgr()
5376 ret = -EBUSY; in binder_ioctl_set_ctx_mgr()
5379 ret = security_binder_set_context_mgr(proc->cred); in binder_ioctl_set_ctx_mgr()
5382 if (uid_valid(context->binder_context_mgr_uid)) { in binder_ioctl_set_ctx_mgr()
5383 if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) { in binder_ioctl_set_ctx_mgr()
5387 context->binder_context_mgr_uid)); in binder_ioctl_set_ctx_mgr()
5388 ret = -EPERM; in binder_ioctl_set_ctx_mgr()
5392 context->binder_context_mgr_uid = curr_euid; in binder_ioctl_set_ctx_mgr()
5396 ret = -ENOMEM; in binder_ioctl_set_ctx_mgr()
5400 new_node->local_weak_refs++; in binder_ioctl_set_ctx_mgr()
5401 new_node->local_strong_refs++; in binder_ioctl_set_ctx_mgr()
5402 new_node->has_strong_ref = 1; in binder_ioctl_set_ctx_mgr()
5403 new_node->has_weak_ref = 1; in binder_ioctl_set_ctx_mgr()
5404 context->binder_context_mgr_node = new_node; in binder_ioctl_set_ctx_mgr()
5408 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_set_ctx_mgr()
5416 struct binder_context *context = proc->context; in binder_ioctl_get_node_info_for_ref()
5417 __u32 handle = info->handle; in binder_ioctl_get_node_info_for_ref()
5419 if (info->strong_count || info->weak_count || info->reserved1 || in binder_ioctl_get_node_info_for_ref()
5420 info->reserved2 || info->reserved3) { in binder_ioctl_get_node_info_for_ref()
5421 binder_user_error("%d BINDER_GET_NODE_INFO_FOR_REF: only handle may be non-zero.", in binder_ioctl_get_node_info_for_ref()
5422 proc->pid); in binder_ioctl_get_node_info_for_ref()
5423 return -EINVAL; in binder_ioctl_get_node_info_for_ref()
5427 mutex_lock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5428 if (!context->binder_context_mgr_node || in binder_ioctl_get_node_info_for_ref()
5429 context->binder_context_mgr_node->proc != proc) { in binder_ioctl_get_node_info_for_ref()
5430 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5431 return -EPERM; in binder_ioctl_get_node_info_for_ref()
5433 mutex_unlock(&context->context_mgr_node_lock); in binder_ioctl_get_node_info_for_ref()
5437 return -EINVAL; in binder_ioctl_get_node_info_for_ref()
5439 info->strong_count = node->local_strong_refs + in binder_ioctl_get_node_info_for_ref()
5440 node->internal_strong_refs; in binder_ioctl_get_node_info_for_ref()
5441 info->weak_count = node->local_weak_refs; in binder_ioctl_get_node_info_for_ref()
5452 binder_uintptr_t ptr = info->ptr; in binder_ioctl_get_node_debug_info()
5457 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in binder_ioctl_get_node_debug_info()
5460 if (node->ptr > ptr) { in binder_ioctl_get_node_debug_info()
5461 info->ptr = node->ptr; in binder_ioctl_get_node_debug_info()
5462 info->cookie = node->cookie; in binder_ioctl_get_node_debug_info()
5463 info->has_strong_ref = node->has_strong_ref; in binder_ioctl_get_node_debug_info()
5464 info->has_weak_ref = node->has_weak_ref; in binder_ioctl_get_node_debug_info()
5476 struct binder_proc *proc = filp->private_data; in binder_ioctl()
5482 proc->pid, current->pid, cmd, arg);*/ in binder_ioctl()
5484 binder_selftest_alloc(&proc->alloc); in binder_ioctl()
5494 ret = -ENOMEM; in binder_ioctl()
5509 ret = -EINVAL; in binder_ioctl()
5513 proc->max_threads = max_threads; in binder_ioctl()
5521 ret = -EINVAL; in binder_ioctl()
5536 proc->pid, thread->pid); in binder_ioctl()
5544 ret = -EINVAL; in binder_ioctl()
5548 &ver->protocol_version)) { in binder_ioctl()
5549 ret = -EINVAL; in binder_ioctl()
5558 ret = -EFAULT; in binder_ioctl()
5567 ret = -EFAULT; in binder_ioctl()
5577 ret = -EFAULT; in binder_ioctl()
5586 ret = -EFAULT; in binder_ioctl()
5595 ret = -EINVAL; in binder_ioctl()
5598 if (put_user(BINDER_CURRENT_FEATURE_SET, &features->feature_set)) { in binder_ioctl()
5599 ret = -EINVAL; in binder_ioctl()
5610 ret = -EINVAL; in binder_ioctl()
5614 token = thread->tokens.sender_tokenid; in binder_ioctl()
5615 ftoken = thread->tokens.first_tokenid; in binder_ioctl()
5617 if (put_user(token, &tokens->sender_tokenid)) { in binder_ioctl()
5618 ret = -EINVAL; in binder_ioctl()
5621 if (put_user(ftoken, &tokens->first_tokenid)) { in binder_ioctl()
5622 ret = -EINVAL; in binder_ioctl()
5634 ret = -EINVAL; in binder_ioctl()
5639 token = thread->tokens.sender_tokenid; in binder_ioctl()
5640 ftoken = thread->tokens.first_tokenid; in binder_ioctl()
5642 sender_pid_nr = thread->sender_pid_nr; in binder_ioctl()
5645 if (put_user(token, &sender->tokens.sender_tokenid)) { in binder_ioctl()
5646 ret = -EFAULT; in binder_ioctl()
5649 if (put_user(ftoken, &sender->tokens.first_tokenid)) { in binder_ioctl()
5650 ret = -EFAULT; in binder_ioctl()
5654 if (put_user(sender_pid_nr, &sender->sender_pid_nr)) { in binder_ioctl()
5655 ret = -EFAULT; in binder_ioctl()
5662 ret = -EINVAL; in binder_ioctl()
5668 thread->looper_need_return = false; in binder_ioctl()
5670 if (ret && ret != -ERESTARTSYS) in binder_ioctl()
5671 pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); in binder_ioctl()
5679 struct binder_proc *proc = vma->vm_private_data; in binder_vma_open()
5682 "%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_vma_open()
5683 proc->pid, vma->vm_start, vma->vm_end, in binder_vma_open()
5684 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_vma_open()
5685 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_vma_open()
5690 struct binder_proc *proc = vma->vm_private_data; in binder_vma_close()
5693 "%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_vma_close()
5694 proc->pid, vma->vm_start, vma->vm_end, in binder_vma_close()
5695 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_vma_close()
5696 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_vma_close()
5697 binder_alloc_vma_close(&proc->alloc); in binder_vma_close()
5713 struct binder_proc *proc = filp->private_data; in binder_mmap()
5715 if (proc->tsk != current->group_leader) in binder_mmap()
5716 return -EINVAL; in binder_mmap()
5719 "%s: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", in binder_mmap()
5720 __func__, proc->pid, vma->vm_start, vma->vm_end, in binder_mmap()
5721 (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, in binder_mmap()
5722 (unsigned long)pgprot_val(vma->vm_page_prot)); in binder_mmap()
5724 if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { in binder_mmap()
5725 pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, in binder_mmap()
5726 proc->pid, vma->vm_start, vma->vm_end, "bad vm_flags", -EPERM); in binder_mmap()
5727 return -EPERM; in binder_mmap()
5729 vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP; in binder_mmap()
5730 vma->vm_flags &= ~VM_MAYWRITE; in binder_mmap()
5732 vma->vm_ops = &binder_vm_ops; in binder_mmap()
5733 vma->vm_private_data = proc; in binder_mmap()
5735 return binder_alloc_mmap_handler(&proc->alloc, vma); in binder_mmap()
5747 current->group_leader->pid, current->pid); in binder_open()
5751 return -ENOMEM; in binder_open()
5752 spin_lock_init(&proc->inner_lock); in binder_open()
5753 spin_lock_init(&proc->outer_lock); in binder_open()
5754 get_task_struct(current->group_leader); in binder_open()
5755 proc->tsk = current->group_leader; in binder_open()
5756 proc->cred = get_cred(filp->f_cred); in binder_open()
5757 INIT_LIST_HEAD(&proc->todo); in binder_open()
5758 proc->default_priority = task_nice(current); in binder_open()
5761 binder_dev = nodp->i_private; in binder_open()
5762 info = nodp->i_sb->s_fs_info; in binder_open()
5763 binder_binderfs_dir_entry_proc = info->proc_log_dir; in binder_open()
5765 binder_dev = container_of(filp->private_data, in binder_open()
5768 refcount_inc(&binder_dev->ref); in binder_open()
5769 proc->context = &binder_dev->context; in binder_open()
5770 binder_alloc_init(&proc->alloc); in binder_open()
5773 proc->pid = current->group_leader->pid; in binder_open()
5774 INIT_LIST_HEAD(&proc->delivered_death); in binder_open()
5775 INIT_LIST_HEAD(&proc->waiting_threads); in binder_open()
5776 filp->private_data = proc; in binder_open()
5780 if (itr->pid == proc->pid) { in binder_open()
5785 hlist_add_head(&proc->proc_node, &binder_procs); in binder_open()
5791 snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); in binder_open()
5798 proc->debugfs_entry = debugfs_create_file(strbuf, 0444, in binder_open()
5800 (void *)(unsigned long)proc->pid, in binder_open()
5808 snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); in binder_open()
5816 strbuf, &proc_fops, (void *)(unsigned long)proc->pid); in binder_open()
5818 proc->binderfs_entry = binderfs_entry; in binder_open()
5833 struct binder_proc *proc = filp->private_data; in binder_flush()
5846 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in binder_deferred_flush()
5849 thread->looper_need_return = true; in binder_deferred_flush()
5850 if (thread->looper & BINDER_LOOPER_STATE_WAITING) { in binder_deferred_flush()
5851 wake_up_interruptible(&thread->wait); in binder_deferred_flush()
5858 "binder_flush: %d woke %d threads\n", proc->pid, in binder_deferred_flush()
5864 struct binder_proc *proc = filp->private_data; in binder_release()
5866 debugfs_remove(proc->debugfs_entry); in binder_release()
5868 if (proc->binderfs_entry) { in binder_release()
5869 binderfs_remove_file(proc->binderfs_entry); in binder_release()
5870 proc->binderfs_entry = NULL; in binder_release()
5882 struct binder_proc *proc = node->proc; in binder_node_release()
5884 binder_release_work(proc, &node->async_todo); in binder_node_release()
5888 binder_dequeue_work_ilocked(&node->work); in binder_node_release()
5892 BUG_ON(!node->tmp_refs); in binder_node_release()
5893 if (hlist_empty(&node->refs) && node->tmp_refs == 1) { in binder_node_release()
5901 node->proc = NULL; in binder_node_release()
5902 node->local_strong_refs = 0; in binder_node_release()
5903 node->local_weak_refs = 0; in binder_node_release()
5907 hlist_add_head(&node->dead_node, &binder_dead_nodes); in binder_node_release()
5910 hlist_for_each_entry(ref, &node->refs, node_entry) { in binder_node_release()
5918 binder_inner_proc_lock(ref->proc); in binder_node_release()
5919 if (!ref->death) { in binder_node_release()
5920 binder_inner_proc_unlock(ref->proc); in binder_node_release()
5926 BUG_ON(!list_empty(&ref->death->work.entry)); in binder_node_release()
5927 ref->death->work.type = BINDER_WORK_DEAD_BINDER; in binder_node_release()
5928 binder_enqueue_work_ilocked(&ref->death->work, in binder_node_release()
5929 &ref->proc->todo); in binder_node_release()
5930 binder_wakeup_proc_ilocked(ref->proc); in binder_node_release()
5931 binder_inner_proc_unlock(ref->proc); in binder_node_release()
5936 node->debug_id, refs, death); in binder_node_release()
5945 struct binder_context *context = proc->context; in binder_deferred_release()
5950 hlist_del(&proc->proc_node); in binder_deferred_release()
5953 mutex_lock(&context->context_mgr_node_lock); in binder_deferred_release()
5954 if (context->binder_context_mgr_node && in binder_deferred_release()
5955 context->binder_context_mgr_node->proc == proc) { in binder_deferred_release()
5958 __func__, proc->pid); in binder_deferred_release()
5959 context->binder_context_mgr_node = NULL; in binder_deferred_release()
5961 mutex_unlock(&context->context_mgr_node_lock); in binder_deferred_release()
5967 proc->tmp_ref++; in binder_deferred_release()
5969 proc->is_dead = true; in binder_deferred_release()
5972 while ((n = rb_first(&proc->threads))) { in binder_deferred_release()
5984 while ((n = rb_first(&proc->nodes))) { in binder_deferred_release()
5995 rb_erase(&node->rb_node, &proc->nodes); in binder_deferred_release()
6004 while ((n = rb_first(&proc->refs_by_desc))) { in binder_deferred_release()
6016 binder_release_work(proc, &proc->todo); in binder_deferred_release()
6017 binder_release_work(proc, &proc->delivered_death); in binder_deferred_release()
6021 __func__, proc->pid, threads, nodes, incoming_refs, in binder_deferred_release()
6038 hlist_del_init(&proc->deferred_work_node); in binder_deferred_func()
6039 defer = proc->deferred_work; in binder_deferred_func()
6040 proc->deferred_work = 0; in binder_deferred_func()
6060 proc->deferred_work |= defer; in binder_defer_work()
6061 if (hlist_unhashed(&proc->deferred_work_node)) { in binder_defer_work()
6062 hlist_add_head(&proc->deferred_work_node, in binder_defer_work()
6071 const char *prefix, in print_binder_transaction_ilocked() argument
6075 struct binder_buffer *buffer = t->buffer; in print_binder_transaction_ilocked()
6077 spin_lock(&t->lock); in print_binder_transaction_ilocked()
6078 to_proc = t->to_proc; in print_binder_transaction_ilocked()
6081 prefix, t->debug_id, t, in print_binder_transaction_ilocked()
6082 t->from ? t->from->proc->pid : 0, in print_binder_transaction_ilocked()
6083 t->from ? t->from->pid : 0, in print_binder_transaction_ilocked()
6084 to_proc ? to_proc->pid : 0, in print_binder_transaction_ilocked()
6085 t->to_thread ? t->to_thread->pid : 0, in print_binder_transaction_ilocked()
6086 t->code, t->flags, t->priority, t->need_reply); in print_binder_transaction_ilocked()
6087 spin_unlock(&t->lock); in print_binder_transaction_ilocked()
6102 if (buffer->target_node) in print_binder_transaction_ilocked()
6103 seq_printf(m, " node %d", buffer->target_node->debug_id); in print_binder_transaction_ilocked()
6105 buffer->data_size, buffer->offsets_size, in print_binder_transaction_ilocked()
6106 buffer->user_data); in print_binder_transaction_ilocked()
6111 const char *prefix, in print_binder_work_ilocked() argument
6118 switch (w->type) { in print_binder_work_ilocked()
6129 prefix, e->cmd); in print_binder_work_ilocked()
6132 seq_printf(m, "%stransaction complete\n", prefix); in print_binder_work_ilocked()
6137 prefix, node->debug_id, in print_binder_work_ilocked()
6138 (u64)node->ptr, (u64)node->cookie); in print_binder_work_ilocked()
6141 seq_printf(m, "%shas dead binder\n", prefix); in print_binder_work_ilocked()
6144 seq_printf(m, "%shas cleared dead binder\n", prefix); in print_binder_work_ilocked()
6147 seq_printf(m, "%shas cleared death notification\n", prefix); in print_binder_work_ilocked()
6150 seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); in print_binder_work_ilocked()
6161 size_t start_pos = m->count; in print_binder_thread_ilocked()
6165 thread->pid, thread->looper, in print_binder_thread_ilocked()
6166 thread->looper_need_return, in print_binder_thread_ilocked()
6167 atomic_read(&thread->tmp_ref)); in print_binder_thread_ilocked()
6168 header_pos = m->count; in print_binder_thread_ilocked()
6169 t = thread->transaction_stack; in print_binder_thread_ilocked()
6171 if (t->from == thread) { in print_binder_thread_ilocked()
6172 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6174 t = t->from_parent; in print_binder_thread_ilocked()
6175 } else if (t->to_thread == thread) { in print_binder_thread_ilocked()
6176 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6178 t = t->to_parent; in print_binder_thread_ilocked()
6180 print_binder_transaction_ilocked(m, thread->proc, in print_binder_thread_ilocked()
6185 list_for_each_entry(w, &thread->todo, entry) { in print_binder_thread_ilocked()
6186 print_binder_work_ilocked(m, thread->proc, " ", in print_binder_thread_ilocked()
6189 if (!print_always && m->count == header_pos) in print_binder_thread_ilocked()
6190 m->count = start_pos; in print_binder_thread_ilocked()
6201 hlist_for_each_entry(ref, &node->refs, node_entry) in print_binder_node_nilocked()
6205 node->debug_id, (u64)node->ptr, (u64)node->cookie, in print_binder_node_nilocked()
6206 node->has_strong_ref, node->has_weak_ref, in print_binder_node_nilocked()
6207 node->local_strong_refs, node->local_weak_refs, in print_binder_node_nilocked()
6208 node->internal_strong_refs, count, node->tmp_refs); in print_binder_node_nilocked()
6211 hlist_for_each_entry(ref, &node->refs, node_entry) in print_binder_node_nilocked()
6212 seq_printf(m, " %d", ref->proc->pid); in print_binder_node_nilocked()
6215 if (node->proc) { in print_binder_node_nilocked()
6216 list_for_each_entry(w, &node->async_todo, entry) in print_binder_node_nilocked()
6217 print_binder_work_ilocked(m, node->proc, " ", in print_binder_node_nilocked()
6218 " pending async transaction", w); in print_binder_node_nilocked()
6225 binder_node_lock(ref->node); in print_binder_ref_olocked()
6227 ref->data.debug_id, ref->data.desc, in print_binder_ref_olocked()
6228 ref->node->proc ? "" : "dead ", in print_binder_ref_olocked()
6229 ref->node->debug_id, ref->data.strong, in print_binder_ref_olocked()
6230 ref->data.weak, ref->death); in print_binder_ref_olocked()
6231 binder_node_unlock(ref->node); in print_binder_ref_olocked()
6239 size_t start_pos = m->count; in print_binder_proc()
6243 seq_printf(m, "proc %d\n", proc->pid); in print_binder_proc()
6244 seq_printf(m, "context %s\n", proc->context->name); in print_binder_proc()
6245 header_pos = m->count; in print_binder_proc()
6248 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) in print_binder_proc()
6252 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in print_binder_proc()
6255 if (!print_all && !node->has_async_transaction) in print_binder_proc()
6280 for (n = rb_first(&proc->refs_by_desc); in print_binder_proc()
6288 binder_alloc_print_allocated(m, &proc->alloc); in print_binder_proc()
6290 list_for_each_entry(w, &proc->todo, entry) in print_binder_proc()
6293 list_for_each_entry(w, &proc->delivered_death, entry) { in print_binder_proc()
6298 if (!print_all && m->count == header_pos) in print_binder_proc()
6299 m->count = start_pos; in print_binder_proc()
6355 static void print_binder_stats(struct seq_file *m, const char *prefix, in print_binder_stats() argument
6360 BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != in print_binder_stats()
6362 for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { in print_binder_stats()
6363 int temp = atomic_read(&stats->bc[i]); in print_binder_stats()
6366 seq_printf(m, "%s%s: %d\n", prefix, in print_binder_stats()
6370 BUILD_BUG_ON(ARRAY_SIZE(stats->br) != in print_binder_stats()
6372 for (i = 0; i < ARRAY_SIZE(stats->br); i++) { in print_binder_stats()
6373 int temp = atomic_read(&stats->br[i]); in print_binder_stats()
6376 seq_printf(m, "%s%s: %d\n", prefix, in print_binder_stats()
6380 BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != in print_binder_stats()
6382 BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != in print_binder_stats()
6383 ARRAY_SIZE(stats->obj_deleted)); in print_binder_stats()
6384 for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { in print_binder_stats()
6385 int created = atomic_read(&stats->obj_created[i]); in print_binder_stats()
6386 int deleted = atomic_read(&stats->obj_deleted[i]); in print_binder_stats()
6390 prefix, in print_binder_stats()
6392 created - deleted, in print_binder_stats()
6405 binder_alloc_get_free_async_space(&proc->alloc); in print_binder_proc_stats()
6407 seq_printf(m, "proc %d\n", proc->pid); in print_binder_proc_stats()
6408 seq_printf(m, "context %s\n", proc->context->name); in print_binder_proc_stats()
6412 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) in print_binder_proc_stats()
6415 list_for_each_entry(thread, &proc->waiting_threads, waiting_thread_node) in print_binder_proc_stats()
6421 " free async space %zd\n", proc->requested_threads, in print_binder_proc_stats()
6422 proc->requested_threads_started, proc->max_threads, in print_binder_proc_stats()
6426 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) in print_binder_proc_stats()
6434 for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { in print_binder_proc_stats()
6438 strong += ref->data.strong; in print_binder_proc_stats()
6439 weak += ref->data.weak; in print_binder_proc_stats()
6444 count = binder_alloc_get_allocated_count(&proc->alloc); in print_binder_proc_stats()
6447 binder_alloc_print_pages(m, &proc->alloc); in print_binder_proc_stats()
6451 list_for_each_entry(w, &proc->todo, entry) { in print_binder_proc_stats()
6452 if (w->type == BINDER_WORK_TRANSACTION) in print_binder_proc_stats()
6458 print_binder_stats(m, " ", &proc->stats); in print_binder_proc_stats()
6479 node->tmp_refs++; in binder_state_show()
6533 int pid = (unsigned long)m->private; in proc_show()
6537 if (itr->pid == pid) { in proc_show()
6550 int debug_id = READ_ONCE(e->debug_id_done); in print_binder_transaction_log_entry()
6558 e->debug_id, (e->call_type == 2) ? "reply" : in print_binder_transaction_log_entry()
6559 ((e->call_type == 1) ? "async" : "call "), e->from_proc, in print_binder_transaction_log_entry()
6560 e->from_thread, e->to_proc, e->to_thread, e->context_name, in print_binder_transaction_log_entry()
6561 e->to_node, e->target_handle, e->data_size, e->offsets_size, in print_binder_transaction_log_entry()
6562 e->return_error, e->return_error_param, in print_binder_transaction_log_entry()
6563 e->return_error_line); in print_binder_transaction_log_entry()
6565 * read-barrier to guarantee read of debug_id_done after in print_binder_transaction_log_entry()
6569 seq_printf(m, debug_id && debug_id == READ_ONCE(e->debug_id_done) ? in print_binder_transaction_log_entry()
6575 struct binder_transaction_log *log = m->private; in binder_transaction_log_show()
6576 unsigned int log_cur = atomic_read(&log->cur); in binder_transaction_log_show()
6582 cur = count < ARRAY_SIZE(log->entry) && !log->full ? in binder_transaction_log_show()
6583 0 : count % ARRAY_SIZE(log->entry); in binder_transaction_log_show()
6584 if (count > ARRAY_SIZE(log->entry) || log->full) in binder_transaction_log_show()
6585 count = ARRAY_SIZE(log->entry); in binder_transaction_log_show()
6587 unsigned int index = cur++ % ARRAY_SIZE(log->entry); in binder_transaction_log_show()
6589 print_binder_transaction_log_entry(m, &log->entry[index]); in binder_transaction_log_show()
6609 const char *prefix, struct binder_transaction *t, in print_binder_transaction_brief_ilocked() argument
6619 spin_lock(&t->lock); in print_binder_transaction_brief_ilocked()
6620 to_proc = t->to_proc; in print_binder_transaction_brief_ilocked()
6621 from_pid = t->from ? (t->from->proc ? t->from->proc->pid : 0) : t->async_from_pid; in print_binder_transaction_brief_ilocked()
6622 from_tid = t->from ? t->from->pid : t->async_from_tid; in print_binder_transaction_brief_ilocked()
6623 to_pid = to_proc ? to_proc->pid : 0; in print_binder_transaction_brief_ilocked()
6624 sec = div_u64_rem((timestamp - t->timestamp), 1000000000, &nsec); in print_binder_transaction_brief_ilocked()
6628 prefix, in print_binder_transaction_brief_ilocked()
6630 to_pid, t->to_thread ? t->to_thread->pid : 0, in print_binder_transaction_brief_ilocked()
6631 t->code, in print_binder_transaction_brief_ilocked()
6632 timestamp > t->timestamp ? sec : 0, in print_binder_transaction_brief_ilocked()
6633 timestamp > t->timestamp ? nsec : 0); in print_binder_transaction_brief_ilocked()
6634 spin_unlock(&t->lock); in print_binder_transaction_brief_ilocked()
6638 const char *prefix, struct binder_work *w, in print_binder_work_transaction_nilocked() argument
6643 switch (w->type) { in print_binder_work_transaction_nilocked()
6646 print_binder_transaction_brief_ilocked(m, prefix, t, timestamp); in print_binder_work_transaction_nilocked()
6661 size_t start_pos = m->count; in print_binder_transaction_brief()
6662 size_t header_pos = m->count; in print_binder_transaction_brief()
6666 for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { in print_binder_transaction_brief()
6668 struct binder_transaction *t = thread->transaction_stack; in print_binder_transaction_brief()
6670 if (t->from == thread) { in print_binder_transaction_brief()
6672 t = t->from_parent; in print_binder_transaction_brief()
6673 } else if (t->to_thread == thread) { in print_binder_transaction_brief()
6674 t = t->to_parent; in print_binder_transaction_brief()
6681 /* async binder / one way */ in print_binder_transaction_brief()
6682 for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { in print_binder_transaction_brief()
6695 list_for_each_entry(w, &node->async_todo, entry) in print_binder_transaction_brief()
6696 print_binder_work_transaction_nilocked(m, "async\t", w, timestamp); in print_binder_transaction_brief()
6706 if (m->count == header_pos) in print_binder_transaction_brief()
6707 m->count = start_pos; in print_binder_transaction_brief()
6715 size_t free_async_space = binder_alloc_get_free_async_space(&proc->alloc); in print_binder_proc_brief()
6717 seq_printf(m, "%d\t", proc->pid); in print_binder_proc_brief()
6718 seq_printf(m, "%s\t", proc->context->name); in print_binder_proc_brief()
6721 list_for_each_entry(thread, &proc->waiting_threads, waiting_thread_node) in print_binder_proc_brief()
6725 "\t%zd\n", proc->requested_threads, in print_binder_proc_brief()
6726 proc->requested_threads_started, proc->max_threads, in print_binder_proc_brief()
6759 return -ENOMEM; in init_binder_device()
6761 binder_device->miscdev.fops = &binder_fops; in init_binder_device()
6762 binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; in init_binder_device()
6763 binder_device->miscdev.name = name; in init_binder_device()
6765 refcount_set(&binder_device->ref, 1); in init_binder_device()
6766 binder_device->context.binder_context_mgr_uid = INVALID_UID; in init_binder_device()
6767 binder_device->context.name = name; in init_binder_device()
6768 mutex_init(&binder_device->context.context_mgr_node_lock); in init_binder_device()
6770 ret = misc_register(&binder_device->miscdev); in init_binder_device()
6776 hlist_add_head(&binder_device->hlist, &binder_devices); in init_binder_device()
6840 * tokenize it in-place. in binder_init()
6844 ret = -ENOMEM; in binder_init()
6864 misc_deregister(&device->miscdev); in binder_init()
6865 hlist_del(&device->hlist); in binder_init()