162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#ifndef _LINUX_BINDER_INTERNAL_H 462306a36Sopenharmony_ci#define _LINUX_BINDER_INTERNAL_H 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/export.h> 762306a36Sopenharmony_ci#include <linux/fs.h> 862306a36Sopenharmony_ci#include <linux/list.h> 962306a36Sopenharmony_ci#include <linux/miscdevice.h> 1062306a36Sopenharmony_ci#include <linux/mutex.h> 1162306a36Sopenharmony_ci#include <linux/refcount.h> 1262306a36Sopenharmony_ci#include <linux/stddef.h> 1362306a36Sopenharmony_ci#include <linux/types.h> 1462306a36Sopenharmony_ci#include <linux/uidgid.h> 1562306a36Sopenharmony_ci#include <uapi/linux/android/binderfs.h> 1662306a36Sopenharmony_ci#include "binder_alloc.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistruct binder_context { 1962306a36Sopenharmony_ci struct binder_node *binder_context_mgr_node; 2062306a36Sopenharmony_ci struct mutex context_mgr_node_lock; 2162306a36Sopenharmony_ci kuid_t binder_context_mgr_uid; 2262306a36Sopenharmony_ci const char *name; 2362306a36Sopenharmony_ci}; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/** 2662306a36Sopenharmony_ci * struct binder_device - information about a binder device node 2762306a36Sopenharmony_ci * @hlist: list of binder devices (only used for devices requested via 2862306a36Sopenharmony_ci * CONFIG_ANDROID_BINDER_DEVICES) 2962306a36Sopenharmony_ci * @miscdev: information about a binder character device node 3062306a36Sopenharmony_ci * @context: binder context information 3162306a36Sopenharmony_ci * @binderfs_inode: This is the inode of the root dentry of the super block 3262306a36Sopenharmony_ci * belonging to a binderfs mount. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistruct binder_device { 3562306a36Sopenharmony_ci struct hlist_node hlist; 3662306a36Sopenharmony_ci struct miscdevice miscdev; 3762306a36Sopenharmony_ci struct binder_context context; 3862306a36Sopenharmony_ci struct inode *binderfs_inode; 3962306a36Sopenharmony_ci refcount_t ref; 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/** 4362306a36Sopenharmony_ci * binderfs_mount_opts - mount options for binderfs 4462306a36Sopenharmony_ci * @max: maximum number of allocatable binderfs binder devices 4562306a36Sopenharmony_ci * @stats_mode: enable binder stats in binderfs. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_cistruct binderfs_mount_opts { 4862306a36Sopenharmony_ci int max; 4962306a36Sopenharmony_ci int stats_mode; 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/** 5362306a36Sopenharmony_ci * binderfs_info - information about a binderfs mount 5462306a36Sopenharmony_ci * @ipc_ns: The ipc namespace the binderfs mount belongs to. 5562306a36Sopenharmony_ci * @control_dentry: This records the dentry of this binderfs mount 5662306a36Sopenharmony_ci * binder-control device. 5762306a36Sopenharmony_ci * @root_uid: uid that needs to be used when a new binder device is 5862306a36Sopenharmony_ci * created. 5962306a36Sopenharmony_ci * @root_gid: gid that needs to be used when a new binder device is 6062306a36Sopenharmony_ci * created. 6162306a36Sopenharmony_ci * @mount_opts: The mount options in use. 6262306a36Sopenharmony_ci * @device_count: The current number of allocated binder devices. 6362306a36Sopenharmony_ci * @proc_log_dir: Pointer to the directory dentry containing process-specific 6462306a36Sopenharmony_ci * logs. 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_cistruct binderfs_info { 6762306a36Sopenharmony_ci struct ipc_namespace *ipc_ns; 6862306a36Sopenharmony_ci struct dentry *control_dentry; 6962306a36Sopenharmony_ci kuid_t root_uid; 7062306a36Sopenharmony_ci kgid_t root_gid; 7162306a36Sopenharmony_ci struct binderfs_mount_opts mount_opts; 7262306a36Sopenharmony_ci int device_count; 7362306a36Sopenharmony_ci struct dentry *proc_log_dir; 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ciextern const struct file_operations binder_fops; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciextern char *binder_devices_param; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#ifdef CONFIG_ANDROID_BINDERFS 8162306a36Sopenharmony_ciextern bool is_binderfs_device(const struct inode *inode); 8262306a36Sopenharmony_ciextern struct dentry *binderfs_create_file(struct dentry *dir, const char *name, 8362306a36Sopenharmony_ci const struct file_operations *fops, 8462306a36Sopenharmony_ci void *data); 8562306a36Sopenharmony_ciextern void binderfs_remove_file(struct dentry *dentry); 8662306a36Sopenharmony_ci#else 8762306a36Sopenharmony_cistatic inline bool is_binderfs_device(const struct inode *inode) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci return false; 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_cistatic inline struct dentry *binderfs_create_file(struct dentry *dir, 9262306a36Sopenharmony_ci const char *name, 9362306a36Sopenharmony_ci const struct file_operations *fops, 9462306a36Sopenharmony_ci void *data) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci return NULL; 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_cistatic inline void binderfs_remove_file(struct dentry *dentry) {} 9962306a36Sopenharmony_ci#endif 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#ifdef CONFIG_ANDROID_BINDERFS 10262306a36Sopenharmony_ciextern int __init init_binderfs(void); 10362306a36Sopenharmony_ci#else 10462306a36Sopenharmony_cistatic inline int __init init_binderfs(void) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci return 0; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci#endif 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_cistruct binder_debugfs_entry { 11162306a36Sopenharmony_ci const char *name; 11262306a36Sopenharmony_ci umode_t mode; 11362306a36Sopenharmony_ci const struct file_operations *fops; 11462306a36Sopenharmony_ci void *data; 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ciextern const struct binder_debugfs_entry binder_debugfs_entries[]; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#define binder_for_each_debugfs_entry(entry) \ 12062306a36Sopenharmony_ci for ((entry) = binder_debugfs_entries; \ 12162306a36Sopenharmony_ci (entry)->name; \ 12262306a36Sopenharmony_ci (entry)++) 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cienum binder_stat_types { 12562306a36Sopenharmony_ci BINDER_STAT_PROC, 12662306a36Sopenharmony_ci BINDER_STAT_THREAD, 12762306a36Sopenharmony_ci BINDER_STAT_NODE, 12862306a36Sopenharmony_ci BINDER_STAT_REF, 12962306a36Sopenharmony_ci BINDER_STAT_DEATH, 13062306a36Sopenharmony_ci BINDER_STAT_TRANSACTION, 13162306a36Sopenharmony_ci BINDER_STAT_TRANSACTION_COMPLETE, 13262306a36Sopenharmony_ci BINDER_STAT_COUNT 13362306a36Sopenharmony_ci}; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistruct binder_stats { 13662306a36Sopenharmony_ci atomic_t br[_IOC_NR(BR_TRANSACTION_PENDING_FROZEN) + 1]; 13762306a36Sopenharmony_ci atomic_t bc[_IOC_NR(BC_REPLY_SG) + 1]; 13862306a36Sopenharmony_ci atomic_t obj_created[BINDER_STAT_COUNT]; 13962306a36Sopenharmony_ci atomic_t obj_deleted[BINDER_STAT_COUNT]; 14062306a36Sopenharmony_ci}; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci/** 14362306a36Sopenharmony_ci * struct binder_work - work enqueued on a worklist 14462306a36Sopenharmony_ci * @entry: node enqueued on list 14562306a36Sopenharmony_ci * @type: type of work to be performed 14662306a36Sopenharmony_ci * 14762306a36Sopenharmony_ci * There are separate work lists for proc, thread, and node (async). 14862306a36Sopenharmony_ci */ 14962306a36Sopenharmony_cistruct binder_work { 15062306a36Sopenharmony_ci struct list_head entry; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci enum binder_work_type { 15362306a36Sopenharmony_ci BINDER_WORK_TRANSACTION = 1, 15462306a36Sopenharmony_ci BINDER_WORK_TRANSACTION_COMPLETE, 15562306a36Sopenharmony_ci BINDER_WORK_TRANSACTION_PENDING, 15662306a36Sopenharmony_ci BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT, 15762306a36Sopenharmony_ci BINDER_WORK_RETURN_ERROR, 15862306a36Sopenharmony_ci BINDER_WORK_NODE, 15962306a36Sopenharmony_ci BINDER_WORK_DEAD_BINDER, 16062306a36Sopenharmony_ci BINDER_WORK_DEAD_BINDER_AND_CLEAR, 16162306a36Sopenharmony_ci BINDER_WORK_CLEAR_DEATH_NOTIFICATION, 16262306a36Sopenharmony_ci } type; 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistruct binder_error { 16662306a36Sopenharmony_ci struct binder_work work; 16762306a36Sopenharmony_ci uint32_t cmd; 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci/** 17162306a36Sopenharmony_ci * struct binder_node - binder node bookkeeping 17262306a36Sopenharmony_ci * @debug_id: unique ID for debugging 17362306a36Sopenharmony_ci * (invariant after initialized) 17462306a36Sopenharmony_ci * @lock: lock for node fields 17562306a36Sopenharmony_ci * @work: worklist element for node work 17662306a36Sopenharmony_ci * (protected by @proc->inner_lock) 17762306a36Sopenharmony_ci * @rb_node: element for proc->nodes tree 17862306a36Sopenharmony_ci * (protected by @proc->inner_lock) 17962306a36Sopenharmony_ci * @dead_node: element for binder_dead_nodes list 18062306a36Sopenharmony_ci * (protected by binder_dead_nodes_lock) 18162306a36Sopenharmony_ci * @proc: binder_proc that owns this node 18262306a36Sopenharmony_ci * (invariant after initialized) 18362306a36Sopenharmony_ci * @refs: list of references on this node 18462306a36Sopenharmony_ci * (protected by @lock) 18562306a36Sopenharmony_ci * @internal_strong_refs: used to take strong references when 18662306a36Sopenharmony_ci * initiating a transaction 18762306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 18862306a36Sopenharmony_ci * and by @lock) 18962306a36Sopenharmony_ci * @local_weak_refs: weak user refs from local process 19062306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 19162306a36Sopenharmony_ci * and by @lock) 19262306a36Sopenharmony_ci * @local_strong_refs: strong user refs from local process 19362306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 19462306a36Sopenharmony_ci * and by @lock) 19562306a36Sopenharmony_ci * @tmp_refs: temporary kernel refs 19662306a36Sopenharmony_ci * (protected by @proc->inner_lock while @proc 19762306a36Sopenharmony_ci * is valid, and by binder_dead_nodes_lock 19862306a36Sopenharmony_ci * if @proc is NULL. During inc/dec and node release 19962306a36Sopenharmony_ci * it is also protected by @lock to provide safety 20062306a36Sopenharmony_ci * as the node dies and @proc becomes NULL) 20162306a36Sopenharmony_ci * @ptr: userspace pointer for node 20262306a36Sopenharmony_ci * (invariant, no lock needed) 20362306a36Sopenharmony_ci * @cookie: userspace cookie for node 20462306a36Sopenharmony_ci * (invariant, no lock needed) 20562306a36Sopenharmony_ci * @has_strong_ref: userspace notified of strong ref 20662306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 20762306a36Sopenharmony_ci * and by @lock) 20862306a36Sopenharmony_ci * @pending_strong_ref: userspace has acked notification of strong ref 20962306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 21062306a36Sopenharmony_ci * and by @lock) 21162306a36Sopenharmony_ci * @has_weak_ref: userspace notified of weak ref 21262306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 21362306a36Sopenharmony_ci * and by @lock) 21462306a36Sopenharmony_ci * @pending_weak_ref: userspace has acked notification of weak ref 21562306a36Sopenharmony_ci * (protected by @proc->inner_lock if @proc 21662306a36Sopenharmony_ci * and by @lock) 21762306a36Sopenharmony_ci * @has_async_transaction: async transaction to node in progress 21862306a36Sopenharmony_ci * (protected by @lock) 21962306a36Sopenharmony_ci * @accept_fds: file descriptor operations supported for node 22062306a36Sopenharmony_ci * (invariant after initialized) 22162306a36Sopenharmony_ci * @min_priority: minimum scheduling priority 22262306a36Sopenharmony_ci * (invariant after initialized) 22362306a36Sopenharmony_ci * @txn_security_ctx: require sender's security context 22462306a36Sopenharmony_ci * (invariant after initialized) 22562306a36Sopenharmony_ci * @async_todo: list of async work items 22662306a36Sopenharmony_ci * (protected by @proc->inner_lock) 22762306a36Sopenharmony_ci * 22862306a36Sopenharmony_ci * Bookkeeping structure for binder nodes. 22962306a36Sopenharmony_ci */ 23062306a36Sopenharmony_cistruct binder_node { 23162306a36Sopenharmony_ci int debug_id; 23262306a36Sopenharmony_ci spinlock_t lock; 23362306a36Sopenharmony_ci struct binder_work work; 23462306a36Sopenharmony_ci union { 23562306a36Sopenharmony_ci struct rb_node rb_node; 23662306a36Sopenharmony_ci struct hlist_node dead_node; 23762306a36Sopenharmony_ci }; 23862306a36Sopenharmony_ci struct binder_proc *proc; 23962306a36Sopenharmony_ci struct hlist_head refs; 24062306a36Sopenharmony_ci int internal_strong_refs; 24162306a36Sopenharmony_ci int local_weak_refs; 24262306a36Sopenharmony_ci int local_strong_refs; 24362306a36Sopenharmony_ci int tmp_refs; 24462306a36Sopenharmony_ci binder_uintptr_t ptr; 24562306a36Sopenharmony_ci binder_uintptr_t cookie; 24662306a36Sopenharmony_ci struct { 24762306a36Sopenharmony_ci /* 24862306a36Sopenharmony_ci * bitfield elements protected by 24962306a36Sopenharmony_ci * proc inner_lock 25062306a36Sopenharmony_ci */ 25162306a36Sopenharmony_ci u8 has_strong_ref:1; 25262306a36Sopenharmony_ci u8 pending_strong_ref:1; 25362306a36Sopenharmony_ci u8 has_weak_ref:1; 25462306a36Sopenharmony_ci u8 pending_weak_ref:1; 25562306a36Sopenharmony_ci }; 25662306a36Sopenharmony_ci struct { 25762306a36Sopenharmony_ci /* 25862306a36Sopenharmony_ci * invariant after initialization 25962306a36Sopenharmony_ci */ 26062306a36Sopenharmony_ci u8 accept_fds:1; 26162306a36Sopenharmony_ci u8 txn_security_ctx:1; 26262306a36Sopenharmony_ci u8 min_priority; 26362306a36Sopenharmony_ci }; 26462306a36Sopenharmony_ci bool has_async_transaction; 26562306a36Sopenharmony_ci struct list_head async_todo; 26662306a36Sopenharmony_ci}; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_cistruct binder_ref_death { 26962306a36Sopenharmony_ci /** 27062306a36Sopenharmony_ci * @work: worklist element for death notifications 27162306a36Sopenharmony_ci * (protected by inner_lock of the proc that 27262306a36Sopenharmony_ci * this ref belongs to) 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_ci struct binder_work work; 27562306a36Sopenharmony_ci binder_uintptr_t cookie; 27662306a36Sopenharmony_ci}; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci/** 27962306a36Sopenharmony_ci * struct binder_ref_data - binder_ref counts and id 28062306a36Sopenharmony_ci * @debug_id: unique ID for the ref 28162306a36Sopenharmony_ci * @desc: unique userspace handle for ref 28262306a36Sopenharmony_ci * @strong: strong ref count (debugging only if not locked) 28362306a36Sopenharmony_ci * @weak: weak ref count (debugging only if not locked) 28462306a36Sopenharmony_ci * 28562306a36Sopenharmony_ci * Structure to hold ref count and ref id information. Since 28662306a36Sopenharmony_ci * the actual ref can only be accessed with a lock, this structure 28762306a36Sopenharmony_ci * is used to return information about the ref to callers of 28862306a36Sopenharmony_ci * ref inc/dec functions. 28962306a36Sopenharmony_ci */ 29062306a36Sopenharmony_cistruct binder_ref_data { 29162306a36Sopenharmony_ci int debug_id; 29262306a36Sopenharmony_ci uint32_t desc; 29362306a36Sopenharmony_ci int strong; 29462306a36Sopenharmony_ci int weak; 29562306a36Sopenharmony_ci}; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci/** 29862306a36Sopenharmony_ci * struct binder_ref - struct to track references on nodes 29962306a36Sopenharmony_ci * @data: binder_ref_data containing id, handle, and current refcounts 30062306a36Sopenharmony_ci * @rb_node_desc: node for lookup by @data.desc in proc's rb_tree 30162306a36Sopenharmony_ci * @rb_node_node: node for lookup by @node in proc's rb_tree 30262306a36Sopenharmony_ci * @node_entry: list entry for node->refs list in target node 30362306a36Sopenharmony_ci * (protected by @node->lock) 30462306a36Sopenharmony_ci * @proc: binder_proc containing ref 30562306a36Sopenharmony_ci * @node: binder_node of target node. When cleaning up a 30662306a36Sopenharmony_ci * ref for deletion in binder_cleanup_ref, a non-NULL 30762306a36Sopenharmony_ci * @node indicates the node must be freed 30862306a36Sopenharmony_ci * @death: pointer to death notification (ref_death) if requested 30962306a36Sopenharmony_ci * (protected by @node->lock) 31062306a36Sopenharmony_ci * 31162306a36Sopenharmony_ci * Structure to track references from procA to target node (on procB). This 31262306a36Sopenharmony_ci * structure is unsafe to access without holding @proc->outer_lock. 31362306a36Sopenharmony_ci */ 31462306a36Sopenharmony_cistruct binder_ref { 31562306a36Sopenharmony_ci /* Lookups needed: */ 31662306a36Sopenharmony_ci /* node + proc => ref (transaction) */ 31762306a36Sopenharmony_ci /* desc + proc => ref (transaction, inc/dec ref) */ 31862306a36Sopenharmony_ci /* node => refs + procs (proc exit) */ 31962306a36Sopenharmony_ci struct binder_ref_data data; 32062306a36Sopenharmony_ci struct rb_node rb_node_desc; 32162306a36Sopenharmony_ci struct rb_node rb_node_node; 32262306a36Sopenharmony_ci struct hlist_node node_entry; 32362306a36Sopenharmony_ci struct binder_proc *proc; 32462306a36Sopenharmony_ci struct binder_node *node; 32562306a36Sopenharmony_ci struct binder_ref_death *death; 32662306a36Sopenharmony_ci}; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/** 32962306a36Sopenharmony_ci * struct binder_proc - binder process bookkeeping 33062306a36Sopenharmony_ci * @proc_node: element for binder_procs list 33162306a36Sopenharmony_ci * @threads: rbtree of binder_threads in this proc 33262306a36Sopenharmony_ci * (protected by @inner_lock) 33362306a36Sopenharmony_ci * @nodes: rbtree of binder nodes associated with 33462306a36Sopenharmony_ci * this proc ordered by node->ptr 33562306a36Sopenharmony_ci * (protected by @inner_lock) 33662306a36Sopenharmony_ci * @refs_by_desc: rbtree of refs ordered by ref->desc 33762306a36Sopenharmony_ci * (protected by @outer_lock) 33862306a36Sopenharmony_ci * @refs_by_node: rbtree of refs ordered by ref->node 33962306a36Sopenharmony_ci * (protected by @outer_lock) 34062306a36Sopenharmony_ci * @waiting_threads: threads currently waiting for proc work 34162306a36Sopenharmony_ci * (protected by @inner_lock) 34262306a36Sopenharmony_ci * @pid PID of group_leader of process 34362306a36Sopenharmony_ci * (invariant after initialized) 34462306a36Sopenharmony_ci * @tsk task_struct for group_leader of process 34562306a36Sopenharmony_ci * (invariant after initialized) 34662306a36Sopenharmony_ci * @cred struct cred associated with the `struct file` 34762306a36Sopenharmony_ci * in binder_open() 34862306a36Sopenharmony_ci * (invariant after initialized) 34962306a36Sopenharmony_ci * @deferred_work_node: element for binder_deferred_list 35062306a36Sopenharmony_ci * (protected by binder_deferred_lock) 35162306a36Sopenharmony_ci * @deferred_work: bitmap of deferred work to perform 35262306a36Sopenharmony_ci * (protected by binder_deferred_lock) 35362306a36Sopenharmony_ci * @outstanding_txns: number of transactions to be transmitted before 35462306a36Sopenharmony_ci * processes in freeze_wait are woken up 35562306a36Sopenharmony_ci * (protected by @inner_lock) 35662306a36Sopenharmony_ci * @is_dead: process is dead and awaiting free 35762306a36Sopenharmony_ci * when outstanding transactions are cleaned up 35862306a36Sopenharmony_ci * (protected by @inner_lock) 35962306a36Sopenharmony_ci * @is_frozen: process is frozen and unable to service 36062306a36Sopenharmony_ci * binder transactions 36162306a36Sopenharmony_ci * (protected by @inner_lock) 36262306a36Sopenharmony_ci * @sync_recv: process received sync transactions since last frozen 36362306a36Sopenharmony_ci * bit 0: received sync transaction after being frozen 36462306a36Sopenharmony_ci * bit 1: new pending sync transaction during freezing 36562306a36Sopenharmony_ci * (protected by @inner_lock) 36662306a36Sopenharmony_ci * @async_recv: process received async transactions since last frozen 36762306a36Sopenharmony_ci * (protected by @inner_lock) 36862306a36Sopenharmony_ci * @freeze_wait: waitqueue of processes waiting for all outstanding 36962306a36Sopenharmony_ci * transactions to be processed 37062306a36Sopenharmony_ci * (protected by @inner_lock) 37162306a36Sopenharmony_ci * @todo: list of work for this process 37262306a36Sopenharmony_ci * (protected by @inner_lock) 37362306a36Sopenharmony_ci * @stats: per-process binder statistics 37462306a36Sopenharmony_ci * (atomics, no lock needed) 37562306a36Sopenharmony_ci * @delivered_death: list of delivered death notification 37662306a36Sopenharmony_ci * (protected by @inner_lock) 37762306a36Sopenharmony_ci * @max_threads: cap on number of binder threads 37862306a36Sopenharmony_ci * (protected by @inner_lock) 37962306a36Sopenharmony_ci * @requested_threads: number of binder threads requested but not 38062306a36Sopenharmony_ci * yet started. In current implementation, can 38162306a36Sopenharmony_ci * only be 0 or 1. 38262306a36Sopenharmony_ci * (protected by @inner_lock) 38362306a36Sopenharmony_ci * @requested_threads_started: number binder threads started 38462306a36Sopenharmony_ci * (protected by @inner_lock) 38562306a36Sopenharmony_ci * @tmp_ref: temporary reference to indicate proc is in use 38662306a36Sopenharmony_ci * (protected by @inner_lock) 38762306a36Sopenharmony_ci * @default_priority: default scheduler priority 38862306a36Sopenharmony_ci * (invariant after initialized) 38962306a36Sopenharmony_ci * @debugfs_entry: debugfs node 39062306a36Sopenharmony_ci * @alloc: binder allocator bookkeeping 39162306a36Sopenharmony_ci * @context: binder_context for this proc 39262306a36Sopenharmony_ci * (invariant after initialized) 39362306a36Sopenharmony_ci * @inner_lock: can nest under outer_lock and/or node lock 39462306a36Sopenharmony_ci * @outer_lock: no nesting under innor or node lock 39562306a36Sopenharmony_ci * Lock order: 1) outer, 2) node, 3) inner 39662306a36Sopenharmony_ci * @binderfs_entry: process-specific binderfs log file 39762306a36Sopenharmony_ci * @oneway_spam_detection_enabled: process enabled oneway spam detection 39862306a36Sopenharmony_ci * or not 39962306a36Sopenharmony_ci * 40062306a36Sopenharmony_ci * Bookkeeping structure for binder processes 40162306a36Sopenharmony_ci */ 40262306a36Sopenharmony_cistruct binder_proc { 40362306a36Sopenharmony_ci struct hlist_node proc_node; 40462306a36Sopenharmony_ci struct rb_root threads; 40562306a36Sopenharmony_ci struct rb_root nodes; 40662306a36Sopenharmony_ci struct rb_root refs_by_desc; 40762306a36Sopenharmony_ci struct rb_root refs_by_node; 40862306a36Sopenharmony_ci struct list_head waiting_threads; 40962306a36Sopenharmony_ci int pid; 41062306a36Sopenharmony_ci struct task_struct *tsk; 41162306a36Sopenharmony_ci const struct cred *cred; 41262306a36Sopenharmony_ci struct hlist_node deferred_work_node; 41362306a36Sopenharmony_ci int deferred_work; 41462306a36Sopenharmony_ci int outstanding_txns; 41562306a36Sopenharmony_ci bool is_dead; 41662306a36Sopenharmony_ci bool is_frozen; 41762306a36Sopenharmony_ci bool sync_recv; 41862306a36Sopenharmony_ci bool async_recv; 41962306a36Sopenharmony_ci wait_queue_head_t freeze_wait; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci struct list_head todo; 42262306a36Sopenharmony_ci struct binder_stats stats; 42362306a36Sopenharmony_ci struct list_head delivered_death; 42462306a36Sopenharmony_ci int max_threads; 42562306a36Sopenharmony_ci int requested_threads; 42662306a36Sopenharmony_ci int requested_threads_started; 42762306a36Sopenharmony_ci int tmp_ref; 42862306a36Sopenharmony_ci long default_priority; 42962306a36Sopenharmony_ci struct dentry *debugfs_entry; 43062306a36Sopenharmony_ci struct binder_alloc alloc; 43162306a36Sopenharmony_ci struct binder_context *context; 43262306a36Sopenharmony_ci spinlock_t inner_lock; 43362306a36Sopenharmony_ci spinlock_t outer_lock; 43462306a36Sopenharmony_ci struct dentry *binderfs_entry; 43562306a36Sopenharmony_ci bool oneway_spam_detection_enabled; 43662306a36Sopenharmony_ci}; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci/** 43962306a36Sopenharmony_ci * struct binder_thread - binder thread bookkeeping 44062306a36Sopenharmony_ci * @proc: binder process for this thread 44162306a36Sopenharmony_ci * (invariant after initialization) 44262306a36Sopenharmony_ci * @rb_node: element for proc->threads rbtree 44362306a36Sopenharmony_ci * (protected by @proc->inner_lock) 44462306a36Sopenharmony_ci * @waiting_thread_node: element for @proc->waiting_threads list 44562306a36Sopenharmony_ci * (protected by @proc->inner_lock) 44662306a36Sopenharmony_ci * @pid: PID for this thread 44762306a36Sopenharmony_ci * (invariant after initialization) 44862306a36Sopenharmony_ci * @looper: bitmap of looping state 44962306a36Sopenharmony_ci * (only accessed by this thread) 45062306a36Sopenharmony_ci * @looper_needs_return: looping thread needs to exit driver 45162306a36Sopenharmony_ci * (no lock needed) 45262306a36Sopenharmony_ci * @transaction_stack: stack of in-progress transactions for this thread 45362306a36Sopenharmony_ci * (protected by @proc->inner_lock) 45462306a36Sopenharmony_ci * @todo: list of work to do for this thread 45562306a36Sopenharmony_ci * (protected by @proc->inner_lock) 45662306a36Sopenharmony_ci * @process_todo: whether work in @todo should be processed 45762306a36Sopenharmony_ci * (protected by @proc->inner_lock) 45862306a36Sopenharmony_ci * @return_error: transaction errors reported by this thread 45962306a36Sopenharmony_ci * (only accessed by this thread) 46062306a36Sopenharmony_ci * @reply_error: transaction errors reported by target thread 46162306a36Sopenharmony_ci * (protected by @proc->inner_lock) 46262306a36Sopenharmony_ci * @ee: extended error information from this thread 46362306a36Sopenharmony_ci * (protected by @proc->inner_lock) 46462306a36Sopenharmony_ci * @wait: wait queue for thread work 46562306a36Sopenharmony_ci * @stats: per-thread statistics 46662306a36Sopenharmony_ci * (atomics, no lock needed) 46762306a36Sopenharmony_ci * @tmp_ref: temporary reference to indicate thread is in use 46862306a36Sopenharmony_ci * (atomic since @proc->inner_lock cannot 46962306a36Sopenharmony_ci * always be acquired) 47062306a36Sopenharmony_ci * @is_dead: thread is dead and awaiting free 47162306a36Sopenharmony_ci * when outstanding transactions are cleaned up 47262306a36Sopenharmony_ci * (protected by @proc->inner_lock) 47362306a36Sopenharmony_ci * 47462306a36Sopenharmony_ci * Bookkeeping structure for binder threads. 47562306a36Sopenharmony_ci */ 47662306a36Sopenharmony_cistruct binder_thread { 47762306a36Sopenharmony_ci struct binder_proc *proc; 47862306a36Sopenharmony_ci struct rb_node rb_node; 47962306a36Sopenharmony_ci struct list_head waiting_thread_node; 48062306a36Sopenharmony_ci int pid; 48162306a36Sopenharmony_ci int looper; /* only modified by this thread */ 48262306a36Sopenharmony_ci bool looper_need_return; /* can be written by other thread */ 48362306a36Sopenharmony_ci struct binder_transaction *transaction_stack; 48462306a36Sopenharmony_ci struct list_head todo; 48562306a36Sopenharmony_ci bool process_todo; 48662306a36Sopenharmony_ci struct binder_error return_error; 48762306a36Sopenharmony_ci struct binder_error reply_error; 48862306a36Sopenharmony_ci struct binder_extended_error ee; 48962306a36Sopenharmony_ci wait_queue_head_t wait; 49062306a36Sopenharmony_ci struct binder_stats stats; 49162306a36Sopenharmony_ci atomic_t tmp_ref; 49262306a36Sopenharmony_ci bool is_dead; 49362306a36Sopenharmony_ci#ifdef CONFIG_ACCESS_TOKENID 49462306a36Sopenharmony_ci struct access_token tokens; 49562306a36Sopenharmony_ci#endif /* CONFIG_ACCESS_TOKENID */ 49662306a36Sopenharmony_ci#ifdef CONFIG_BINDER_SENDER_INFO 49762306a36Sopenharmony_ci __u64 sender_pid_nr; 49862306a36Sopenharmony_ci#endif /* CONFIG_BINDER_SENDER_INFO */ 49962306a36Sopenharmony_ci}; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci/** 50262306a36Sopenharmony_ci * struct binder_txn_fd_fixup - transaction fd fixup list element 50362306a36Sopenharmony_ci * @fixup_entry: list entry 50462306a36Sopenharmony_ci * @file: struct file to be associated with new fd 50562306a36Sopenharmony_ci * @offset: offset in buffer data to this fixup 50662306a36Sopenharmony_ci * @target_fd: fd to use by the target to install @file 50762306a36Sopenharmony_ci * 50862306a36Sopenharmony_ci * List element for fd fixups in a transaction. Since file 50962306a36Sopenharmony_ci * descriptors need to be allocated in the context of the 51062306a36Sopenharmony_ci * target process, we pass each fd to be processed in this 51162306a36Sopenharmony_ci * struct. 51262306a36Sopenharmony_ci */ 51362306a36Sopenharmony_cistruct binder_txn_fd_fixup { 51462306a36Sopenharmony_ci struct list_head fixup_entry; 51562306a36Sopenharmony_ci struct file *file; 51662306a36Sopenharmony_ci size_t offset; 51762306a36Sopenharmony_ci int target_fd; 51862306a36Sopenharmony_ci}; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cistruct binder_transaction { 52162306a36Sopenharmony_ci int debug_id; 52262306a36Sopenharmony_ci struct binder_work work; 52362306a36Sopenharmony_ci struct binder_thread *from; 52462306a36Sopenharmony_ci pid_t from_pid; 52562306a36Sopenharmony_ci pid_t from_tid; 52662306a36Sopenharmony_ci#ifdef CONFIG_BINDER_TRANSACTION_PROC_BRIEF 52762306a36Sopenharmony_ci u64 timestamp; 52862306a36Sopenharmony_ci#endif 52962306a36Sopenharmony_ci struct binder_transaction *from_parent; 53062306a36Sopenharmony_ci struct binder_proc *to_proc; 53162306a36Sopenharmony_ci struct binder_thread *to_thread; 53262306a36Sopenharmony_ci struct binder_transaction *to_parent; 53362306a36Sopenharmony_ci unsigned need_reply:1; 53462306a36Sopenharmony_ci /* unsigned is_dead:1; */ /* not used at the moment */ 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci struct binder_buffer *buffer; 53762306a36Sopenharmony_ci unsigned int code; 53862306a36Sopenharmony_ci unsigned int flags; 53962306a36Sopenharmony_ci long priority; 54062306a36Sopenharmony_ci long saved_priority; 54162306a36Sopenharmony_ci kuid_t sender_euid; 54262306a36Sopenharmony_ci ktime_t start_time; 54362306a36Sopenharmony_ci struct list_head fd_fixups; 54462306a36Sopenharmony_ci binder_uintptr_t security_ctx; 54562306a36Sopenharmony_ci /** 54662306a36Sopenharmony_ci * @lock: protects @from, @to_proc, and @to_thread 54762306a36Sopenharmony_ci * 54862306a36Sopenharmony_ci * @from, @to_proc, and @to_thread can be set to NULL 54962306a36Sopenharmony_ci * during thread teardown 55062306a36Sopenharmony_ci */ 55162306a36Sopenharmony_ci spinlock_t lock; 55262306a36Sopenharmony_ci#ifdef CONFIG_ACCESS_TOKENID 55362306a36Sopenharmony_ci u64 sender_tokenid; 55462306a36Sopenharmony_ci u64 first_tokenid; 55562306a36Sopenharmony_ci#endif /* CONFIG_ACCESS_TOKENID */ 55662306a36Sopenharmony_ci}; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci/** 55962306a36Sopenharmony_ci * struct binder_object - union of flat binder object types 56062306a36Sopenharmony_ci * @hdr: generic object header 56162306a36Sopenharmony_ci * @fbo: binder object (nodes and refs) 56262306a36Sopenharmony_ci * @fdo: file descriptor object 56362306a36Sopenharmony_ci * @bbo: binder buffer pointer 56462306a36Sopenharmony_ci * @fdao: file descriptor array 56562306a36Sopenharmony_ci * 56662306a36Sopenharmony_ci * Used for type-independent object copies 56762306a36Sopenharmony_ci */ 56862306a36Sopenharmony_cistruct binder_object { 56962306a36Sopenharmony_ci union { 57062306a36Sopenharmony_ci struct binder_object_header hdr; 57162306a36Sopenharmony_ci struct flat_binder_object fbo; 57262306a36Sopenharmony_ci struct binder_fd_object fdo; 57362306a36Sopenharmony_ci struct binder_buffer_object bbo; 57462306a36Sopenharmony_ci struct binder_fd_array_object fdao; 57562306a36Sopenharmony_ci }; 57662306a36Sopenharmony_ci}; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci#endif /* _LINUX_BINDER_INTERNAL_H */ 579