Blame view

drivers/android/binder.c 160 KB
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /* binder.c
   *
   * Android IPC Subsystem
   *
   * Copyright (C) 2007-2008 Google, Inc.
   *
   * This software is licensed under the terms of the GNU General Public
   * License version 2, as published by the Free Software Foundation, and
   * may be copied, distributed, and modified under those terms.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   */
9630fe883   Todd Kjos   binder: introduce...
17
18
19
20
21
22
23
24
25
26
27
28
29
  /*
   * Locking overview
   *
   * There are 3 main spinlocks which must be acquired in the
   * order shown:
   *
   * 1) proc->outer_lock : protects binder_ref
   *    binder_proc_lock() and binder_proc_unlock() are
   *    used to acq/rel.
   * 2) node->lock : protects most fields of binder_node.
   *    binder_node_lock() and binder_node_unlock() are
   *    used to acq/rel
   * 3) proc->inner_lock : protects the thread and node lists
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
30
31
32
33
   *    (proc->threads, proc->waiting_threads, proc->nodes)
   *    and all todo lists associated with the binder_proc
   *    (proc->todo, thread->todo, proc->delivered_death and
   *    node->async_todo), as well as thread->transaction_stack
9630fe883   Todd Kjos   binder: introduce...
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
   *    binder_inner_proc_lock() and binder_inner_proc_unlock()
   *    are used to acq/rel
   *
   * Any lock under procA must never be nested under any lock at the same
   * level or below on procB.
   *
   * Functions that require a lock held on entry indicate which lock
   * in the suffix of the function name:
   *
   * foo_olocked() : requires node->outer_lock
   * foo_nlocked() : requires node->lock
   * foo_ilocked() : requires proc->inner_lock
   * foo_oilocked(): requires proc->outer_lock and proc->inner_lock
   * foo_nilocked(): requires node->lock and proc->inner_lock
   * ...
   */
56b468fc7   Anmol Sarma   Staging: android:...
50
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
51
52
53
  #include <asm/cacheflush.h>
  #include <linux/fdtable.h>
  #include <linux/file.h>
e2610b268   Colin Cross   binder: use freez...
54
  #include <linux/freezer.h>
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
55
56
57
  #include <linux/fs.h>
  #include <linux/list.h>
  #include <linux/miscdevice.h>
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
58
59
60
61
  #include <linux/module.h>
  #include <linux/mutex.h>
  #include <linux/nsproxy.h>
  #include <linux/poll.h>
16b665543   Arve Hjønnevåg   staging: android:...
62
  #include <linux/debugfs.h>
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
63
  #include <linux/rbtree.h>
3f07c0144   Ingo Molnar   sched/headers: Pr...
64
  #include <linux/sched/signal.h>
6e84f3152   Ingo Molnar   sched/headers: Pr...
65
  #include <linux/sched/mm.h>
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
66
  #include <linux/seq_file.h>
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
67
  #include <linux/uaccess.h>
17cf22c33   Eric W. Biederman   pidns: Use task_a...
68
  #include <linux/pid_namespace.h>
79af73079   Stephen Smalley   Add security hook...
69
  #include <linux/security.h>
9630fe883   Todd Kjos   binder: introduce...
70
  #include <linux/spinlock.h>
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
71

9246a4a98   Greg Kroah-Hartman   android: binder: ...
72
73
74
75
76
  #ifdef CONFIG_ANDROID_BINDER_IPC_32BIT
  #define BINDER_IPC_32BIT 1
  #endif
  
  #include <uapi/linux/android/binder.h>
0c972a05c   Todd Kjos   binder: move bind...
77
  #include "binder_alloc.h"
975a1ac9a   Arve Hjønnevåg   Staging: android:...
78
  #include "binder_trace.h"
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
79

c44b1231f   Todd Kjos   binder: add prote...
80
  static HLIST_HEAD(binder_deferred_list);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
81
  static DEFINE_MUTEX(binder_deferred_lock);
ac4812c5f   Martijn Coenen   binder: Support m...
82
  static HLIST_HEAD(binder_devices);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
83
  static HLIST_HEAD(binder_procs);
c44b1231f   Todd Kjos   binder: add prote...
84
  static DEFINE_MUTEX(binder_procs_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
85
  static HLIST_HEAD(binder_dead_nodes);
c44b1231f   Todd Kjos   binder: add prote...
86
  static DEFINE_SPINLOCK(binder_dead_nodes_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
87

16b665543   Arve Hjønnevåg   staging: android:...
88
89
  static struct dentry *binder_debugfs_dir_entry_root;
  static struct dentry *binder_debugfs_dir_entry_proc;
656a800aa   Todd Kjos   binder: make bind...
90
  static atomic_t binder_last_id;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
91

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
92
93
94
  #define BINDER_DEBUG_ENTRY(name) \
  static int binder_##name##_open(struct inode *inode, struct file *file) \
  { \
16b665543   Arve Hjønnevåg   staging: android:...
95
  	return single_open(file, binder_##name##_show, inode->i_private); \
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
96
97
98
99
100
101
102
103
104
105
106
107
  } \
  \
  static const struct file_operations binder_##name##_fops = { \
  	.owner = THIS_MODULE, \
  	.open = binder_##name##_open, \
  	.read = seq_read, \
  	.llseek = seq_lseek, \
  	.release = single_release, \
  }
  
  static int binder_proc_show(struct seq_file *m, void *unused);
  BINDER_DEBUG_ENTRY(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
108
109
110
111
112
113
114
115
116
117
118
  
  /* This is only defined in include/asm-arm/sizes.h */
  #ifndef SZ_1K
  #define SZ_1K                               0x400
  #endif
  
  #ifndef SZ_4M
  #define SZ_4M                               0x400000
  #endif
  
  #define FORBIDDEN_MMAP_FLAGS                (VM_WRITE)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
119
120
121
122
123
124
125
126
127
128
129
130
131
132
  enum {
  	BINDER_DEBUG_USER_ERROR             = 1U << 0,
  	BINDER_DEBUG_FAILED_TRANSACTION     = 1U << 1,
  	BINDER_DEBUG_DEAD_TRANSACTION       = 1U << 2,
  	BINDER_DEBUG_OPEN_CLOSE             = 1U << 3,
  	BINDER_DEBUG_DEAD_BINDER            = 1U << 4,
  	BINDER_DEBUG_DEATH_NOTIFICATION     = 1U << 5,
  	BINDER_DEBUG_READ_WRITE             = 1U << 6,
  	BINDER_DEBUG_USER_REFS              = 1U << 7,
  	BINDER_DEBUG_THREADS                = 1U << 8,
  	BINDER_DEBUG_TRANSACTION            = 1U << 9,
  	BINDER_DEBUG_TRANSACTION_COMPLETE   = 1U << 10,
  	BINDER_DEBUG_FREE_BUFFER            = 1U << 11,
  	BINDER_DEBUG_INTERNAL_REFS          = 1U << 12,
19c987241   Todd Kjos   binder: separate ...
133
  	BINDER_DEBUG_PRIORITY_CAP           = 1U << 13,
9630fe883   Todd Kjos   binder: introduce...
134
  	BINDER_DEBUG_SPINLOCKS              = 1U << 14,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
135
136
137
138
  };
  static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
  	BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
  module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
ac4812c5f   Martijn Coenen   binder: Support m...
139
140
  static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES;
  module_param_named(devices, binder_devices_param, charp, 0444);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
141
142
143
144
145
146
147
  static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait);
  static int binder_stop_on_user_error;
  
  static int binder_set_stop_on_user_error(const char *val,
  					 struct kernel_param *kp)
  {
  	int ret;
10f62861b   Seunghun Lee   staging: android:...
148

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
149
150
151
152
153
154
155
156
157
158
159
  	ret = param_set_int(val, kp);
  	if (binder_stop_on_user_error < 2)
  		wake_up(&binder_user_error_wait);
  	return ret;
  }
  module_param_call(stop_on_user_error, binder_set_stop_on_user_error,
  	param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO);
  
  #define binder_debug(mask, x...) \
  	do { \
  		if (binder_debug_mask & mask) \
258767fed   Sherwin Soltani   drivers: staging:...
160
  			pr_info(x); \
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
161
162
163
164
165
  	} while (0)
  
  #define binder_user_error(x...) \
  	do { \
  		if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \
258767fed   Sherwin Soltani   drivers: staging:...
166
  			pr_info(x); \
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
167
168
169
  		if (binder_stop_on_user_error) \
  			binder_stop_on_user_error = 2; \
  	} while (0)
feba3900c   Martijn Coenen   binder: Split fla...
170
171
172
173
  #define to_flat_binder_object(hdr) \
  	container_of(hdr, struct flat_binder_object, hdr)
  
  #define to_binder_fd_object(hdr) container_of(hdr, struct binder_fd_object, hdr)
7980240b6   Martijn Coenen   binder: Add suppo...
174
175
  #define to_binder_buffer_object(hdr) \
  	container_of(hdr, struct binder_buffer_object, hdr)
def95c735   Martijn Coenen   binder: Add suppo...
176
177
  #define to_binder_fd_array_object(hdr) \
  	container_of(hdr, struct binder_fd_array_object, hdr)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
178
179
180
181
182
183
184
185
186
187
188
189
  enum binder_stat_types {
  	BINDER_STAT_PROC,
  	BINDER_STAT_THREAD,
  	BINDER_STAT_NODE,
  	BINDER_STAT_REF,
  	BINDER_STAT_DEATH,
  	BINDER_STAT_TRANSACTION,
  	BINDER_STAT_TRANSACTION_COMPLETE,
  	BINDER_STAT_COUNT
  };
  
  struct binder_stats {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
190
191
192
193
  	atomic_t br[_IOC_NR(BR_FAILED_REPLY) + 1];
  	atomic_t bc[_IOC_NR(BC_REPLY_SG) + 1];
  	atomic_t obj_created[BINDER_STAT_COUNT];
  	atomic_t obj_deleted[BINDER_STAT_COUNT];
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
194
195
196
197
198
199
  };
  
  static struct binder_stats binder_stats;
  
  static inline void binder_stats_deleted(enum binder_stat_types type)
  {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
200
  	atomic_inc(&binder_stats.obj_deleted[type]);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
201
202
203
204
  }
  
  static inline void binder_stats_created(enum binder_stat_types type)
  {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
205
  	atomic_inc(&binder_stats.obj_created[type]);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
206
207
208
209
  }
  
  struct binder_transaction_log_entry {
  	int debug_id;
d99c7333a   Todd Kjos   binder: use atomi...
210
  	int debug_id_done;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
211
212
213
214
215
216
217
218
219
  	int call_type;
  	int from_proc;
  	int from_thread;
  	int target_handle;
  	int to_proc;
  	int to_thread;
  	int to_node;
  	int data_size;
  	int offsets_size;
57ada2fb2   Todd Kjos   binder: add log i...
220
221
222
  	int return_error_line;
  	uint32_t return_error;
  	uint32_t return_error_param;
14db31814   Martijn Coenen   binder: Deal with...
223
  	const char *context_name;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
224
225
  };
  struct binder_transaction_log {
d99c7333a   Todd Kjos   binder: use atomi...
226
227
  	atomic_t cur;
  	bool full;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
228
229
230
231
232
233
234
235
236
  	struct binder_transaction_log_entry entry[32];
  };
  static struct binder_transaction_log binder_transaction_log;
  static struct binder_transaction_log binder_transaction_log_failed;
  
  static struct binder_transaction_log_entry *binder_transaction_log_add(
  	struct binder_transaction_log *log)
  {
  	struct binder_transaction_log_entry *e;
d99c7333a   Todd Kjos   binder: use atomi...
237
  	unsigned int cur = atomic_inc_return(&log->cur);
10f62861b   Seunghun Lee   staging: android:...
238

d99c7333a   Todd Kjos   binder: use atomi...
239
  	if (cur >= ARRAY_SIZE(log->entry))
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
240
  		log->full = 1;
d99c7333a   Todd Kjos   binder: use atomi...
241
242
243
244
245
246
247
248
249
  	e = &log->entry[cur % ARRAY_SIZE(log->entry)];
  	WRITE_ONCE(e->debug_id_done, 0);
  	/*
  	 * write-barrier to synchronize access to e->debug_id_done.
  	 * We make sure the initialized 0 value is seen before
  	 * memset() other fields are zeroed by memset.
  	 */
  	smp_wmb();
  	memset(e, 0, sizeof(*e));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
250
251
  	return e;
  }
342e5c90b   Martijn Coenen   binder: Support m...
252
253
  struct binder_context {
  	struct binder_node *binder_context_mgr_node;
c44b1231f   Todd Kjos   binder: add prote...
254
  	struct mutex context_mgr_node_lock;
342e5c90b   Martijn Coenen   binder: Support m...
255
  	kuid_t binder_context_mgr_uid;
14db31814   Martijn Coenen   binder: Deal with...
256
  	const char *name;
342e5c90b   Martijn Coenen   binder: Support m...
257
  };
ac4812c5f   Martijn Coenen   binder: Support m...
258
259
260
261
  struct binder_device {
  	struct hlist_node hlist;
  	struct miscdevice miscdev;
  	struct binder_context context;
342e5c90b   Martijn Coenen   binder: Support m...
262
  };
72196393a   Todd Kjos   binder: add spinl...
263
264
265
266
267
268
269
  /**
   * struct binder_work - work enqueued on a worklist
   * @entry:             node enqueued on list
   * @type:              type of work to be performed
   *
   * There are separate work lists for proc, thread, and node (async).
   */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
270
271
  struct binder_work {
  	struct list_head entry;
72196393a   Todd Kjos   binder: add spinl...
272

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
273
274
275
  	enum {
  		BINDER_WORK_TRANSACTION = 1,
  		BINDER_WORK_TRANSACTION_COMPLETE,
26549d177   Todd Kjos   binder: guarantee...
276
  		BINDER_WORK_RETURN_ERROR,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
277
278
279
280
281
282
  		BINDER_WORK_NODE,
  		BINDER_WORK_DEAD_BINDER,
  		BINDER_WORK_DEAD_BINDER_AND_CLEAR,
  		BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
  	} type;
  };
26549d177   Todd Kjos   binder: guarantee...
283
284
285
286
  struct binder_error {
  	struct binder_work work;
  	uint32_t cmd;
  };
9630fe883   Todd Kjos   binder: introduce...
287
288
289
290
291
292
  /**
   * struct binder_node - binder node bookkeeping
   * @debug_id:             unique ID for debugging
   *                        (invariant after initialized)
   * @lock:                 lock for node fields
   * @work:                 worklist element for node work
72196393a   Todd Kjos   binder: add spinl...
293
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
294
   * @rb_node:              element for proc->nodes tree
da0fa9e4e   Todd Kjos   binder: protect p...
295
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
296
297
298
299
300
   * @dead_node:            element for binder_dead_nodes list
   *                        (protected by binder_dead_nodes_lock)
   * @proc:                 binder_proc that owns this node
   *                        (invariant after initialized)
   * @refs:                 list of references on this node
673068eee   Todd Kjos   binder: add spinl...
301
   *                        (protected by @lock)
9630fe883   Todd Kjos   binder: introduce...
302
303
   * @internal_strong_refs: used to take strong references when
   *                        initiating a transaction
ed29721e2   Todd Kjos   binder: use inner...
304
305
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
306
   * @local_weak_refs:      weak user refs from local process
ed29721e2   Todd Kjos   binder: use inner...
307
308
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
309
   * @local_strong_refs:    strong user refs from local process
ed29721e2   Todd Kjos   binder: use inner...
310
311
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
312
   * @tmp_refs:             temporary kernel refs
ed29721e2   Todd Kjos   binder: use inner...
313
314
315
316
317
   *                        (protected by @proc->inner_lock while @proc
   *                        is valid, and by binder_dead_nodes_lock
   *                        if @proc is NULL. During inc/dec and node release
   *                        it is also protected by @lock to provide safety
   *                        as the node dies and @proc becomes NULL)
9630fe883   Todd Kjos   binder: introduce...
318
319
320
321
322
   * @ptr:                  userspace pointer for node
   *                        (invariant, no lock needed)
   * @cookie:               userspace cookie for node
   *                        (invariant, no lock needed)
   * @has_strong_ref:       userspace notified of strong ref
ed29721e2   Todd Kjos   binder: use inner...
323
324
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
325
   * @pending_strong_ref:   userspace has acked notification of strong ref
ed29721e2   Todd Kjos   binder: use inner...
326
327
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
328
   * @has_weak_ref:         userspace notified of weak ref
ed29721e2   Todd Kjos   binder: use inner...
329
330
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
331
   * @pending_weak_ref:     userspace has acked notification of weak ref
ed29721e2   Todd Kjos   binder: use inner...
332
333
   *                        (protected by @proc->inner_lock if @proc
   *                        and by @lock)
9630fe883   Todd Kjos   binder: introduce...
334
   * @has_async_transaction: async transaction to node in progress
673068eee   Todd Kjos   binder: add spinl...
335
   *                        (protected by @lock)
9630fe883   Todd Kjos   binder: introduce...
336
337
338
339
340
   * @accept_fds:           file descriptor operations supported for node
   *                        (invariant after initialized)
   * @min_priority:         minimum scheduling priority
   *                        (invariant after initialized)
   * @async_todo:           list of async work items
72196393a   Todd Kjos   binder: add spinl...
341
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
342
343
344
   *
   * Bookkeeping structure for binder nodes.
   */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
345
346
  struct binder_node {
  	int debug_id;
9630fe883   Todd Kjos   binder: introduce...
347
  	spinlock_t lock;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
348
349
350
351
352
353
354
355
356
357
  	struct binder_work work;
  	union {
  		struct rb_node rb_node;
  		struct hlist_node dead_node;
  	};
  	struct binder_proc *proc;
  	struct hlist_head refs;
  	int internal_strong_refs;
  	int local_weak_refs;
  	int local_strong_refs;
adc188422   Todd Kjos   binder: use node-...
358
  	int tmp_refs;
da49889de   Arve Hjønnevåg   staging: binder: ...
359
360
  	binder_uintptr_t ptr;
  	binder_uintptr_t cookie;
ed29721e2   Todd Kjos   binder: use inner...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  	struct {
  		/*
  		 * bitfield elements protected by
  		 * proc inner_lock
  		 */
  		u8 has_strong_ref:1;
  		u8 pending_strong_ref:1;
  		u8 has_weak_ref:1;
  		u8 pending_weak_ref:1;
  	};
  	struct {
  		/*
  		 * invariant after initialization
  		 */
  		u8 accept_fds:1;
  		u8 min_priority;
  	};
  	bool has_async_transaction;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
379
380
381
382
  	struct list_head async_todo;
  };
  
  struct binder_ref_death {
72196393a   Todd Kjos   binder: add spinl...
383
384
385
386
387
  	/**
  	 * @work: worklist element for death notifications
  	 *        (protected by inner_lock of the proc that
  	 *        this ref belongs to)
  	 */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
388
  	struct binder_work work;
da49889de   Arve Hjønnevåg   staging: binder: ...
389
  	binder_uintptr_t cookie;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
390
  };
372e3147d   Todd Kjos   binder: refactor ...
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  /**
   * struct binder_ref_data - binder_ref counts and id
   * @debug_id:        unique ID for the ref
   * @desc:            unique userspace handle for ref
   * @strong:          strong ref count (debugging only if not locked)
   * @weak:            weak ref count (debugging only if not locked)
   *
   * Structure to hold ref count and ref id information. Since
   * the actual ref can only be accessed with a lock, this structure
   * is used to return information about the ref to callers of
   * ref inc/dec functions.
   */
  struct binder_ref_data {
  	int debug_id;
  	uint32_t desc;
  	int strong;
  	int weak;
  };
  
  /**
   * struct binder_ref - struct to track references on nodes
   * @data:        binder_ref_data containing id, handle, and current refcounts
   * @rb_node_desc: node for lookup by @data.desc in proc's rb_tree
   * @rb_node_node: node for lookup by @node in proc's rb_tree
   * @node_entry:  list entry for node->refs list in target node
673068eee   Todd Kjos   binder: add spinl...
416
   *               (protected by @node->lock)
372e3147d   Todd Kjos   binder: refactor ...
417
418
419
420
421
   * @proc:        binder_proc containing ref
   * @node:        binder_node of target node. When cleaning up a
   *               ref for deletion in binder_cleanup_ref, a non-NULL
   *               @node indicates the node must be freed
   * @death:       pointer to death notification (ref_death) if requested
ab51ec6bd   Martijn Coenen   binder: fix death...
422
   *               (protected by @node->lock)
372e3147d   Todd Kjos   binder: refactor ...
423
424
425
426
   *
   * Structure to track references from procA to target node (on procB). This
   * structure is unsafe to access without holding @proc->outer_lock.
   */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
427
428
429
430
431
  struct binder_ref {
  	/* Lookups needed: */
  	/*   node + proc => ref (transaction) */
  	/*   desc + proc => ref (transaction, inc/dec ref) */
  	/*   node => refs + procs (proc exit) */
372e3147d   Todd Kjos   binder: refactor ...
432
  	struct binder_ref_data data;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
433
434
435
436
437
  	struct rb_node rb_node_desc;
  	struct rb_node rb_node_node;
  	struct hlist_node node_entry;
  	struct binder_proc *proc;
  	struct binder_node *node;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
438
439
  	struct binder_ref_death *death;
  };
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
440
441
442
443
444
  enum binder_deferred_state {
  	BINDER_DEFERRED_PUT_FILES    = 0x01,
  	BINDER_DEFERRED_FLUSH        = 0x02,
  	BINDER_DEFERRED_RELEASE      = 0x04,
  };
9630fe883   Todd Kjos   binder: introduce...
445
446
447
448
  /**
   * struct binder_proc - binder process bookkeeping
   * @proc_node:            element for binder_procs list
   * @threads:              rbtree of binder_threads in this proc
7bd7b0e63   Todd Kjos   binder: protect p...
449
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
450
451
   * @nodes:                rbtree of binder nodes associated with
   *                        this proc ordered by node->ptr
da0fa9e4e   Todd Kjos   binder: protect p...
452
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
453
   * @refs_by_desc:         rbtree of refs ordered by ref->desc
2c1838dc6   Todd Kjos   binder: protect b...
454
   *                        (protected by @outer_lock)
9630fe883   Todd Kjos   binder: introduce...
455
   * @refs_by_node:         rbtree of refs ordered by ref->node
2c1838dc6   Todd Kjos   binder: protect b...
456
   *                        (protected by @outer_lock)
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
457
458
   * @waiting_threads:      threads currently waiting for proc work
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
459
460
461
462
463
   * @pid                   PID of group_leader of process
   *                        (invariant after initialized)
   * @tsk                   task_struct for group_leader of process
   *                        (invariant after initialized)
   * @files                 files_struct for process
d87f1bc7d   Todd Kjos   binder: fix proc-...
464
465
   *                        (protected by @files_lock)
   * @files_lock            mutex to protect @files
9630fe883   Todd Kjos   binder: introduce...
466
467
468
469
470
471
   * @deferred_work_node:   element for binder_deferred_list
   *                        (protected by binder_deferred_lock)
   * @deferred_work:        bitmap of deferred work to perform
   *                        (protected by binder_deferred_lock)
   * @is_dead:              process is dead and awaiting free
   *                        when outstanding transactions are cleaned up
7bd7b0e63   Todd Kjos   binder: protect p...
472
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
473
   * @todo:                 list of work for this process
72196393a   Todd Kjos   binder: add spinl...
474
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
475
476
477
478
479
   * @wait:                 wait queue head to wait for proc work
   *                        (invariant after initialized)
   * @stats:                per-process binder statistics
   *                        (atomics, no lock needed)
   * @delivered_death:      list of delivered death notification
72196393a   Todd Kjos   binder: add spinl...
480
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
481
   * @max_threads:          cap on number of binder threads
b3e686128   Todd Kjos   binder: use inner...
482
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
483
484
485
   * @requested_threads:    number of binder threads requested but not
   *                        yet started. In current implementation, can
   *                        only be 0 or 1.
b3e686128   Todd Kjos   binder: use inner...
486
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
487
   * @requested_threads_started: number binder threads started
b3e686128   Todd Kjos   binder: use inner...
488
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
489
   * @tmp_ref:              temporary reference to indicate proc is in use
7bd7b0e63   Todd Kjos   binder: protect p...
490
   *                        (protected by @inner_lock)
9630fe883   Todd Kjos   binder: introduce...
491
492
493
494
495
496
497
498
499
500
501
502
   * @default_priority:     default scheduler priority
   *                        (invariant after initialized)
   * @debugfs_entry:        debugfs node
   * @alloc:                binder allocator bookkeeping
   * @context:              binder_context for this proc
   *                        (invariant after initialized)
   * @inner_lock:           can nest under outer_lock and/or node lock
   * @outer_lock:           no nesting under innor or node lock
   *                        Lock order: 1) outer, 2) node, 3) inner
   *
   * Bookkeeping structure for binder processes
   */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
503
504
505
506
507
508
  struct binder_proc {
  	struct hlist_node proc_node;
  	struct rb_root threads;
  	struct rb_root nodes;
  	struct rb_root refs_by_desc;
  	struct rb_root refs_by_node;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
509
  	struct list_head waiting_threads;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
510
  	int pid;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
511
512
  	struct task_struct *tsk;
  	struct files_struct *files;
d87f1bc7d   Todd Kjos   binder: fix proc-...
513
  	struct mutex files_lock;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
514
515
  	struct hlist_node deferred_work_node;
  	int deferred_work;
7a4408c6b   Todd Kjos   binder: make sure...
516
  	bool is_dead;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
517

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
518
519
520
521
522
523
524
  	struct list_head todo;
  	wait_queue_head_t wait;
  	struct binder_stats stats;
  	struct list_head delivered_death;
  	int max_threads;
  	int requested_threads;
  	int requested_threads_started;
7a4408c6b   Todd Kjos   binder: make sure...
525
  	int tmp_ref;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
526
  	long default_priority;
16b665543   Arve Hjønnevåg   staging: android:...
527
  	struct dentry *debugfs_entry;
fdfb4a99b   Todd Kjos   binder: separate ...
528
  	struct binder_alloc alloc;
342e5c90b   Martijn Coenen   binder: Support m...
529
  	struct binder_context *context;
9630fe883   Todd Kjos   binder: introduce...
530
531
  	spinlock_t inner_lock;
  	spinlock_t outer_lock;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
532
533
534
535
536
537
538
539
  };
  
  enum {
  	BINDER_LOOPER_STATE_REGISTERED  = 0x01,
  	BINDER_LOOPER_STATE_ENTERED     = 0x02,
  	BINDER_LOOPER_STATE_EXITED      = 0x04,
  	BINDER_LOOPER_STATE_INVALID     = 0x08,
  	BINDER_LOOPER_STATE_WAITING     = 0x10,
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
540
  	BINDER_LOOPER_STATE_POLL        = 0x20,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
541
  };
9630fe883   Todd Kjos   binder: introduce...
542
543
544
545
546
  /**
   * struct binder_thread - binder thread bookkeeping
   * @proc:                 binder process for this thread
   *                        (invariant after initialization)
   * @rb_node:              element for proc->threads rbtree
7bd7b0e63   Todd Kjos   binder: protect p...
547
   *                        (protected by @proc->inner_lock)
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
548
549
   * @waiting_thread_node:  element for @proc->waiting_threads list
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
550
551
552
553
554
555
556
   * @pid:                  PID for this thread
   *                        (invariant after initialization)
   * @looper:               bitmap of looping state
   *                        (only accessed by this thread)
   * @looper_needs_return:  looping thread needs to exit driver
   *                        (no lock needed)
   * @transaction_stack:    stack of in-progress transactions for this thread
0b89d69a9   Martijn Coenen   binder: protect t...
557
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
558
   * @todo:                 list of work to do for this thread
72196393a   Todd Kjos   binder: add spinl...
559
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
560
561
562
   * @return_error:         transaction errors reported by this thread
   *                        (only accessed by this thread)
   * @reply_error:          transaction errors reported by target thread
0b89d69a9   Martijn Coenen   binder: protect t...
563
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
564
565
566
567
568
569
570
571
   * @wait:                 wait queue for thread work
   * @stats:                per-thread statistics
   *                        (atomics, no lock needed)
   * @tmp_ref:              temporary reference to indicate thread is in use
   *                        (atomic since @proc->inner_lock cannot
   *                        always be acquired)
   * @is_dead:              thread is dead and awaiting free
   *                        when outstanding transactions are cleaned up
7bd7b0e63   Todd Kjos   binder: protect p...
572
   *                        (protected by @proc->inner_lock)
9630fe883   Todd Kjos   binder: introduce...
573
574
575
   *
   * Bookkeeping structure for binder threads.
   */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
576
577
578
  struct binder_thread {
  	struct binder_proc *proc;
  	struct rb_node rb_node;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
579
  	struct list_head waiting_thread_node;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
580
  	int pid;
08dabceef   Todd Kjos   binder: don't mod...
581
582
  	int looper;              /* only modified by this thread */
  	bool looper_need_return; /* can be written by other thread */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
583
584
  	struct binder_transaction *transaction_stack;
  	struct list_head todo;
26549d177   Todd Kjos   binder: guarantee...
585
586
  	struct binder_error return_error;
  	struct binder_error reply_error;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
587
588
  	wait_queue_head_t wait;
  	struct binder_stats stats;
7a4408c6b   Todd Kjos   binder: make sure...
589
590
  	atomic_t tmp_ref;
  	bool is_dead;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
  };
  
  struct binder_transaction {
  	int debug_id;
  	struct binder_work work;
  	struct binder_thread *from;
  	struct binder_transaction *from_parent;
  	struct binder_proc *to_proc;
  	struct binder_thread *to_thread;
  	struct binder_transaction *to_parent;
  	unsigned need_reply:1;
  	/* unsigned is_dead:1; */	/* not used at the moment */
  
  	struct binder_buffer *buffer;
  	unsigned int	code;
  	unsigned int	flags;
  	long	priority;
  	long	saved_priority;
4a2ebb93b   Eric W. Biederman   userns: Convert b...
609
  	kuid_t	sender_euid;
7a4408c6b   Todd Kjos   binder: make sure...
610
611
612
613
614
615
616
  	/**
  	 * @lock:  protects @from, @to_proc, and @to_thread
  	 *
  	 * @from, @to_proc, and @to_thread can be set to NULL
  	 * during thread teardown
  	 */
  	spinlock_t lock;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
617
  };
9630fe883   Todd Kjos   binder: introduce...
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
  /**
   * binder_proc_lock() - Acquire outer lock for given binder_proc
   * @proc:         struct binder_proc to acquire
   *
   * Acquires proc->outer_lock. Used to protect binder_ref
   * structures associated with the given proc.
   */
  #define binder_proc_lock(proc) _binder_proc_lock(proc, __LINE__)
  static void
  _binder_proc_lock(struct binder_proc *proc, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_lock(&proc->outer_lock);
  }
  
  /**
   * binder_proc_unlock() - Release spinlock for given binder_proc
   * @proc:         struct binder_proc to acquire
   *
   * Release lock acquired via binder_proc_lock()
   */
  #define binder_proc_unlock(_proc) _binder_proc_unlock(_proc, __LINE__)
  static void
  _binder_proc_unlock(struct binder_proc *proc, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_unlock(&proc->outer_lock);
  }
  
  /**
   * binder_inner_proc_lock() - Acquire inner lock for given binder_proc
   * @proc:         struct binder_proc to acquire
   *
   * Acquires proc->inner_lock. Used to protect todo lists
   */
  #define binder_inner_proc_lock(proc) _binder_inner_proc_lock(proc, __LINE__)
  static void
  _binder_inner_proc_lock(struct binder_proc *proc, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_lock(&proc->inner_lock);
  }
  
  /**
   * binder_inner_proc_unlock() - Release inner lock for given binder_proc
   * @proc:         struct binder_proc to acquire
   *
   * Release lock acquired via binder_inner_proc_lock()
   */
  #define binder_inner_proc_unlock(proc) _binder_inner_proc_unlock(proc, __LINE__)
  static void
  _binder_inner_proc_unlock(struct binder_proc *proc, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_unlock(&proc->inner_lock);
  }
  
  /**
   * binder_node_lock() - Acquire spinlock for given binder_node
   * @node:         struct binder_node to acquire
   *
   * Acquires node->lock. Used to protect binder_node fields
   */
  #define binder_node_lock(node) _binder_node_lock(node, __LINE__)
  static void
  _binder_node_lock(struct binder_node *node, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_lock(&node->lock);
  }
  
  /**
   * binder_node_unlock() - Release spinlock for given binder_proc
   * @node:         struct binder_node to acquire
   *
   * Release lock acquired via binder_node_lock()
   */
  #define binder_node_unlock(node) _binder_node_unlock(node, __LINE__)
  static void
  _binder_node_unlock(struct binder_node *node, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_unlock(&node->lock);
  }
673068eee   Todd Kjos   binder: add spinl...
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
  /**
   * binder_node_inner_lock() - Acquire node and inner locks
   * @node:         struct binder_node to acquire
   *
   * Acquires node->lock. If node->proc also acquires
   * proc->inner_lock. Used to protect binder_node fields
   */
  #define binder_node_inner_lock(node) _binder_node_inner_lock(node, __LINE__)
  static void
  _binder_node_inner_lock(struct binder_node *node, int line)
  {
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	spin_lock(&node->lock);
  	if (node->proc)
  		binder_inner_proc_lock(node->proc);
  }
  
  /**
   * binder_node_unlock() - Release node and inner locks
   * @node:         struct binder_node to acquire
   *
   * Release lock acquired via binder_node_lock()
   */
  #define binder_node_inner_unlock(node) _binder_node_inner_unlock(node, __LINE__)
  static void
  _binder_node_inner_unlock(struct binder_node *node, int line)
  {
  	struct binder_proc *proc = node->proc;
  
  	binder_debug(BINDER_DEBUG_SPINLOCKS,
  		     "%s: line=%d
  ", __func__, line);
  	if (proc)
  		binder_inner_proc_unlock(proc);
  	spin_unlock(&node->lock);
  }
72196393a   Todd Kjos   binder: add spinl...
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
  static bool binder_worklist_empty_ilocked(struct list_head *list)
  {
  	return list_empty(list);
  }
  
  /**
   * binder_worklist_empty() - Check if no items on the work list
   * @proc:       binder_proc associated with list
   * @list:	list to check
   *
   * Return: true if there are no items on list, else false
   */
  static bool binder_worklist_empty(struct binder_proc *proc,
  				  struct list_head *list)
  {
  	bool ret;
  
  	binder_inner_proc_lock(proc);
  	ret = binder_worklist_empty_ilocked(list);
  	binder_inner_proc_unlock(proc);
  	return ret;
  }
  
  static void
  binder_enqueue_work_ilocked(struct binder_work *work,
  			   struct list_head *target_list)
  {
  	BUG_ON(target_list == NULL);
  	BUG_ON(work->entry.next && !list_empty(&work->entry));
  	list_add_tail(&work->entry, target_list);
  }
  
  /**
   * binder_enqueue_work() - Add an item to the work list
   * @proc:         binder_proc associated with list
   * @work:         struct binder_work to add to list
   * @target_list:  list to add work to
   *
   * Adds the work to the specified list. Asserts that work
   * is not already on a list.
   */
  static void
  binder_enqueue_work(struct binder_proc *proc,
  		    struct binder_work *work,
  		    struct list_head *target_list)
  {
  	binder_inner_proc_lock(proc);
  	binder_enqueue_work_ilocked(work, target_list);
  	binder_inner_proc_unlock(proc);
  }
  
  static void
  binder_dequeue_work_ilocked(struct binder_work *work)
  {
  	list_del_init(&work->entry);
  }
  
  /**
   * binder_dequeue_work() - Removes an item from the work list
   * @proc:         binder_proc associated with list
   * @work:         struct binder_work to remove from list
   *
   * Removes the specified work item from whatever list it is on.
   * Can safely be called if work is not on any list.
   */
  static void
  binder_dequeue_work(struct binder_proc *proc, struct binder_work *work)
  {
  	binder_inner_proc_lock(proc);
  	binder_dequeue_work_ilocked(work);
  	binder_inner_proc_unlock(proc);
  }
  
  static struct binder_work *binder_dequeue_work_head_ilocked(
  					struct list_head *list)
  {
  	struct binder_work *w;
  
  	w = list_first_entry_or_null(list, struct binder_work, entry);
  	if (w)
  		list_del_init(&w->entry);
  	return w;
  }
  
  /**
   * binder_dequeue_work_head() - Dequeues the item at head of list
   * @proc:         binder_proc associated with list
   * @list:         list to dequeue head
   *
   * Removes the head of the list if there are items on the list
   *
   * Return: pointer dequeued binder_work, NULL if list was empty
   */
  static struct binder_work *binder_dequeue_work_head(
  					struct binder_proc *proc,
  					struct list_head *list)
  {
  	struct binder_work *w;
  
  	binder_inner_proc_lock(proc);
  	w = binder_dequeue_work_head_ilocked(list);
  	binder_inner_proc_unlock(proc);
  	return w;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
856
857
  static void
  binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer);
7a4408c6b   Todd Kjos   binder: make sure...
858
859
  static void binder_free_thread(struct binder_thread *thread);
  static void binder_free_proc(struct binder_proc *proc);
da0fa9e4e   Todd Kjos   binder: protect p...
860
  static void binder_inc_node_tmpref_ilocked(struct binder_node *node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
861

efde99cd2   Sachin Kamat   Staging: android:...
862
  static int task_get_unused_fd_flags(struct binder_proc *proc, int flags)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
863
  {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
864
865
  	unsigned long rlim_cur;
  	unsigned long irqs;
d87f1bc7d   Todd Kjos   binder: fix proc-...
866
  	int ret;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
867

d87f1bc7d   Todd Kjos   binder: fix proc-...
868
869
870
871
872
873
874
875
876
  	mutex_lock(&proc->files_lock);
  	if (proc->files == NULL) {
  		ret = -ESRCH;
  		goto err;
  	}
  	if (!lock_task_sighand(proc->tsk, &irqs)) {
  		ret = -EMFILE;
  		goto err;
  	}
dcfadfa4e   Al Viro   new helper: __all...
877
878
  	rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE);
  	unlock_task_sighand(proc->tsk, &irqs);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
879

d87f1bc7d   Todd Kjos   binder: fix proc-...
880
881
882
883
  	ret = __alloc_fd(proc->files, 0, rlim_cur, flags);
  err:
  	mutex_unlock(&proc->files_lock);
  	return ret;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
884
885
886
887
888
889
890
891
  }
  
  /*
   * copied from fd_install
   */
  static void task_fd_install(
  	struct binder_proc *proc, unsigned int fd, struct file *file)
  {
d87f1bc7d   Todd Kjos   binder: fix proc-...
892
  	mutex_lock(&proc->files_lock);
f869e8a7f   Al Viro   expose a low-leve...
893
894
  	if (proc->files)
  		__fd_install(proc->files, fd, file);
d87f1bc7d   Todd Kjos   binder: fix proc-...
895
  	mutex_unlock(&proc->files_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
896
897
898
899
900
901
902
  }
  
  /*
   * copied from sys_close
   */
  static long task_close_fd(struct binder_proc *proc, unsigned int fd)
  {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
903
  	int retval;
d87f1bc7d   Todd Kjos   binder: fix proc-...
904
905
906
907
908
  	mutex_lock(&proc->files_lock);
  	if (proc->files == NULL) {
  		retval = -ESRCH;
  		goto err;
  	}
483ce1d4b   Al Viro   take descriptor-r...
909
  	retval = __close_fd(proc->files, fd);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
910
911
912
913
914
915
  	/* can't restart close syscall because file table entry was cleared */
  	if (unlikely(retval == -ERESTARTSYS ||
  		     retval == -ERESTARTNOINTR ||
  		     retval == -ERESTARTNOHAND ||
  		     retval == -ERESTART_RESTARTBLOCK))
  		retval = -EINTR;
d87f1bc7d   Todd Kjos   binder: fix proc-...
916
917
  err:
  	mutex_unlock(&proc->files_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
918
  	return retval;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
919
  }
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
  static bool binder_has_work_ilocked(struct binder_thread *thread,
  				    bool do_proc_work)
  {
  	return !binder_worklist_empty_ilocked(&thread->todo) ||
  		thread->looper_need_return ||
  		(do_proc_work &&
  		 !binder_worklist_empty_ilocked(&thread->proc->todo));
  }
  
  static bool binder_has_work(struct binder_thread *thread, bool do_proc_work)
  {
  	bool has_work;
  
  	binder_inner_proc_lock(thread->proc);
  	has_work = binder_has_work_ilocked(thread, do_proc_work);
  	binder_inner_proc_unlock(thread->proc);
  
  	return has_work;
  }
  
  static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread)
  {
  	return !thread->transaction_stack &&
  		binder_worklist_empty_ilocked(&thread->todo) &&
  		(thread->looper & (BINDER_LOOPER_STATE_ENTERED |
  				   BINDER_LOOPER_STATE_REGISTERED));
  }
  
  static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc,
  					       bool sync)
  {
  	struct rb_node *n;
  	struct binder_thread *thread;
  
  	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
  		thread = rb_entry(n, struct binder_thread, rb_node);
  		if (thread->looper & BINDER_LOOPER_STATE_POLL &&
  		    binder_available_for_proc_work_ilocked(thread)) {
  			if (sync)
  				wake_up_interruptible_sync(&thread->wait);
  			else
  				wake_up_interruptible(&thread->wait);
  		}
  	}
  }
408c68b17   Martijn Coenen   ANDROID: binder: ...
965
966
967
968
969
970
971
972
973
974
975
976
977
978
  /**
   * binder_select_thread_ilocked() - selects a thread for doing proc work.
   * @proc:	process to select a thread from
   *
   * Note that calling this function moves the thread off the waiting_threads
   * list, so it can only be woken up by the caller of this function, or a
   * signal. Therefore, callers *should* always wake up the thread this function
   * returns.
   *
   * Return:	If there's a thread currently waiting for process work,
   *		returns that thread. Otherwise returns NULL.
   */
  static struct binder_thread *
  binder_select_thread_ilocked(struct binder_proc *proc)
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
979
980
  {
  	struct binder_thread *thread;
858b27196   Martijn Coenen   ANDROID: binder: ...
981
  	assert_spin_locked(&proc->inner_lock);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
982
983
984
  	thread = list_first_entry_or_null(&proc->waiting_threads,
  					  struct binder_thread,
  					  waiting_thread_node);
408c68b17   Martijn Coenen   ANDROID: binder: ...
985
  	if (thread)
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
986
  		list_del_init(&thread->waiting_thread_node);
408c68b17   Martijn Coenen   ANDROID: binder: ...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
  
  	return thread;
  }
  
  /**
   * binder_wakeup_thread_ilocked() - wakes up a thread for doing proc work.
   * @proc:	process to wake up a thread in
   * @thread:	specific thread to wake-up (may be NULL)
   * @sync:	whether to do a synchronous wake-up
   *
   * This function wakes up a thread in the @proc process.
   * The caller may provide a specific thread to wake-up in
   * the @thread parameter. If @thread is NULL, this function
   * will wake up threads that have called poll().
   *
   * Note that for this function to work as expected, callers
   * should first call binder_select_thread() to find a thread
   * to handle the work (if they don't have a thread already),
   * and pass the result into the @thread parameter.
   */
  static void binder_wakeup_thread_ilocked(struct binder_proc *proc,
  					 struct binder_thread *thread,
  					 bool sync)
  {
858b27196   Martijn Coenen   ANDROID: binder: ...
1011
  	assert_spin_locked(&proc->inner_lock);
408c68b17   Martijn Coenen   ANDROID: binder: ...
1012
1013
  
  	if (thread) {
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
  		if (sync)
  			wake_up_interruptible_sync(&thread->wait);
  		else
  			wake_up_interruptible(&thread->wait);
  		return;
  	}
  
  	/* Didn't find a thread waiting for proc work; this can happen
  	 * in two scenarios:
  	 * 1. All threads are busy handling transactions
  	 *    In that case, one of those threads should call back into
  	 *    the kernel driver soon and pick up this work.
  	 * 2. Threads are using the (e)poll interface, in which case
  	 *    they may be blocked on the waitqueue without having been
  	 *    added to waiting_threads. For this case, we just iterate
  	 *    over all threads not handling transaction work, and
  	 *    wake them all up. We wake all because we don't know whether
  	 *    a thread that called into (e)poll is handling non-binder
  	 *    work currently.
  	 */
  	binder_wakeup_poll_threads_ilocked(proc, sync);
  }
408c68b17   Martijn Coenen   ANDROID: binder: ...
1036
1037
1038
1039
1040
1041
  static void binder_wakeup_proc_ilocked(struct binder_proc *proc)
  {
  	struct binder_thread *thread = binder_select_thread_ilocked(proc);
  
  	binder_wakeup_thread_ilocked(proc, thread, /* sync = */false);
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1042
1043
1044
  static void binder_set_nice(long nice)
  {
  	long min_nice;
10f62861b   Seunghun Lee   staging: android:...
1045

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1046
1047
1048
1049
  	if (can_nice(current, nice)) {
  		set_user_nice(current, nice);
  		return;
  	}
c3643b699   Krzysztof Opasiak   android: binder: ...
1050
  	min_nice = rlimit_to_nice(rlimit(RLIMIT_NICE));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1051
  	binder_debug(BINDER_DEBUG_PRIORITY_CAP,
56b468fc7   Anmol Sarma   Staging: android:...
1052
1053
1054
  		     "%d: nice value %ld not allowed use %ld instead
  ",
  		      current->pid, nice, min_nice);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1055
  	set_user_nice(current, min_nice);
8698a745d   Dongsheng Yang   sched, treewide: ...
1056
  	if (min_nice <= MAX_NICE)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1057
  		return;
56b468fc7   Anmol Sarma   Staging: android:...
1058
1059
  	binder_user_error("%d RLIMIT_NICE not set
  ", current->pid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1060
  }
da0fa9e4e   Todd Kjos   binder: protect p...
1061
1062
  static struct binder_node *binder_get_node_ilocked(struct binder_proc *proc,
  						   binder_uintptr_t ptr)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1063
1064
1065
  {
  	struct rb_node *n = proc->nodes.rb_node;
  	struct binder_node *node;
858b27196   Martijn Coenen   ANDROID: binder: ...
1066
  	assert_spin_locked(&proc->inner_lock);
da0fa9e4e   Todd Kjos   binder: protect p...
1067

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1068
1069
1070
1071
1072
1073
1074
  	while (n) {
  		node = rb_entry(n, struct binder_node, rb_node);
  
  		if (ptr < node->ptr)
  			n = n->rb_left;
  		else if (ptr > node->ptr)
  			n = n->rb_right;
adc188422   Todd Kjos   binder: use node-...
1075
1076
1077
1078
1079
1080
  		else {
  			/*
  			 * take an implicit weak reference
  			 * to ensure node stays alive until
  			 * call to binder_put_node()
  			 */
da0fa9e4e   Todd Kjos   binder: protect p...
1081
  			binder_inc_node_tmpref_ilocked(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1082
  			return node;
adc188422   Todd Kjos   binder: use node-...
1083
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1084
1085
1086
  	}
  	return NULL;
  }
da0fa9e4e   Todd Kjos   binder: protect p...
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
  static struct binder_node *binder_get_node(struct binder_proc *proc,
  					   binder_uintptr_t ptr)
  {
  	struct binder_node *node;
  
  	binder_inner_proc_lock(proc);
  	node = binder_get_node_ilocked(proc, ptr);
  	binder_inner_proc_unlock(proc);
  	return node;
  }
  
  static struct binder_node *binder_init_node_ilocked(
  						struct binder_proc *proc,
  						struct binder_node *new_node,
  						struct flat_binder_object *fp)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1102
1103
1104
1105
  {
  	struct rb_node **p = &proc->nodes.rb_node;
  	struct rb_node *parent = NULL;
  	struct binder_node *node;
673068eee   Todd Kjos   binder: add spinl...
1106
1107
1108
  	binder_uintptr_t ptr = fp ? fp->binder : 0;
  	binder_uintptr_t cookie = fp ? fp->cookie : 0;
  	__u32 flags = fp ? fp->flags : 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1109

858b27196   Martijn Coenen   ANDROID: binder: ...
1110
  	assert_spin_locked(&proc->inner_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1111
  	while (*p) {
da0fa9e4e   Todd Kjos   binder: protect p...
1112

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1113
1114
1115
1116
1117
1118
1119
  		parent = *p;
  		node = rb_entry(parent, struct binder_node, rb_node);
  
  		if (ptr < node->ptr)
  			p = &(*p)->rb_left;
  		else if (ptr > node->ptr)
  			p = &(*p)->rb_right;
da0fa9e4e   Todd Kjos   binder: protect p...
1120
1121
1122
1123
1124
1125
1126
1127
1128
  		else {
  			/*
  			 * A matching node is already in
  			 * the rb tree. Abandon the init
  			 * and return it.
  			 */
  			binder_inc_node_tmpref_ilocked(node);
  			return node;
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1129
  	}
da0fa9e4e   Todd Kjos   binder: protect p...
1130
  	node = new_node;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1131
  	binder_stats_created(BINDER_STAT_NODE);
adc188422   Todd Kjos   binder: use node-...
1132
  	node->tmp_refs++;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1133
1134
  	rb_link_node(&node->rb_node, parent, p);
  	rb_insert_color(&node->rb_node, &proc->nodes);
656a800aa   Todd Kjos   binder: make bind...
1135
  	node->debug_id = atomic_inc_return(&binder_last_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1136
1137
1138
1139
  	node->proc = proc;
  	node->ptr = ptr;
  	node->cookie = cookie;
  	node->work.type = BINDER_WORK_NODE;
673068eee   Todd Kjos   binder: add spinl...
1140
1141
  	node->min_priority = flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
  	node->accept_fds = !!(flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
9630fe883   Todd Kjos   binder: introduce...
1142
  	spin_lock_init(&node->lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1143
1144
1145
  	INIT_LIST_HEAD(&node->work.entry);
  	INIT_LIST_HEAD(&node->async_todo);
  	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
da49889de   Arve Hjønnevåg   staging: binder: ...
1146
1147
  		     "%d:%d node %d u%016llx c%016llx created
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1148
  		     proc->pid, current->pid, node->debug_id,
da49889de   Arve Hjønnevåg   staging: binder: ...
1149
  		     (u64)node->ptr, (u64)node->cookie);
da0fa9e4e   Todd Kjos   binder: protect p...
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  
  	return node;
  }
  
  static struct binder_node *binder_new_node(struct binder_proc *proc,
  					   struct flat_binder_object *fp)
  {
  	struct binder_node *node;
  	struct binder_node *new_node = kzalloc(sizeof(*node), GFP_KERNEL);
  
  	if (!new_node)
  		return NULL;
  	binder_inner_proc_lock(proc);
  	node = binder_init_node_ilocked(proc, new_node, fp);
  	binder_inner_proc_unlock(proc);
  	if (node != new_node)
  		/*
  		 * The node was already added by another thread
  		 */
  		kfree(new_node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1170
1171
  	return node;
  }
ed29721e2   Todd Kjos   binder: use inner...
1172
  static void binder_free_node(struct binder_node *node)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1173
  {
ed29721e2   Todd Kjos   binder: use inner...
1174
1175
1176
  	kfree(node);
  	binder_stats_deleted(BINDER_STAT_NODE);
  }
673068eee   Todd Kjos   binder: add spinl...
1177
1178
1179
  static int binder_inc_node_nilocked(struct binder_node *node, int strong,
  				    int internal,
  				    struct list_head *target_list)
ed29721e2   Todd Kjos   binder: use inner...
1180
  {
673068eee   Todd Kjos   binder: add spinl...
1181
  	struct binder_proc *proc = node->proc;
858b27196   Martijn Coenen   ANDROID: binder: ...
1182
  	assert_spin_locked(&node->lock);
673068eee   Todd Kjos   binder: add spinl...
1183
  	if (proc)
858b27196   Martijn Coenen   ANDROID: binder: ...
1184
  		assert_spin_locked(&proc->inner_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1185
1186
1187
1188
  	if (strong) {
  		if (internal) {
  			if (target_list == NULL &&
  			    node->internal_strong_refs == 0 &&
342e5c90b   Martijn Coenen   binder: Support m...
1189
1190
1191
  			    !(node->proc &&
  			      node == node->proc->context->binder_context_mgr_node &&
  			      node->has_strong_ref)) {
56b468fc7   Anmol Sarma   Staging: android:...
1192
1193
1194
  				pr_err("invalid inc strong node for %d
  ",
  					node->debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1195
1196
1197
1198
1199
1200
  				return -EINVAL;
  			}
  			node->internal_strong_refs++;
  		} else
  			node->local_strong_refs++;
  		if (!node->has_strong_ref && target_list) {
72196393a   Todd Kjos   binder: add spinl...
1201
1202
  			binder_dequeue_work_ilocked(&node->work);
  			binder_enqueue_work_ilocked(&node->work, target_list);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1203
1204
1205
1206
1207
1208
  		}
  	} else {
  		if (!internal)
  			node->local_weak_refs++;
  		if (!node->has_weak_ref && list_empty(&node->work.entry)) {
  			if (target_list == NULL) {
56b468fc7   Anmol Sarma   Staging: android:...
1209
1210
1211
  				pr_err("invalid inc weak node for %d
  ",
  					node->debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1212
1213
  				return -EINVAL;
  			}
72196393a   Todd Kjos   binder: add spinl...
1214
  			binder_enqueue_work_ilocked(&node->work, target_list);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1215
1216
1217
1218
  		}
  	}
  	return 0;
  }
ed29721e2   Todd Kjos   binder: use inner...
1219
1220
1221
1222
  static int binder_inc_node(struct binder_node *node, int strong, int internal,
  			   struct list_head *target_list)
  {
  	int ret;
673068eee   Todd Kjos   binder: add spinl...
1223
1224
1225
  	binder_node_inner_lock(node);
  	ret = binder_inc_node_nilocked(node, strong, internal, target_list);
  	binder_node_inner_unlock(node);
ed29721e2   Todd Kjos   binder: use inner...
1226
1227
1228
  
  	return ret;
  }
673068eee   Todd Kjos   binder: add spinl...
1229
1230
  static bool binder_dec_node_nilocked(struct binder_node *node,
  				     int strong, int internal)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1231
  {
ed29721e2   Todd Kjos   binder: use inner...
1232
  	struct binder_proc *proc = node->proc;
858b27196   Martijn Coenen   ANDROID: binder: ...
1233
  	assert_spin_locked(&node->lock);
ed29721e2   Todd Kjos   binder: use inner...
1234
  	if (proc)
858b27196   Martijn Coenen   ANDROID: binder: ...
1235
  		assert_spin_locked(&proc->inner_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1236
1237
1238
1239
1240
1241
  	if (strong) {
  		if (internal)
  			node->internal_strong_refs--;
  		else
  			node->local_strong_refs--;
  		if (node->local_strong_refs || node->internal_strong_refs)
ed29721e2   Todd Kjos   binder: use inner...
1242
  			return false;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1243
1244
1245
  	} else {
  		if (!internal)
  			node->local_weak_refs--;
adc188422   Todd Kjos   binder: use node-...
1246
1247
  		if (node->local_weak_refs || node->tmp_refs ||
  				!hlist_empty(&node->refs))
ed29721e2   Todd Kjos   binder: use inner...
1248
  			return false;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1249
  	}
ed29721e2   Todd Kjos   binder: use inner...
1250
1251
  
  	if (proc && (node->has_strong_ref || node->has_weak_ref)) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1252
  		if (list_empty(&node->work.entry)) {
72196393a   Todd Kjos   binder: add spinl...
1253
  			binder_enqueue_work_ilocked(&node->work, &proc->todo);
408c68b17   Martijn Coenen   ANDROID: binder: ...
1254
  			binder_wakeup_proc_ilocked(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1255
1256
1257
  		}
  	} else {
  		if (hlist_empty(&node->refs) && !node->local_strong_refs &&
adc188422   Todd Kjos   binder: use node-...
1258
  		    !node->local_weak_refs && !node->tmp_refs) {
ed29721e2   Todd Kjos   binder: use inner...
1259
  			if (proc) {
72196393a   Todd Kjos   binder: add spinl...
1260
1261
  				binder_dequeue_work_ilocked(&node->work);
  				rb_erase(&node->rb_node, &proc->nodes);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1262
  				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
56b468fc7   Anmol Sarma   Staging: android:...
1263
1264
  					     "refless node %d deleted
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1265
1266
  					     node->debug_id);
  			} else {
72196393a   Todd Kjos   binder: add spinl...
1267
  				BUG_ON(!list_empty(&node->work.entry));
c44b1231f   Todd Kjos   binder: add prote...
1268
  				spin_lock(&binder_dead_nodes_lock);
ed29721e2   Todd Kjos   binder: use inner...
1269
1270
1271
1272
1273
1274
1275
1276
  				/*
  				 * tmp_refs could have changed so
  				 * check it again
  				 */
  				if (node->tmp_refs) {
  					spin_unlock(&binder_dead_nodes_lock);
  					return false;
  				}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1277
  				hlist_del(&node->dead_node);
c44b1231f   Todd Kjos   binder: add prote...
1278
  				spin_unlock(&binder_dead_nodes_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1279
  				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
56b468fc7   Anmol Sarma   Staging: android:...
1280
1281
  					     "dead node %d deleted
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1282
1283
  					     node->debug_id);
  			}
ed29721e2   Todd Kjos   binder: use inner...
1284
  			return true;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1285
1286
  		}
  	}
ed29721e2   Todd Kjos   binder: use inner...
1287
1288
  	return false;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1289

ed29721e2   Todd Kjos   binder: use inner...
1290
1291
1292
  static void binder_dec_node(struct binder_node *node, int strong, int internal)
  {
  	bool free_node;
673068eee   Todd Kjos   binder: add spinl...
1293
1294
1295
  	binder_node_inner_lock(node);
  	free_node = binder_dec_node_nilocked(node, strong, internal);
  	binder_node_inner_unlock(node);
ed29721e2   Todd Kjos   binder: use inner...
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
  	if (free_node)
  		binder_free_node(node);
  }
  
  static void binder_inc_node_tmpref_ilocked(struct binder_node *node)
  {
  	/*
  	 * No call to binder_inc_node() is needed since we
  	 * don't need to inform userspace of any changes to
  	 * tmp_refs
  	 */
  	node->tmp_refs++;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1308
  }
adc188422   Todd Kjos   binder: use node-...
1309
1310
1311
1312
1313
  /**
   * binder_inc_node_tmpref() - take a temporary reference on node
   * @node:	node to reference
   *
   * Take reference on node to prevent the node from being freed
ed29721e2   Todd Kjos   binder: use inner...
1314
1315
1316
1317
1318
1319
1320
   * while referenced only by a local variable. The inner lock is
   * needed to serialize with the node work on the queue (which
   * isn't needed after the node is dead). If the node is dead
   * (node->proc is NULL), use binder_dead_nodes_lock to protect
   * node->tmp_refs against dead-node-only cases where the node
   * lock cannot be acquired (eg traversing the dead node list to
   * print nodes)
adc188422   Todd Kjos   binder: use node-...
1321
1322
1323
   */
  static void binder_inc_node_tmpref(struct binder_node *node)
  {
673068eee   Todd Kjos   binder: add spinl...
1324
  	binder_node_lock(node);
ed29721e2   Todd Kjos   binder: use inner...
1325
1326
1327
1328
1329
1330
1331
1332
1333
  	if (node->proc)
  		binder_inner_proc_lock(node->proc);
  	else
  		spin_lock(&binder_dead_nodes_lock);
  	binder_inc_node_tmpref_ilocked(node);
  	if (node->proc)
  		binder_inner_proc_unlock(node->proc);
  	else
  		spin_unlock(&binder_dead_nodes_lock);
673068eee   Todd Kjos   binder: add spinl...
1334
  	binder_node_unlock(node);
adc188422   Todd Kjos   binder: use node-...
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  }
  
  /**
   * binder_dec_node_tmpref() - remove a temporary reference on node
   * @node:	node to reference
   *
   * Release temporary reference on node taken via binder_inc_node_tmpref()
   */
  static void binder_dec_node_tmpref(struct binder_node *node)
  {
ed29721e2   Todd Kjos   binder: use inner...
1345
  	bool free_node;
673068eee   Todd Kjos   binder: add spinl...
1346
1347
  	binder_node_inner_lock(node);
  	if (!node->proc)
ed29721e2   Todd Kjos   binder: use inner...
1348
  		spin_lock(&binder_dead_nodes_lock);
adc188422   Todd Kjos   binder: use node-...
1349
1350
  	node->tmp_refs--;
  	BUG_ON(node->tmp_refs < 0);
ed29721e2   Todd Kjos   binder: use inner...
1351
1352
  	if (!node->proc)
  		spin_unlock(&binder_dead_nodes_lock);
adc188422   Todd Kjos   binder: use node-...
1353
1354
1355
1356
1357
1358
  	/*
  	 * Call binder_dec_node() to check if all refcounts are 0
  	 * and cleanup is needed. Calling with strong=0 and internal=1
  	 * causes no actual reference to be released in binder_dec_node().
  	 * If that changes, a change is needed here too.
  	 */
673068eee   Todd Kjos   binder: add spinl...
1359
1360
  	free_node = binder_dec_node_nilocked(node, 0, 1);
  	binder_node_inner_unlock(node);
ed29721e2   Todd Kjos   binder: use inner...
1361
1362
  	if (free_node)
  		binder_free_node(node);
adc188422   Todd Kjos   binder: use node-...
1363
1364
1365
1366
1367
1368
  }
  
  static void binder_put_node(struct binder_node *node)
  {
  	binder_dec_node_tmpref(node);
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1369

2c1838dc6   Todd Kjos   binder: protect b...
1370
1371
  static struct binder_ref *binder_get_ref_olocked(struct binder_proc *proc,
  						 u32 desc, bool need_strong_ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1372
1373
1374
1375
1376
1377
  {
  	struct rb_node *n = proc->refs_by_desc.rb_node;
  	struct binder_ref *ref;
  
  	while (n) {
  		ref = rb_entry(n, struct binder_ref, rb_node_desc);
372e3147d   Todd Kjos   binder: refactor ...
1378
  		if (desc < ref->data.desc) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1379
  			n = n->rb_left;
372e3147d   Todd Kjos   binder: refactor ...
1380
  		} else if (desc > ref->data.desc) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1381
  			n = n->rb_right;
372e3147d   Todd Kjos   binder: refactor ...
1382
  		} else if (need_strong_ref && !ref->data.strong) {
0a3ffab93   Arve Hjønnevåg   ANDROID: binder: ...
1383
1384
1385
1386
  			binder_user_error("tried to use weak ref as strong ref
  ");
  			return NULL;
  		} else {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1387
  			return ref;
0a3ffab93   Arve Hjønnevåg   ANDROID: binder: ...
1388
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1389
1390
1391
  	}
  	return NULL;
  }
372e3147d   Todd Kjos   binder: refactor ...
1392
  /**
2c1838dc6   Todd Kjos   binder: protect b...
1393
   * binder_get_ref_for_node_olocked() - get the ref associated with given node
372e3147d   Todd Kjos   binder: refactor ...
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
   * @proc:	binder_proc that owns the ref
   * @node:	binder_node of target
   * @new_ref:	newly allocated binder_ref to be initialized or %NULL
   *
   * Look up the ref for the given node and return it if it exists
   *
   * If it doesn't exist and the caller provides a newly allocated
   * ref, initialize the fields of the newly allocated ref and insert
   * into the given proc rb_trees and node refs list.
   *
   * Return:	the ref for node. It is possible that another thread
   *		allocated/initialized the ref first in which case the
   *		returned ref would be different than the passed-in
   *		new_ref. new_ref must be kfree'd by the caller in
   *		this case.
   */
2c1838dc6   Todd Kjos   binder: protect b...
1410
1411
1412
1413
  static struct binder_ref *binder_get_ref_for_node_olocked(
  					struct binder_proc *proc,
  					struct binder_node *node,
  					struct binder_ref *new_ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1414
  {
372e3147d   Todd Kjos   binder: refactor ...
1415
  	struct binder_context *context = proc->context;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1416
1417
  	struct rb_node **p = &proc->refs_by_node.rb_node;
  	struct rb_node *parent = NULL;
372e3147d   Todd Kjos   binder: refactor ...
1418
1419
  	struct binder_ref *ref;
  	struct rb_node *n;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
  
  	while (*p) {
  		parent = *p;
  		ref = rb_entry(parent, struct binder_ref, rb_node_node);
  
  		if (node < ref->node)
  			p = &(*p)->rb_left;
  		else if (node > ref->node)
  			p = &(*p)->rb_right;
  		else
  			return ref;
  	}
372e3147d   Todd Kjos   binder: refactor ...
1432
  	if (!new_ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1433
  		return NULL;
372e3147d   Todd Kjos   binder: refactor ...
1434

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1435
  	binder_stats_created(BINDER_STAT_REF);
372e3147d   Todd Kjos   binder: refactor ...
1436
  	new_ref->data.debug_id = atomic_inc_return(&binder_last_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1437
1438
1439
1440
  	new_ref->proc = proc;
  	new_ref->node = node;
  	rb_link_node(&new_ref->rb_node_node, parent, p);
  	rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node);
372e3147d   Todd Kjos   binder: refactor ...
1441
  	new_ref->data.desc = (node == context->binder_context_mgr_node) ? 0 : 1;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1442
1443
  	for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
  		ref = rb_entry(n, struct binder_ref, rb_node_desc);
372e3147d   Todd Kjos   binder: refactor ...
1444
  		if (ref->data.desc > new_ref->data.desc)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1445
  			break;
372e3147d   Todd Kjos   binder: refactor ...
1446
  		new_ref->data.desc = ref->data.desc + 1;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1447
1448
1449
1450
1451
1452
  	}
  
  	p = &proc->refs_by_desc.rb_node;
  	while (*p) {
  		parent = *p;
  		ref = rb_entry(parent, struct binder_ref, rb_node_desc);
372e3147d   Todd Kjos   binder: refactor ...
1453
  		if (new_ref->data.desc < ref->data.desc)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1454
  			p = &(*p)->rb_left;
372e3147d   Todd Kjos   binder: refactor ...
1455
  		else if (new_ref->data.desc > ref->data.desc)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1456
1457
1458
1459
1460
1461
  			p = &(*p)->rb_right;
  		else
  			BUG();
  	}
  	rb_link_node(&new_ref->rb_node_desc, parent, p);
  	rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc);
673068eee   Todd Kjos   binder: add spinl...
1462
1463
  
  	binder_node_lock(node);
e4cffcf4b   Todd Kjos   binder: remove de...
1464
  	hlist_add_head(&new_ref->node_entry, &node->refs);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1465

e4cffcf4b   Todd Kjos   binder: remove de...
1466
1467
1468
  	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
  		     "%d new ref %d desc %d for node %d
  ",
372e3147d   Todd Kjos   binder: refactor ...
1469
  		      proc->pid, new_ref->data.debug_id, new_ref->data.desc,
e4cffcf4b   Todd Kjos   binder: remove de...
1470
  		      node->debug_id);
673068eee   Todd Kjos   binder: add spinl...
1471
  	binder_node_unlock(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1472
1473
  	return new_ref;
  }
2c1838dc6   Todd Kjos   binder: protect b...
1474
  static void binder_cleanup_ref_olocked(struct binder_ref *ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1475
  {
ed29721e2   Todd Kjos   binder: use inner...
1476
  	bool delete_node = false;
ed29721e2   Todd Kjos   binder: use inner...
1477

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1478
  	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
56b468fc7   Anmol Sarma   Staging: android:...
1479
1480
  		     "%d delete ref %d desc %d for node %d
  ",
372e3147d   Todd Kjos   binder: refactor ...
1481
  		      ref->proc->pid, ref->data.debug_id, ref->data.desc,
56b468fc7   Anmol Sarma   Staging: android:...
1482
  		      ref->node->debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1483
1484
1485
  
  	rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc);
  	rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node);
372e3147d   Todd Kjos   binder: refactor ...
1486

673068eee   Todd Kjos   binder: add spinl...
1487
  	binder_node_inner_lock(ref->node);
372e3147d   Todd Kjos   binder: refactor ...
1488
  	if (ref->data.strong)
673068eee   Todd Kjos   binder: add spinl...
1489
  		binder_dec_node_nilocked(ref->node, 1, 1);
372e3147d   Todd Kjos   binder: refactor ...
1490

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1491
  	hlist_del(&ref->node_entry);
673068eee   Todd Kjos   binder: add spinl...
1492
1493
  	delete_node = binder_dec_node_nilocked(ref->node, 0, 1);
  	binder_node_inner_unlock(ref->node);
ed29721e2   Todd Kjos   binder: use inner...
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
  	/*
  	 * Clear ref->node unless we want the caller to free the node
  	 */
  	if (!delete_node) {
  		/*
  		 * The caller uses ref->node to determine
  		 * whether the node needs to be freed. Clear
  		 * it since the node is still alive.
  		 */
  		ref->node = NULL;
  	}
372e3147d   Todd Kjos   binder: refactor ...
1505

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1506
1507
  	if (ref->death) {
  		binder_debug(BINDER_DEBUG_DEAD_BINDER,
56b468fc7   Anmol Sarma   Staging: android:...
1508
1509
  			     "%d delete ref %d desc %d has death notification
  ",
372e3147d   Todd Kjos   binder: refactor ...
1510
1511
  			      ref->proc->pid, ref->data.debug_id,
  			      ref->data.desc);
72196393a   Todd Kjos   binder: add spinl...
1512
  		binder_dequeue_work(ref->proc, &ref->death->work);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1513
1514
  		binder_stats_deleted(BINDER_STAT_DEATH);
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1515
1516
  	binder_stats_deleted(BINDER_STAT_REF);
  }
372e3147d   Todd Kjos   binder: refactor ...
1517
  /**
2c1838dc6   Todd Kjos   binder: protect b...
1518
   * binder_inc_ref_olocked() - increment the ref for given handle
372e3147d   Todd Kjos   binder: refactor ...
1519
1520
1521
1522
   * @ref:         ref to be incremented
   * @strong:      if true, strong increment, else weak
   * @target_list: list to queue node work on
   *
2c1838dc6   Todd Kjos   binder: protect b...
1523
   * Increment the ref. @ref->proc->outer_lock must be held on entry
372e3147d   Todd Kjos   binder: refactor ...
1524
1525
1526
   *
   * Return: 0, if successful, else errno
   */
2c1838dc6   Todd Kjos   binder: protect b...
1527
1528
  static int binder_inc_ref_olocked(struct binder_ref *ref, int strong,
  				  struct list_head *target_list)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1529
1530
  {
  	int ret;
10f62861b   Seunghun Lee   staging: android:...
1531

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1532
  	if (strong) {
372e3147d   Todd Kjos   binder: refactor ...
1533
  		if (ref->data.strong == 0) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1534
1535
1536
1537
  			ret = binder_inc_node(ref->node, 1, 1, target_list);
  			if (ret)
  				return ret;
  		}
372e3147d   Todd Kjos   binder: refactor ...
1538
  		ref->data.strong++;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1539
  	} else {
372e3147d   Todd Kjos   binder: refactor ...
1540
  		if (ref->data.weak == 0) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1541
1542
1543
1544
  			ret = binder_inc_node(ref->node, 0, 1, target_list);
  			if (ret)
  				return ret;
  		}
372e3147d   Todd Kjos   binder: refactor ...
1545
  		ref->data.weak++;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1546
1547
1548
  	}
  	return 0;
  }
372e3147d   Todd Kjos   binder: refactor ...
1549
1550
1551
1552
1553
1554
1555
  /**
   * binder_dec_ref() - dec the ref for given handle
   * @ref:	ref to be decremented
   * @strong:	if true, strong decrement, else weak
   *
   * Decrement the ref.
   *
372e3147d   Todd Kjos   binder: refactor ...
1556
1557
   * Return: true if ref is cleaned up and ready to be freed
   */
2c1838dc6   Todd Kjos   binder: protect b...
1558
  static bool binder_dec_ref_olocked(struct binder_ref *ref, int strong)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1559
1560
  {
  	if (strong) {
372e3147d   Todd Kjos   binder: refactor ...
1561
  		if (ref->data.strong == 0) {
56b468fc7   Anmol Sarma   Staging: android:...
1562
1563
  			binder_user_error("%d invalid dec strong, ref %d desc %d s %d w %d
  ",
372e3147d   Todd Kjos   binder: refactor ...
1564
1565
1566
1567
  					  ref->proc->pid, ref->data.debug_id,
  					  ref->data.desc, ref->data.strong,
  					  ref->data.weak);
  			return false;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1568
  		}
372e3147d   Todd Kjos   binder: refactor ...
1569
  		ref->data.strong--;
ed29721e2   Todd Kjos   binder: use inner...
1570
1571
  		if (ref->data.strong == 0)
  			binder_dec_node(ref->node, strong, 1);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1572
  	} else {
372e3147d   Todd Kjos   binder: refactor ...
1573
  		if (ref->data.weak == 0) {
56b468fc7   Anmol Sarma   Staging: android:...
1574
1575
  			binder_user_error("%d invalid dec weak, ref %d desc %d s %d w %d
  ",
372e3147d   Todd Kjos   binder: refactor ...
1576
1577
1578
1579
  					  ref->proc->pid, ref->data.debug_id,
  					  ref->data.desc, ref->data.strong,
  					  ref->data.weak);
  			return false;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1580
  		}
372e3147d   Todd Kjos   binder: refactor ...
1581
  		ref->data.weak--;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1582
  	}
372e3147d   Todd Kjos   binder: refactor ...
1583
  	if (ref->data.strong == 0 && ref->data.weak == 0) {
2c1838dc6   Todd Kjos   binder: protect b...
1584
  		binder_cleanup_ref_olocked(ref);
372e3147d   Todd Kjos   binder: refactor ...
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
  		return true;
  	}
  	return false;
  }
  
  /**
   * binder_get_node_from_ref() - get the node from the given proc/desc
   * @proc:	proc containing the ref
   * @desc:	the handle associated with the ref
   * @need_strong_ref: if true, only return node if ref is strong
   * @rdata:	the id/refcount data for the ref
   *
   * Given a proc and ref handle, return the associated binder_node
   *
   * Return: a binder_node or NULL if not found or not strong when strong required
   */
  static struct binder_node *binder_get_node_from_ref(
  		struct binder_proc *proc,
  		u32 desc, bool need_strong_ref,
  		struct binder_ref_data *rdata)
  {
  	struct binder_node *node;
  	struct binder_ref *ref;
2c1838dc6   Todd Kjos   binder: protect b...
1608
1609
  	binder_proc_lock(proc);
  	ref = binder_get_ref_olocked(proc, desc, need_strong_ref);
372e3147d   Todd Kjos   binder: refactor ...
1610
1611
1612
  	if (!ref)
  		goto err_no_ref;
  	node = ref->node;
adc188422   Todd Kjos   binder: use node-...
1613
1614
1615
1616
1617
  	/*
  	 * Take an implicit reference on the node to ensure
  	 * it stays alive until the call to binder_put_node()
  	 */
  	binder_inc_node_tmpref(node);
372e3147d   Todd Kjos   binder: refactor ...
1618
1619
  	if (rdata)
  		*rdata = ref->data;
2c1838dc6   Todd Kjos   binder: protect b...
1620
  	binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
1621
1622
1623
1624
  
  	return node;
  
  err_no_ref:
2c1838dc6   Todd Kjos   binder: protect b...
1625
  	binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
1626
1627
1628
1629
1630
1631
1632
  	return NULL;
  }
  
  /**
   * binder_free_ref() - free the binder_ref
   * @ref:	ref to free
   *
ed29721e2   Todd Kjos   binder: use inner...
1633
1634
   * Free the binder_ref. Free the binder_node indicated by ref->node
   * (if non-NULL) and the binder_ref_death indicated by ref->death.
372e3147d   Todd Kjos   binder: refactor ...
1635
1636
1637
   */
  static void binder_free_ref(struct binder_ref *ref)
  {
ed29721e2   Todd Kjos   binder: use inner...
1638
1639
  	if (ref->node)
  		binder_free_node(ref->node);
372e3147d   Todd Kjos   binder: refactor ...
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
  	kfree(ref->death);
  	kfree(ref);
  }
  
  /**
   * binder_update_ref_for_handle() - inc/dec the ref for given handle
   * @proc:	proc containing the ref
   * @desc:	the handle associated with the ref
   * @increment:	true=inc reference, false=dec reference
   * @strong:	true=strong reference, false=weak reference
   * @rdata:	the id/refcount data for the ref
   *
   * Given a proc and ref handle, increment or decrement the ref
   * according to "increment" arg.
   *
   * Return: 0 if successful, else errno
   */
  static int binder_update_ref_for_handle(struct binder_proc *proc,
  		uint32_t desc, bool increment, bool strong,
  		struct binder_ref_data *rdata)
  {
  	int ret = 0;
  	struct binder_ref *ref;
  	bool delete_ref = false;
2c1838dc6   Todd Kjos   binder: protect b...
1664
1665
  	binder_proc_lock(proc);
  	ref = binder_get_ref_olocked(proc, desc, strong);
372e3147d   Todd Kjos   binder: refactor ...
1666
1667
1668
1669
1670
  	if (!ref) {
  		ret = -EINVAL;
  		goto err_no_ref;
  	}
  	if (increment)
2c1838dc6   Todd Kjos   binder: protect b...
1671
  		ret = binder_inc_ref_olocked(ref, strong, NULL);
372e3147d   Todd Kjos   binder: refactor ...
1672
  	else
2c1838dc6   Todd Kjos   binder: protect b...
1673
  		delete_ref = binder_dec_ref_olocked(ref, strong);
372e3147d   Todd Kjos   binder: refactor ...
1674
1675
1676
  
  	if (rdata)
  		*rdata = ref->data;
2c1838dc6   Todd Kjos   binder: protect b...
1677
  	binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
1678
1679
1680
1681
1682
1683
  
  	if (delete_ref)
  		binder_free_ref(ref);
  	return ret;
  
  err_no_ref:
2c1838dc6   Todd Kjos   binder: protect b...
1684
  	binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
  	return ret;
  }
  
  /**
   * binder_dec_ref_for_handle() - dec the ref for given handle
   * @proc:	proc containing the ref
   * @desc:	the handle associated with the ref
   * @strong:	true=strong reference, false=weak reference
   * @rdata:	the id/refcount data for the ref
   *
   * Just calls binder_update_ref_for_handle() to decrement the ref.
   *
   * Return: 0 if successful, else errno
   */
  static int binder_dec_ref_for_handle(struct binder_proc *proc,
  		uint32_t desc, bool strong, struct binder_ref_data *rdata)
  {
  	return binder_update_ref_for_handle(proc, desc, false, strong, rdata);
  }
  
  
  /**
   * binder_inc_ref_for_node() - increment the ref for given proc/node
   * @proc:	 proc containing the ref
   * @node:	 target node
   * @strong:	 true=strong reference, false=weak reference
   * @target_list: worklist to use if node is incremented
   * @rdata:	 the id/refcount data for the ref
   *
   * Given a proc and node, increment the ref. Create the ref if it
   * doesn't already exist
   *
   * Return: 0 if successful, else errno
   */
  static int binder_inc_ref_for_node(struct binder_proc *proc,
  			struct binder_node *node,
  			bool strong,
  			struct list_head *target_list,
  			struct binder_ref_data *rdata)
  {
  	struct binder_ref *ref;
  	struct binder_ref *new_ref = NULL;
  	int ret = 0;
2c1838dc6   Todd Kjos   binder: protect b...
1728
1729
  	binder_proc_lock(proc);
  	ref = binder_get_ref_for_node_olocked(proc, node, NULL);
372e3147d   Todd Kjos   binder: refactor ...
1730
  	if (!ref) {
2c1838dc6   Todd Kjos   binder: protect b...
1731
  		binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
1732
1733
1734
  		new_ref = kzalloc(sizeof(*ref), GFP_KERNEL);
  		if (!new_ref)
  			return -ENOMEM;
2c1838dc6   Todd Kjos   binder: protect b...
1735
1736
  		binder_proc_lock(proc);
  		ref = binder_get_ref_for_node_olocked(proc, node, new_ref);
372e3147d   Todd Kjos   binder: refactor ...
1737
  	}
2c1838dc6   Todd Kjos   binder: protect b...
1738
  	ret = binder_inc_ref_olocked(ref, strong, target_list);
372e3147d   Todd Kjos   binder: refactor ...
1739
  	*rdata = ref->data;
2c1838dc6   Todd Kjos   binder: protect b...
1740
  	binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
1741
1742
1743
1744
1745
1746
1747
  	if (new_ref && ref != new_ref)
  		/*
  		 * Another thread created the ref first so
  		 * free the one we allocated
  		 */
  		kfree(new_ref);
  	return ret;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1748
  }
0b89d69a9   Martijn Coenen   binder: protect t...
1749
1750
  static void binder_pop_transaction_ilocked(struct binder_thread *target_thread,
  					   struct binder_transaction *t)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1751
  {
b6d282cea   Todd Kjos   binder: refactor ...
1752
  	BUG_ON(!target_thread);
858b27196   Martijn Coenen   ANDROID: binder: ...
1753
  	assert_spin_locked(&target_thread->proc->inner_lock);
b6d282cea   Todd Kjos   binder: refactor ...
1754
1755
1756
1757
1758
1759
  	BUG_ON(target_thread->transaction_stack != t);
  	BUG_ON(target_thread->transaction_stack->from != target_thread);
  	target_thread->transaction_stack =
  		target_thread->transaction_stack->from_parent;
  	t->from = NULL;
  }
7a4408c6b   Todd Kjos   binder: make sure...
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
  /**
   * binder_thread_dec_tmpref() - decrement thread->tmp_ref
   * @thread:	thread to decrement
   *
   * A thread needs to be kept alive while being used to create or
   * handle a transaction. binder_get_txn_from() is used to safely
   * extract t->from from a binder_transaction and keep the thread
   * indicated by t->from from being freed. When done with that
   * binder_thread, this function is called to decrement the
   * tmp_ref and free if appropriate (thread has been released
   * and no transaction being processed by the driver)
   */
  static void binder_thread_dec_tmpref(struct binder_thread *thread)
  {
  	/*
  	 * atomic is used to protect the counter value while
  	 * it cannot reach zero or thread->is_dead is false
7a4408c6b   Todd Kjos   binder: make sure...
1777
  	 */
7bd7b0e63   Todd Kjos   binder: protect p...
1778
  	binder_inner_proc_lock(thread->proc);
7a4408c6b   Todd Kjos   binder: make sure...
1779
1780
  	atomic_dec(&thread->tmp_ref);
  	if (thread->is_dead && !atomic_read(&thread->tmp_ref)) {
7bd7b0e63   Todd Kjos   binder: protect p...
1781
  		binder_inner_proc_unlock(thread->proc);
7a4408c6b   Todd Kjos   binder: make sure...
1782
1783
1784
  		binder_free_thread(thread);
  		return;
  	}
7bd7b0e63   Todd Kjos   binder: protect p...
1785
  	binder_inner_proc_unlock(thread->proc);
7a4408c6b   Todd Kjos   binder: make sure...
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
  }
  
  /**
   * binder_proc_dec_tmpref() - decrement proc->tmp_ref
   * @proc:	proc to decrement
   *
   * A binder_proc needs to be kept alive while being used to create or
   * handle a transaction. proc->tmp_ref is incremented when
   * creating a new transaction or the binder_proc is currently in-use
   * by threads that are being released. When done with the binder_proc,
   * this function is called to decrement the counter and free the
   * proc if appropriate (proc has been released, all threads have
   * been released and not currenly in-use to process a transaction).
   */
  static void binder_proc_dec_tmpref(struct binder_proc *proc)
  {
7bd7b0e63   Todd Kjos   binder: protect p...
1802
  	binder_inner_proc_lock(proc);
7a4408c6b   Todd Kjos   binder: make sure...
1803
1804
1805
  	proc->tmp_ref--;
  	if (proc->is_dead && RB_EMPTY_ROOT(&proc->threads) &&
  			!proc->tmp_ref) {
7bd7b0e63   Todd Kjos   binder: protect p...
1806
  		binder_inner_proc_unlock(proc);
7a4408c6b   Todd Kjos   binder: make sure...
1807
1808
1809
  		binder_free_proc(proc);
  		return;
  	}
7bd7b0e63   Todd Kjos   binder: protect p...
1810
  	binder_inner_proc_unlock(proc);
7a4408c6b   Todd Kjos   binder: make sure...
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
  }
  
  /**
   * binder_get_txn_from() - safely extract the "from" thread in transaction
   * @t:	binder transaction for t->from
   *
   * Atomically return the "from" thread and increment the tmp_ref
   * count for the thread to ensure it stays alive until
   * binder_thread_dec_tmpref() is called.
   *
   * Return: the value of t->from
   */
  static struct binder_thread *binder_get_txn_from(
  		struct binder_transaction *t)
  {
  	struct binder_thread *from;
  
  	spin_lock(&t->lock);
  	from = t->from;
  	if (from)
  		atomic_inc(&from->tmp_ref);
  	spin_unlock(&t->lock);
  	return from;
  }
0b89d69a9   Martijn Coenen   binder: protect t...
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
  /**
   * binder_get_txn_from_and_acq_inner() - get t->from and acquire inner lock
   * @t:	binder transaction for t->from
   *
   * Same as binder_get_txn_from() except it also acquires the proc->inner_lock
   * to guarantee that the thread cannot be released while operating on it.
   * The caller must call binder_inner_proc_unlock() to release the inner lock
   * as well as call binder_dec_thread_txn() to release the reference.
   *
   * Return: the value of t->from
   */
  static struct binder_thread *binder_get_txn_from_and_acq_inner(
  		struct binder_transaction *t)
  {
  	struct binder_thread *from;
  
  	from = binder_get_txn_from(t);
  	if (!from)
  		return NULL;
  	binder_inner_proc_lock(from->proc);
  	if (t->from) {
  		BUG_ON(from != t->from);
  		return from;
  	}
  	binder_inner_proc_unlock(from->proc);
  	binder_thread_dec_tmpref(from);
  	return NULL;
  }
b6d282cea   Todd Kjos   binder: refactor ...
1863
1864
  static void binder_free_transaction(struct binder_transaction *t)
  {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
  	if (t->buffer)
  		t->buffer->transaction = NULL;
  	kfree(t);
  	binder_stats_deleted(BINDER_STAT_TRANSACTION);
  }
  
  static void binder_send_failed_reply(struct binder_transaction *t,
  				     uint32_t error_code)
  {
  	struct binder_thread *target_thread;
d4ec15e16   Lucas Tanure   staging: android:...
1875
  	struct binder_transaction *next;
10f62861b   Seunghun Lee   staging: android:...
1876

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1877
1878
  	BUG_ON(t->flags & TF_ONE_WAY);
  	while (1) {
0b89d69a9   Martijn Coenen   binder: protect t...
1879
  		target_thread = binder_get_txn_from_and_acq_inner(t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1880
  		if (target_thread) {
26549d177   Todd Kjos   binder: guarantee...
1881
1882
1883
1884
1885
1886
  			binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
  				     "send failed reply for transaction %d to %d:%d
  ",
  				      t->debug_id,
  				      target_thread->proc->pid,
  				      target_thread->pid);
0b89d69a9   Martijn Coenen   binder: protect t...
1887
  			binder_pop_transaction_ilocked(target_thread, t);
26549d177   Todd Kjos   binder: guarantee...
1888
1889
  			if (target_thread->reply_error.cmd == BR_OK) {
  				target_thread->reply_error.cmd = error_code;
0b89d69a9   Martijn Coenen   binder: protect t...
1890
  				binder_enqueue_work_ilocked(
72196393a   Todd Kjos   binder: add spinl...
1891
  					&target_thread->reply_error.work,
26549d177   Todd Kjos   binder: guarantee...
1892
  					&target_thread->todo);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1893
1894
  				wake_up_interruptible(&target_thread->wait);
  			} else {
129926c37   Todd Kjos   ANDROID: binder: ...
1895
1896
1897
1898
1899
1900
1901
1902
1903
  				/*
  				 * Cannot get here for normal operation, but
  				 * we can if multiple synchronous transactions
  				 * are sent without blocking for responses.
  				 * Just ignore the 2nd error in this case.
  				 */
  				pr_warn("Unexpected reply error: %u
  ",
  					target_thread->reply_error.cmd);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1904
  			}
0b89d69a9   Martijn Coenen   binder: protect t...
1905
  			binder_inner_proc_unlock(target_thread->proc);
7a4408c6b   Todd Kjos   binder: make sure...
1906
  			binder_thread_dec_tmpref(target_thread);
26549d177   Todd Kjos   binder: guarantee...
1907
  			binder_free_transaction(t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1908
  			return;
d4ec15e16   Lucas Tanure   staging: android:...
1909
1910
1911
1912
1913
1914
1915
  		}
  		next = t->from_parent;
  
  		binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
  			     "send failed reply for transaction %d, target dead
  ",
  			     t->debug_id);
b6d282cea   Todd Kjos   binder: refactor ...
1916
  		binder_free_transaction(t);
d4ec15e16   Lucas Tanure   staging: android:...
1917
  		if (next == NULL) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1918
  			binder_debug(BINDER_DEBUG_DEAD_BINDER,
d4ec15e16   Lucas Tanure   staging: android:...
1919
1920
1921
  				     "reply failed, no target thread at root
  ");
  			return;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1922
  		}
d4ec15e16   Lucas Tanure   staging: android:...
1923
1924
1925
1926
1927
  		t = next;
  		binder_debug(BINDER_DEBUG_DEAD_BINDER,
  			     "reply failed, no target thread -- retry %d
  ",
  			      t->debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
1928
1929
  	}
  }
feba3900c   Martijn Coenen   binder: Split fla...
1930
  /**
22ad53793   Martijn Coenen   ANDROID: binder: ...
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
   * binder_cleanup_transaction() - cleans up undelivered transaction
   * @t:		transaction that needs to be cleaned up
   * @reason:	reason the transaction wasn't delivered
   * @error_code:	error to return to caller (if synchronous call)
   */
  static void binder_cleanup_transaction(struct binder_transaction *t,
  				       const char *reason,
  				       uint32_t error_code)
  {
  	if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) {
  		binder_send_failed_reply(t, error_code);
  	} else {
  		binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
  			"undelivered transaction %d, %s
  ",
  			t->debug_id, reason);
  		binder_free_transaction(t);
  	}
  }
  
  /**
feba3900c   Martijn Coenen   binder: Split fla...
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
   * binder_validate_object() - checks for a valid metadata object in a buffer.
   * @buffer:	binder_buffer that we're parsing.
   * @offset:	offset in the buffer at which to validate an object.
   *
   * Return:	If there's a valid metadata object at @offset in @buffer, the
   *		size of that object. Otherwise, it returns zero.
   */
  static size_t binder_validate_object(struct binder_buffer *buffer, u64 offset)
  {
  	/* Check if we can read a header first */
  	struct binder_object_header *hdr;
  	size_t object_size = 0;
  
  	if (offset > buffer->data_size - sizeof(*hdr) ||
  	    buffer->data_size < sizeof(*hdr) ||
  	    !IS_ALIGNED(offset, sizeof(u32)))
  		return 0;
  
  	/* Ok, now see if we can read a complete object. */
  	hdr = (struct binder_object_header *)(buffer->data + offset);
  	switch (hdr->type) {
  	case BINDER_TYPE_BINDER:
  	case BINDER_TYPE_WEAK_BINDER:
  	case BINDER_TYPE_HANDLE:
  	case BINDER_TYPE_WEAK_HANDLE:
  		object_size = sizeof(struct flat_binder_object);
  		break;
  	case BINDER_TYPE_FD:
  		object_size = sizeof(struct binder_fd_object);
  		break;
7980240b6   Martijn Coenen   binder: Add suppo...
1982
1983
1984
  	case BINDER_TYPE_PTR:
  		object_size = sizeof(struct binder_buffer_object);
  		break;
def95c735   Martijn Coenen   binder: Add suppo...
1985
1986
1987
  	case BINDER_TYPE_FDA:
  		object_size = sizeof(struct binder_fd_array_object);
  		break;
feba3900c   Martijn Coenen   binder: Split fla...
1988
1989
1990
1991
1992
1993
1994
1995
1996
  	default:
  		return 0;
  	}
  	if (offset <= buffer->data_size - object_size &&
  	    buffer->data_size >= object_size)
  		return object_size;
  	else
  		return 0;
  }
7980240b6   Martijn Coenen   binder: Add suppo...
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
  /**
   * binder_validate_ptr() - validates binder_buffer_object in a binder_buffer.
   * @b:		binder_buffer containing the object
   * @index:	index in offset array at which the binder_buffer_object is
   *		located
   * @start:	points to the start of the offset array
   * @num_valid:	the number of valid offsets in the offset array
   *
   * Return:	If @index is within the valid range of the offset array
   *		described by @start and @num_valid, and if there's a valid
   *		binder_buffer_object at the offset found in index @index
   *		of the offset array, that object is returned. Otherwise,
   *		%NULL is returned.
   *		Note that the offset found in index @index itself is not
   *		verified; this function assumes that @num_valid elements
   *		from @start were previously verified to have valid offsets.
   */
  static struct binder_buffer_object *binder_validate_ptr(struct binder_buffer *b,
  							binder_size_t index,
  							binder_size_t *start,
  							binder_size_t num_valid)
  {
  	struct binder_buffer_object *buffer_obj;
  	binder_size_t *offp;
  
  	if (index >= num_valid)
  		return NULL;
  
  	offp = start + index;
  	buffer_obj = (struct binder_buffer_object *)(b->data + *offp);
  	if (buffer_obj->hdr.type != BINDER_TYPE_PTR)
  		return NULL;
  
  	return buffer_obj;
  }
  
  /**
   * binder_validate_fixup() - validates pointer/fd fixups happen in order.
   * @b:			transaction buffer
   * @objects_start	start of objects buffer
   * @buffer:		binder_buffer_object in which to fix up
   * @offset:		start offset in @buffer to fix up
   * @last_obj:		last binder_buffer_object that we fixed up in
   * @last_min_offset:	minimum fixup offset in @last_obj
   *
   * Return:		%true if a fixup in buffer @buffer at offset @offset is
   *			allowed.
   *
   * For safety reasons, we only allow fixups inside a buffer to happen
   * at increasing offsets; additionally, we only allow fixup on the last
   * buffer object that was verified, or one of its parents.
   *
   * Example of what is allowed:
   *
   * A
   *   B (parent = A, offset = 0)
   *   C (parent = A, offset = 16)
   *     D (parent = C, offset = 0)
   *   E (parent = A, offset = 32) // min_offset is 16 (C.parent_offset)
   *
   * Examples of what is not allowed:
   *
   * Decreasing offsets within the same parent:
   * A
   *   C (parent = A, offset = 16)
   *   B (parent = A, offset = 0) // decreasing offset within A
   *
   * Referring to a parent that wasn't the last object or any of its parents:
   * A
   *   B (parent = A, offset = 0)
   *   C (parent = A, offset = 0)
   *   C (parent = A, offset = 16)
   *     D (parent = B, offset = 0) // B is not A or any of A's parents
   */
  static bool binder_validate_fixup(struct binder_buffer *b,
  				  binder_size_t *objects_start,
  				  struct binder_buffer_object *buffer,
  				  binder_size_t fixup_offset,
  				  struct binder_buffer_object *last_obj,
  				  binder_size_t last_min_offset)
  {
  	if (!last_obj) {
  		/* Nothing to fix up in */
  		return false;
  	}
  
  	while (last_obj != buffer) {
  		/*
  		 * Safe to retrieve the parent of last_obj, since it
  		 * was already previously verified by the driver.
  		 */
  		if ((last_obj->flags & BINDER_BUFFER_FLAG_HAS_PARENT) == 0)
  			return false;
  		last_min_offset = last_obj->parent_offset + sizeof(uintptr_t);
  		last_obj = (struct binder_buffer_object *)
  			(b->data + *(objects_start + last_obj->parent));
  	}
  	return (fixup_offset >= last_min_offset);
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2096
2097
  static void binder_transaction_buffer_release(struct binder_proc *proc,
  					      struct binder_buffer *buffer,
da49889de   Arve Hjønnevåg   staging: binder: ...
2098
  					      binder_size_t *failed_at)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2099
  {
7980240b6   Martijn Coenen   binder: Add suppo...
2100
  	binder_size_t *offp, *off_start, *off_end;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2101
2102
2103
  	int debug_id = buffer->debug_id;
  
  	binder_debug(BINDER_DEBUG_TRANSACTION,
b46af094b   Todd Kjos   binder: replace "...
2104
2105
  		     "%d buffer release %d, size %zd-%zd, failed at %pK
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2106
2107
2108
2109
2110
  		     proc->pid, buffer->debug_id,
  		     buffer->data_size, buffer->offsets_size, failed_at);
  
  	if (buffer->target_node)
  		binder_dec_node(buffer->target_node, 1, 0);
7980240b6   Martijn Coenen   binder: Add suppo...
2111
2112
  	off_start = (binder_size_t *)(buffer->data +
  				      ALIGN(buffer->data_size, sizeof(void *)));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2113
2114
2115
  	if (failed_at)
  		off_end = failed_at;
  	else
7980240b6   Martijn Coenen   binder: Add suppo...
2116
2117
  		off_end = (void *)off_start + buffer->offsets_size;
  	for (offp = off_start; offp < off_end; offp++) {
feba3900c   Martijn Coenen   binder: Split fla...
2118
2119
  		struct binder_object_header *hdr;
  		size_t object_size = binder_validate_object(buffer, *offp);
10f62861b   Seunghun Lee   staging: android:...
2120

feba3900c   Martijn Coenen   binder: Split fla...
2121
2122
2123
  		if (object_size == 0) {
  			pr_err("transaction release %d bad object at offset %lld, size %zd
  ",
da49889de   Arve Hjønnevåg   staging: binder: ...
2124
  			       debug_id, (u64)*offp, buffer->data_size);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2125
2126
  			continue;
  		}
feba3900c   Martijn Coenen   binder: Split fla...
2127
2128
  		hdr = (struct binder_object_header *)(buffer->data + *offp);
  		switch (hdr->type) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2129
2130
  		case BINDER_TYPE_BINDER:
  		case BINDER_TYPE_WEAK_BINDER: {
feba3900c   Martijn Coenen   binder: Split fla...
2131
2132
  			struct flat_binder_object *fp;
  			struct binder_node *node;
10f62861b   Seunghun Lee   staging: android:...
2133

feba3900c   Martijn Coenen   binder: Split fla...
2134
2135
  			fp = to_flat_binder_object(hdr);
  			node = binder_get_node(proc, fp->binder);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2136
  			if (node == NULL) {
da49889de   Arve Hjønnevåg   staging: binder: ...
2137
2138
2139
  				pr_err("transaction release %d bad node %016llx
  ",
  				       debug_id, (u64)fp->binder);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2140
2141
2142
  				break;
  			}
  			binder_debug(BINDER_DEBUG_TRANSACTION,
da49889de   Arve Hjønnevåg   staging: binder: ...
2143
2144
2145
  				     "        node %d u%016llx
  ",
  				     node->debug_id, (u64)node->ptr);
feba3900c   Martijn Coenen   binder: Split fla...
2146
2147
  			binder_dec_node(node, hdr->type == BINDER_TYPE_BINDER,
  					0);
adc188422   Todd Kjos   binder: use node-...
2148
  			binder_put_node(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2149
2150
2151
  		} break;
  		case BINDER_TYPE_HANDLE:
  		case BINDER_TYPE_WEAK_HANDLE: {
feba3900c   Martijn Coenen   binder: Split fla...
2152
  			struct flat_binder_object *fp;
372e3147d   Todd Kjos   binder: refactor ...
2153
2154
  			struct binder_ref_data rdata;
  			int ret;
0a3ffab93   Arve Hjønnevåg   ANDROID: binder: ...
2155

feba3900c   Martijn Coenen   binder: Split fla...
2156
  			fp = to_flat_binder_object(hdr);
372e3147d   Todd Kjos   binder: refactor ...
2157
2158
2159
2160
2161
2162
2163
  			ret = binder_dec_ref_for_handle(proc, fp->handle,
  				hdr->type == BINDER_TYPE_HANDLE, &rdata);
  
  			if (ret) {
  				pr_err("transaction release %d bad handle %d, ret = %d
  ",
  				 debug_id, fp->handle, ret);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2164
2165
2166
  				break;
  			}
  			binder_debug(BINDER_DEBUG_TRANSACTION,
372e3147d   Todd Kjos   binder: refactor ...
2167
2168
2169
  				     "        ref %d desc %d
  ",
  				     rdata.debug_id, rdata.desc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2170
  		} break;
feba3900c   Martijn Coenen   binder: Split fla...
2171
2172
  		case BINDER_TYPE_FD: {
  			struct binder_fd_object *fp = to_binder_fd_object(hdr);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2173
  			binder_debug(BINDER_DEBUG_TRANSACTION,
feba3900c   Martijn Coenen   binder: Split fla...
2174
2175
  				     "        fd %d
  ", fp->fd);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2176
  			if (failed_at)
feba3900c   Martijn Coenen   binder: Split fla...
2177
2178
  				task_close_fd(proc, fp->fd);
  		} break;
7980240b6   Martijn Coenen   binder: Add suppo...
2179
2180
2181
2182
2183
2184
  		case BINDER_TYPE_PTR:
  			/*
  			 * Nothing to do here, this will get cleaned up when the
  			 * transaction buffer gets freed
  			 */
  			break;
def95c735   Martijn Coenen   binder: Add suppo...
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
  		case BINDER_TYPE_FDA: {
  			struct binder_fd_array_object *fda;
  			struct binder_buffer_object *parent;
  			uintptr_t parent_buffer;
  			u32 *fd_array;
  			size_t fd_index;
  			binder_size_t fd_buf_size;
  
  			fda = to_binder_fd_array_object(hdr);
  			parent = binder_validate_ptr(buffer, fda->parent,
  						     off_start,
  						     offp - off_start);
  			if (!parent) {
  				pr_err("transaction release %d bad parent offset",
  				       debug_id);
  				continue;
  			}
  			/*
  			 * Since the parent was already fixed up, convert it
  			 * back to kernel address space to access it
  			 */
  			parent_buffer = parent->buffer -
19c987241   Todd Kjos   binder: separate ...
2207
2208
  				binder_alloc_get_user_buffer_offset(
  						&proc->alloc);
def95c735   Martijn Coenen   binder: Add suppo...
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
  
  			fd_buf_size = sizeof(u32) * fda->num_fds;
  			if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
  				pr_err("transaction release %d invalid number of fds (%lld)
  ",
  				       debug_id, (u64)fda->num_fds);
  				continue;
  			}
  			if (fd_buf_size > parent->length ||
  			    fda->parent_offset > parent->length - fd_buf_size) {
  				/* No space for all file descriptors here. */
  				pr_err("transaction release %d not enough space for %lld fds in buffer
  ",
  				       debug_id, (u64)fda->num_fds);
  				continue;
  			}
1c363eaec   Arnd Bergmann   android: binder: ...
2225
  			fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
def95c735   Martijn Coenen   binder: Add suppo...
2226
2227
2228
  			for (fd_index = 0; fd_index < fda->num_fds; fd_index++)
  				task_close_fd(proc, fd_array[fd_index]);
  		} break;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2229
  		default:
64dcfe6b8   Serban Constantinescu   staging: android:...
2230
2231
  			pr_err("transaction release %d bad object type %x
  ",
feba3900c   Martijn Coenen   binder: Split fla...
2232
  				debug_id, hdr->type);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2233
2234
2235
2236
  			break;
  		}
  	}
  }
a056af420   Martijn Coenen   binder: Refactor ...
2237
2238
2239
2240
2241
  static int binder_translate_binder(struct flat_binder_object *fp,
  				   struct binder_transaction *t,
  				   struct binder_thread *thread)
  {
  	struct binder_node *node;
a056af420   Martijn Coenen   binder: Refactor ...
2242
2243
  	struct binder_proc *proc = thread->proc;
  	struct binder_proc *target_proc = t->to_proc;
372e3147d   Todd Kjos   binder: refactor ...
2244
  	struct binder_ref_data rdata;
adc188422   Todd Kjos   binder: use node-...
2245
  	int ret = 0;
a056af420   Martijn Coenen   binder: Refactor ...
2246
2247
2248
  
  	node = binder_get_node(proc, fp->binder);
  	if (!node) {
673068eee   Todd Kjos   binder: add spinl...
2249
  		node = binder_new_node(proc, fp);
a056af420   Martijn Coenen   binder: Refactor ...
2250
2251
  		if (!node)
  			return -ENOMEM;
a056af420   Martijn Coenen   binder: Refactor ...
2252
2253
2254
2255
2256
2257
2258
  	}
  	if (fp->cookie != node->cookie) {
  		binder_user_error("%d:%d sending u%016llx node %d, cookie mismatch %016llx != %016llx
  ",
  				  proc->pid, thread->pid, (u64)fp->binder,
  				  node->debug_id, (u64)fp->cookie,
  				  (u64)node->cookie);
adc188422   Todd Kjos   binder: use node-...
2259
2260
2261
2262
2263
2264
  		ret = -EINVAL;
  		goto done;
  	}
  	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
  		ret = -EPERM;
  		goto done;
a056af420   Martijn Coenen   binder: Refactor ...
2265
  	}
a056af420   Martijn Coenen   binder: Refactor ...
2266

372e3147d   Todd Kjos   binder: refactor ...
2267
2268
2269
2270
  	ret = binder_inc_ref_for_node(target_proc, node,
  			fp->hdr.type == BINDER_TYPE_BINDER,
  			&thread->todo, &rdata);
  	if (ret)
adc188422   Todd Kjos   binder: use node-...
2271
  		goto done;
a056af420   Martijn Coenen   binder: Refactor ...
2272
2273
2274
2275
2276
2277
  
  	if (fp->hdr.type == BINDER_TYPE_BINDER)
  		fp->hdr.type = BINDER_TYPE_HANDLE;
  	else
  		fp->hdr.type = BINDER_TYPE_WEAK_HANDLE;
  	fp->binder = 0;
372e3147d   Todd Kjos   binder: refactor ...
2278
  	fp->handle = rdata.desc;
a056af420   Martijn Coenen   binder: Refactor ...
2279
  	fp->cookie = 0;
a056af420   Martijn Coenen   binder: Refactor ...
2280

372e3147d   Todd Kjos   binder: refactor ...
2281
  	trace_binder_transaction_node_to_ref(t, node, &rdata);
a056af420   Martijn Coenen   binder: Refactor ...
2282
2283
2284
2285
  	binder_debug(BINDER_DEBUG_TRANSACTION,
  		     "        node %d u%016llx -> ref %d desc %d
  ",
  		     node->debug_id, (u64)node->ptr,
372e3147d   Todd Kjos   binder: refactor ...
2286
  		     rdata.debug_id, rdata.desc);
adc188422   Todd Kjos   binder: use node-...
2287
2288
2289
  done:
  	binder_put_node(node);
  	return ret;
a056af420   Martijn Coenen   binder: Refactor ...
2290
2291
2292
2293
2294
2295
  }
  
  static int binder_translate_handle(struct flat_binder_object *fp,
  				   struct binder_transaction *t,
  				   struct binder_thread *thread)
  {
a056af420   Martijn Coenen   binder: Refactor ...
2296
2297
  	struct binder_proc *proc = thread->proc;
  	struct binder_proc *target_proc = t->to_proc;
372e3147d   Todd Kjos   binder: refactor ...
2298
2299
  	struct binder_node *node;
  	struct binder_ref_data src_rdata;
adc188422   Todd Kjos   binder: use node-...
2300
  	int ret = 0;
a056af420   Martijn Coenen   binder: Refactor ...
2301

372e3147d   Todd Kjos   binder: refactor ...
2302
2303
2304
  	node = binder_get_node_from_ref(proc, fp->handle,
  			fp->hdr.type == BINDER_TYPE_HANDLE, &src_rdata);
  	if (!node) {
a056af420   Martijn Coenen   binder: Refactor ...
2305
2306
2307
2308
2309
  		binder_user_error("%d:%d got transaction with invalid handle, %d
  ",
  				  proc->pid, thread->pid, fp->handle);
  		return -EINVAL;
  	}
adc188422   Todd Kjos   binder: use node-...
2310
2311
2312
2313
  	if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
  		ret = -EPERM;
  		goto done;
  	}
a056af420   Martijn Coenen   binder: Refactor ...
2314

673068eee   Todd Kjos   binder: add spinl...
2315
  	binder_node_lock(node);
372e3147d   Todd Kjos   binder: refactor ...
2316
  	if (node->proc == target_proc) {
a056af420   Martijn Coenen   binder: Refactor ...
2317
2318
2319
2320
  		if (fp->hdr.type == BINDER_TYPE_HANDLE)
  			fp->hdr.type = BINDER_TYPE_BINDER;
  		else
  			fp->hdr.type = BINDER_TYPE_WEAK_BINDER;
372e3147d   Todd Kjos   binder: refactor ...
2321
2322
  		fp->binder = node->ptr;
  		fp->cookie = node->cookie;
673068eee   Todd Kjos   binder: add spinl...
2323
2324
2325
2326
2327
2328
2329
  		if (node->proc)
  			binder_inner_proc_lock(node->proc);
  		binder_inc_node_nilocked(node,
  					 fp->hdr.type == BINDER_TYPE_BINDER,
  					 0, NULL);
  		if (node->proc)
  			binder_inner_proc_unlock(node->proc);
372e3147d   Todd Kjos   binder: refactor ...
2330
  		trace_binder_transaction_ref_to_node(t, node, &src_rdata);
a056af420   Martijn Coenen   binder: Refactor ...
2331
2332
2333
  		binder_debug(BINDER_DEBUG_TRANSACTION,
  			     "        ref %d desc %d -> node %d u%016llx
  ",
372e3147d   Todd Kjos   binder: refactor ...
2334
2335
  			     src_rdata.debug_id, src_rdata.desc, node->debug_id,
  			     (u64)node->ptr);
673068eee   Todd Kjos   binder: add spinl...
2336
  		binder_node_unlock(node);
a056af420   Martijn Coenen   binder: Refactor ...
2337
  	} else {
372e3147d   Todd Kjos   binder: refactor ...
2338
  		struct binder_ref_data dest_rdata;
a056af420   Martijn Coenen   binder: Refactor ...
2339

673068eee   Todd Kjos   binder: add spinl...
2340
  		binder_node_unlock(node);
372e3147d   Todd Kjos   binder: refactor ...
2341
2342
2343
2344
  		ret = binder_inc_ref_for_node(target_proc, node,
  				fp->hdr.type == BINDER_TYPE_HANDLE,
  				NULL, &dest_rdata);
  		if (ret)
adc188422   Todd Kjos   binder: use node-...
2345
  			goto done;
a056af420   Martijn Coenen   binder: Refactor ...
2346
2347
  
  		fp->binder = 0;
372e3147d   Todd Kjos   binder: refactor ...
2348
  		fp->handle = dest_rdata.desc;
a056af420   Martijn Coenen   binder: Refactor ...
2349
  		fp->cookie = 0;
372e3147d   Todd Kjos   binder: refactor ...
2350
2351
  		trace_binder_transaction_ref_to_ref(t, node, &src_rdata,
  						    &dest_rdata);
a056af420   Martijn Coenen   binder: Refactor ...
2352
2353
2354
  		binder_debug(BINDER_DEBUG_TRANSACTION,
  			     "        ref %d desc %d -> ref %d desc %d (node %d)
  ",
372e3147d   Todd Kjos   binder: refactor ...
2355
2356
2357
  			     src_rdata.debug_id, src_rdata.desc,
  			     dest_rdata.debug_id, dest_rdata.desc,
  			     node->debug_id);
a056af420   Martijn Coenen   binder: Refactor ...
2358
  	}
adc188422   Todd Kjos   binder: use node-...
2359
2360
2361
  done:
  	binder_put_node(node);
  	return ret;
a056af420   Martijn Coenen   binder: Refactor ...
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
  }
  
  static int binder_translate_fd(int fd,
  			       struct binder_transaction *t,
  			       struct binder_thread *thread,
  			       struct binder_transaction *in_reply_to)
  {
  	struct binder_proc *proc = thread->proc;
  	struct binder_proc *target_proc = t->to_proc;
  	int target_fd;
  	struct file *file;
  	int ret;
  	bool target_allows_fd;
  
  	if (in_reply_to)
  		target_allows_fd = !!(in_reply_to->flags & TF_ACCEPT_FDS);
  	else
  		target_allows_fd = t->buffer->target_node->accept_fds;
  	if (!target_allows_fd) {
  		binder_user_error("%d:%d got %s with fd, %d, but target does not allow fds
  ",
  				  proc->pid, thread->pid,
  				  in_reply_to ? "reply" : "transaction",
  				  fd);
  		ret = -EPERM;
  		goto err_fd_not_accepted;
  	}
  
  	file = fget(fd);
  	if (!file) {
  		binder_user_error("%d:%d got transaction with invalid fd, %d
  ",
  				  proc->pid, thread->pid, fd);
  		ret = -EBADF;
  		goto err_fget;
  	}
  	ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
  	if (ret < 0) {
  		ret = -EPERM;
  		goto err_security;
  	}
  
  	target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
  	if (target_fd < 0) {
  		ret = -ENOMEM;
  		goto err_get_unused_fd;
  	}
  	task_fd_install(target_proc, target_fd, file);
  	trace_binder_transaction_fd(t, fd, target_fd);
  	binder_debug(BINDER_DEBUG_TRANSACTION, "        fd %d -> %d
  ",
  		     fd, target_fd);
  
  	return target_fd;
  
  err_get_unused_fd:
  err_security:
  	fput(file);
  err_fget:
  err_fd_not_accepted:
  	return ret;
  }
def95c735   Martijn Coenen   binder: Add suppo...
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
  static int binder_translate_fd_array(struct binder_fd_array_object *fda,
  				     struct binder_buffer_object *parent,
  				     struct binder_transaction *t,
  				     struct binder_thread *thread,
  				     struct binder_transaction *in_reply_to)
  {
  	binder_size_t fdi, fd_buf_size, num_installed_fds;
  	int target_fd;
  	uintptr_t parent_buffer;
  	u32 *fd_array;
  	struct binder_proc *proc = thread->proc;
  	struct binder_proc *target_proc = t->to_proc;
  
  	fd_buf_size = sizeof(u32) * fda->num_fds;
  	if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
  		binder_user_error("%d:%d got transaction with invalid number of fds (%lld)
  ",
  				  proc->pid, thread->pid, (u64)fda->num_fds);
  		return -EINVAL;
  	}
  	if (fd_buf_size > parent->length ||
  	    fda->parent_offset > parent->length - fd_buf_size) {
  		/* No space for all file descriptors here. */
  		binder_user_error("%d:%d not enough space to store %lld fds in buffer
  ",
  				  proc->pid, thread->pid, (u64)fda->num_fds);
  		return -EINVAL;
  	}
  	/*
  	 * Since the parent was already fixed up, convert it
  	 * back to the kernel address space to access it
  	 */
19c987241   Todd Kjos   binder: separate ...
2456
2457
  	parent_buffer = parent->buffer -
  		binder_alloc_get_user_buffer_offset(&target_proc->alloc);
1c363eaec   Arnd Bergmann   android: binder: ...
2458
  	fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
def95c735   Martijn Coenen   binder: Add suppo...
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
  	if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) {
  		binder_user_error("%d:%d parent offset not aligned correctly.
  ",
  				  proc->pid, thread->pid);
  		return -EINVAL;
  	}
  	for (fdi = 0; fdi < fda->num_fds; fdi++) {
  		target_fd = binder_translate_fd(fd_array[fdi], t, thread,
  						in_reply_to);
  		if (target_fd < 0)
  			goto err_translate_fd_failed;
  		fd_array[fdi] = target_fd;
  	}
  	return 0;
  
  err_translate_fd_failed:
  	/*
  	 * Failed to allocate fd or security error, free fds
  	 * installed so far.
  	 */
  	num_installed_fds = fdi;
  	for (fdi = 0; fdi < num_installed_fds; fdi++)
  		task_close_fd(target_proc, fd_array[fdi]);
  	return target_fd;
  }
7980240b6   Martijn Coenen   binder: Add suppo...
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
  static int binder_fixup_parent(struct binder_transaction *t,
  			       struct binder_thread *thread,
  			       struct binder_buffer_object *bp,
  			       binder_size_t *off_start,
  			       binder_size_t num_valid,
  			       struct binder_buffer_object *last_fixup_obj,
  			       binder_size_t last_fixup_min_off)
  {
  	struct binder_buffer_object *parent;
  	u8 *parent_buffer;
  	struct binder_buffer *b = t->buffer;
  	struct binder_proc *proc = thread->proc;
  	struct binder_proc *target_proc = t->to_proc;
  
  	if (!(bp->flags & BINDER_BUFFER_FLAG_HAS_PARENT))
  		return 0;
  
  	parent = binder_validate_ptr(b, bp->parent, off_start, num_valid);
  	if (!parent) {
  		binder_user_error("%d:%d got transaction with invalid parent offset or type
  ",
  				  proc->pid, thread->pid);
  		return -EINVAL;
  	}
  
  	if (!binder_validate_fixup(b, off_start,
  				   parent, bp->parent_offset,
  				   last_fixup_obj,
  				   last_fixup_min_off)) {
  		binder_user_error("%d:%d got transaction with out-of-order buffer fixup
  ",
  				  proc->pid, thread->pid);
  		return -EINVAL;
  	}
  
  	if (parent->length < sizeof(binder_uintptr_t) ||
  	    bp->parent_offset > parent->length - sizeof(binder_uintptr_t)) {
  		/* No space for a pointer here! */
  		binder_user_error("%d:%d got transaction with invalid parent offset
  ",
  				  proc->pid, thread->pid);
  		return -EINVAL;
  	}
1c363eaec   Arnd Bergmann   android: binder: ...
2527
  	parent_buffer = (u8 *)((uintptr_t)parent->buffer -
19c987241   Todd Kjos   binder: separate ...
2528
2529
  			binder_alloc_get_user_buffer_offset(
  				&target_proc->alloc));
7980240b6   Martijn Coenen   binder: Add suppo...
2530
2531
2532
2533
  	*(binder_uintptr_t *)(parent_buffer + bp->parent_offset) = bp->buffer;
  
  	return 0;
  }
408c68b17   Martijn Coenen   ANDROID: binder: ...
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
  /**
   * binder_proc_transaction() - sends a transaction to a process and wakes it up
   * @t:		transaction to send
   * @proc:	process to send the transaction to
   * @thread:	thread in @proc to send the transaction to (may be NULL)
   *
   * This function queues a transaction to the specified process. It will try
   * to find a thread in the target process to handle the transaction and
   * wake it up. If no thread is found, the work is queued to the proc
   * waitqueue.
   *
   * If the @thread parameter is not NULL, the transaction is always queued
   * to the waitlist of that specific thread.
   *
   * Return:	true if the transactions was successfully queued
   *		false if the target process or thread is dead
   */
  static bool binder_proc_transaction(struct binder_transaction *t,
  				    struct binder_proc *proc,
  				    struct binder_thread *thread)
  {
  	struct list_head *target_list = NULL;
  	struct binder_node *node = t->buffer->target_node;
  	bool oneway = !!(t->flags & TF_ONE_WAY);
  	bool wakeup = true;
  
  	BUG_ON(!node);
  	binder_node_lock(node);
  	if (oneway) {
  		BUG_ON(thread);
  		if (node->has_async_transaction) {
  			target_list = &node->async_todo;
  			wakeup = false;
  		} else {
  			node->has_async_transaction = 1;
  		}
  	}
  
  	binder_inner_proc_lock(proc);
  
  	if (proc->is_dead || (thread && thread->is_dead)) {
  		binder_inner_proc_unlock(proc);
  		binder_node_unlock(node);
  		return false;
  	}
  
  	if (!thread && !target_list)
  		thread = binder_select_thread_ilocked(proc);
  
  	if (thread)
  		target_list = &thread->todo;
  	else if (!target_list)
  		target_list = &proc->todo;
  	else
  		BUG_ON(target_list != &node->async_todo);
  
  	binder_enqueue_work_ilocked(&t->work, target_list);
  
  	if (wakeup)
  		binder_wakeup_thread_ilocked(proc, thread, !oneway /* sync */);
  
  	binder_inner_proc_unlock(proc);
  	binder_node_unlock(node);
  
  	return true;
  }
512cf465e   Todd Kjos   binder: fix use-a...
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
  /**
   * binder_get_node_refs_for_txn() - Get required refs on node for txn
   * @node:         struct binder_node for which to get refs
   * @proc:         returns @node->proc if valid
   * @error:        if no @proc then returns BR_DEAD_REPLY
   *
   * User-space normally keeps the node alive when creating a transaction
   * since it has a reference to the target. The local strong ref keeps it
   * alive if the sending process dies before the target process processes
   * the transaction. If the source process is malicious or has a reference
   * counting bug, relying on the local strong ref can fail.
   *
   * Since user-space can cause the local strong ref to go away, we also take
   * a tmpref on the node to ensure it survives while we are constructing
   * the transaction. We also need a tmpref on the proc while we are
   * constructing the transaction, so we take that here as well.
   *
   * Return: The target_node with refs taken or NULL if no @node->proc is NULL.
   * Also sets @proc if valid. If the @node->proc is NULL indicating that the
   * target proc has died, @error is set to BR_DEAD_REPLY
   */
  static struct binder_node *binder_get_node_refs_for_txn(
  		struct binder_node *node,
  		struct binder_proc **procp,
  		uint32_t *error)
  {
  	struct binder_node *target_node = NULL;
  
  	binder_node_inner_lock(node);
  	if (node->proc) {
  		target_node = node;
  		binder_inc_node_nilocked(node, 1, 0, NULL);
  		binder_inc_node_tmpref_ilocked(node);
  		node->proc->tmp_ref++;
  		*procp = node->proc;
  	} else
  		*error = BR_DEAD_REPLY;
  	binder_node_inner_unlock(node);
  
  	return target_node;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2641
2642
  static void binder_transaction(struct binder_proc *proc,
  			       struct binder_thread *thread,
4bfac80af   Martijn Coenen   binder: Add extra...
2643
2644
  			       struct binder_transaction_data *tr, int reply,
  			       binder_size_t extra_buffers_size)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2645
  {
a056af420   Martijn Coenen   binder: Refactor ...
2646
  	int ret;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2647
2648
  	struct binder_transaction *t;
  	struct binder_work *tcomplete;
7980240b6   Martijn Coenen   binder: Add suppo...
2649
  	binder_size_t *offp, *off_end, *off_start;
212265e5a   Arve Hjønnevåg   android: binder: ...
2650
  	binder_size_t off_min;
7980240b6   Martijn Coenen   binder: Add suppo...
2651
  	u8 *sg_bufp, *sg_buf_end;
7a4408c6b   Todd Kjos   binder: make sure...
2652
  	struct binder_proc *target_proc = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2653
2654
  	struct binder_thread *target_thread = NULL;
  	struct binder_node *target_node = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2655
2656
  	struct binder_transaction *in_reply_to = NULL;
  	struct binder_transaction_log_entry *e;
57ada2fb2   Todd Kjos   binder: add log i...
2657
2658
2659
  	uint32_t return_error = 0;
  	uint32_t return_error_param = 0;
  	uint32_t return_error_line = 0;
7980240b6   Martijn Coenen   binder: Add suppo...
2660
2661
  	struct binder_buffer_object *last_fixup_obj = NULL;
  	binder_size_t last_fixup_min_off = 0;
342e5c90b   Martijn Coenen   binder: Support m...
2662
  	struct binder_context *context = proc->context;
d99c7333a   Todd Kjos   binder: use atomi...
2663
  	int t_debug_id = atomic_inc_return(&binder_last_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2664
2665
  
  	e = binder_transaction_log_add(&binder_transaction_log);
d99c7333a   Todd Kjos   binder: use atomi...
2666
  	e->debug_id = t_debug_id;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2667
2668
2669
2670
2671
2672
  	e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
  	e->from_proc = proc->pid;
  	e->from_thread = thread->pid;
  	e->target_handle = tr->target.handle;
  	e->data_size = tr->data_size;
  	e->offsets_size = tr->offsets_size;
14db31814   Martijn Coenen   binder: Deal with...
2673
  	e->context_name = proc->context->name;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2674
2675
  
  	if (reply) {
0b89d69a9   Martijn Coenen   binder: protect t...
2676
  		binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2677
2678
  		in_reply_to = thread->transaction_stack;
  		if (in_reply_to == NULL) {
0b89d69a9   Martijn Coenen   binder: protect t...
2679
  			binder_inner_proc_unlock(proc);
56b468fc7   Anmol Sarma   Staging: android:...
2680
2681
  			binder_user_error("%d:%d got reply transaction with no transaction stack
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2682
2683
  					  proc->pid, thread->pid);
  			return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2684
2685
  			return_error_param = -EPROTO;
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2686
2687
  			goto err_empty_call_stack;
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2688
  		if (in_reply_to->to_thread != thread) {
7a4408c6b   Todd Kjos   binder: make sure...
2689
  			spin_lock(&in_reply_to->lock);
56b468fc7   Anmol Sarma   Staging: android:...
2690
2691
  			binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2692
2693
2694
2695
2696
  				proc->pid, thread->pid, in_reply_to->debug_id,
  				in_reply_to->to_proc ?
  				in_reply_to->to_proc->pid : 0,
  				in_reply_to->to_thread ?
  				in_reply_to->to_thread->pid : 0);
7a4408c6b   Todd Kjos   binder: make sure...
2697
  			spin_unlock(&in_reply_to->lock);
0b89d69a9   Martijn Coenen   binder: protect t...
2698
  			binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2699
  			return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2700
2701
  			return_error_param = -EPROTO;
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2702
2703
2704
2705
  			in_reply_to = NULL;
  			goto err_bad_call_stack;
  		}
  		thread->transaction_stack = in_reply_to->to_parent;
0b89d69a9   Martijn Coenen   binder: protect t...
2706
2707
2708
  		binder_inner_proc_unlock(proc);
  		binder_set_nice(in_reply_to->saved_priority);
  		target_thread = binder_get_txn_from_and_acq_inner(in_reply_to);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2709
2710
  		if (target_thread == NULL) {
  			return_error = BR_DEAD_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2711
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2712
2713
2714
  			goto err_dead_binder;
  		}
  		if (target_thread->transaction_stack != in_reply_to) {
56b468fc7   Anmol Sarma   Staging: android:...
2715
2716
  			binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2717
2718
2719
2720
  				proc->pid, thread->pid,
  				target_thread->transaction_stack ?
  				target_thread->transaction_stack->debug_id : 0,
  				in_reply_to->debug_id);
0b89d69a9   Martijn Coenen   binder: protect t...
2721
  			binder_inner_proc_unlock(target_thread->proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2722
  			return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2723
2724
  			return_error_param = -EPROTO;
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2725
2726
2727
2728
2729
  			in_reply_to = NULL;
  			target_thread = NULL;
  			goto err_dead_binder;
  		}
  		target_proc = target_thread->proc;
7a4408c6b   Todd Kjos   binder: make sure...
2730
  		target_proc->tmp_ref++;
0b89d69a9   Martijn Coenen   binder: protect t...
2731
  		binder_inner_proc_unlock(target_thread->proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2732
2733
2734
  	} else {
  		if (tr->target.handle) {
  			struct binder_ref *ref;
10f62861b   Seunghun Lee   staging: android:...
2735

eb34983ba   Todd Kjos   binder: make sure...
2736
2737
2738
2739
2740
2741
2742
  			/*
  			 * There must already be a strong ref
  			 * on this node. If so, do a strong
  			 * increment on the node to ensure it
  			 * stays alive until the transaction is
  			 * done.
  			 */
2c1838dc6   Todd Kjos   binder: protect b...
2743
2744
2745
  			binder_proc_lock(proc);
  			ref = binder_get_ref_olocked(proc, tr->target.handle,
  						     true);
eb34983ba   Todd Kjos   binder: make sure...
2746
  			if (ref) {
512cf465e   Todd Kjos   binder: fix use-a...
2747
2748
2749
2750
  				target_node = binder_get_node_refs_for_txn(
  						ref->node, &target_proc,
  						&return_error);
  			} else {
56b468fc7   Anmol Sarma   Staging: android:...
2751
2752
  				binder_user_error("%d:%d got transaction to invalid handle
  ",
512cf465e   Todd Kjos   binder: fix use-a...
2753
  						  proc->pid, thread->pid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2754
  				return_error = BR_FAILED_REPLY;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2755
  			}
512cf465e   Todd Kjos   binder: fix use-a...
2756
  			binder_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2757
  		} else {
c44b1231f   Todd Kjos   binder: add prote...
2758
  			mutex_lock(&context->context_mgr_node_lock);
342e5c90b   Martijn Coenen   binder: Support m...
2759
  			target_node = context->binder_context_mgr_node;
512cf465e   Todd Kjos   binder: fix use-a...
2760
2761
2762
2763
2764
  			if (target_node)
  				target_node = binder_get_node_refs_for_txn(
  						target_node, &target_proc,
  						&return_error);
  			else
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2765
  				return_error = BR_DEAD_REPLY;
c44b1231f   Todd Kjos   binder: add prote...
2766
  			mutex_unlock(&context->context_mgr_node_lock);
fd0485e2c   Martijn Coenen   ANDROID: binder: ...
2767
2768
2769
2770
2771
2772
2773
2774
2775
  			if (target_node && target_proc == proc) {
  				binder_user_error("%d:%d got transaction to context manager from process owning it
  ",
  						  proc->pid, thread->pid);
  				return_error = BR_FAILED_REPLY;
  				return_error_param = -EINVAL;
  				return_error_line = __LINE__;
  				goto err_invalid_target_handle;
  			}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2776
  		}
512cf465e   Todd Kjos   binder: fix use-a...
2777
2778
2779
2780
2781
  		if (!target_node) {
  			/*
  			 * return_error is set above
  			 */
  			return_error_param = -EINVAL;
57ada2fb2   Todd Kjos   binder: add log i...
2782
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2783
2784
  			goto err_dead_binder;
  		}
512cf465e   Todd Kjos   binder: fix use-a...
2785
  		e->to_node = target_node->debug_id;
79af73079   Stephen Smalley   Add security hook...
2786
2787
2788
  		if (security_binder_transaction(proc->tsk,
  						target_proc->tsk) < 0) {
  			return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2789
2790
  			return_error_param = -EPERM;
  			return_error_line = __LINE__;
79af73079   Stephen Smalley   Add security hook...
2791
2792
  			goto err_invalid_target_handle;
  		}
0b89d69a9   Martijn Coenen   binder: protect t...
2793
  		binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2794
2795
  		if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
  			struct binder_transaction *tmp;
10f62861b   Seunghun Lee   staging: android:...
2796

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2797
2798
  			tmp = thread->transaction_stack;
  			if (tmp->to_thread != thread) {
7a4408c6b   Todd Kjos   binder: make sure...
2799
  				spin_lock(&tmp->lock);
56b468fc7   Anmol Sarma   Staging: android:...
2800
2801
  				binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2802
2803
2804
2805
  					proc->pid, thread->pid, tmp->debug_id,
  					tmp->to_proc ? tmp->to_proc->pid : 0,
  					tmp->to_thread ?
  					tmp->to_thread->pid : 0);
7a4408c6b   Todd Kjos   binder: make sure...
2806
  				spin_unlock(&tmp->lock);
0b89d69a9   Martijn Coenen   binder: protect t...
2807
  				binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2808
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2809
2810
  				return_error_param = -EPROTO;
  				return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2811
2812
2813
  				goto err_bad_call_stack;
  			}
  			while (tmp) {
7a4408c6b   Todd Kjos   binder: make sure...
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
  				struct binder_thread *from;
  
  				spin_lock(&tmp->lock);
  				from = tmp->from;
  				if (from && from->proc == target_proc) {
  					atomic_inc(&from->tmp_ref);
  					target_thread = from;
  					spin_unlock(&tmp->lock);
  					break;
  				}
  				spin_unlock(&tmp->lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2825
2826
2827
  				tmp = tmp->from_parent;
  			}
  		}
0b89d69a9   Martijn Coenen   binder: protect t...
2828
  		binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2829
  	}
408c68b17   Martijn Coenen   ANDROID: binder: ...
2830
  	if (target_thread)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2831
  		e->to_thread = target_thread->pid;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2832
2833
2834
2835
2836
2837
  	e->to_proc = target_proc->pid;
  
  	/* TODO: reuse incoming transaction for reply */
  	t = kzalloc(sizeof(*t), GFP_KERNEL);
  	if (t == NULL) {
  		return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2838
2839
  		return_error_param = -ENOMEM;
  		return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2840
2841
2842
  		goto err_alloc_t_failed;
  	}
  	binder_stats_created(BINDER_STAT_TRANSACTION);
7a4408c6b   Todd Kjos   binder: make sure...
2843
  	spin_lock_init(&t->lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2844
2845
2846
2847
  
  	tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
  	if (tcomplete == NULL) {
  		return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2848
2849
  		return_error_param = -ENOMEM;
  		return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2850
2851
2852
  		goto err_alloc_tcomplete_failed;
  	}
  	binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
d99c7333a   Todd Kjos   binder: use atomi...
2853
  	t->debug_id = t_debug_id;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2854
2855
2856
  
  	if (reply)
  		binder_debug(BINDER_DEBUG_TRANSACTION,
4bfac80af   Martijn Coenen   binder: Add extra...
2857
2858
  			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld-%lld
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2859
2860
  			     proc->pid, thread->pid, t->debug_id,
  			     target_proc->pid, target_thread->pid,
da49889de   Arve Hjønnevåg   staging: binder: ...
2861
2862
  			     (u64)tr->data.ptr.buffer,
  			     (u64)tr->data.ptr.offsets,
4bfac80af   Martijn Coenen   binder: Add extra...
2863
2864
  			     (u64)tr->data_size, (u64)tr->offsets_size,
  			     (u64)extra_buffers_size);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2865
2866
  	else
  		binder_debug(BINDER_DEBUG_TRANSACTION,
4bfac80af   Martijn Coenen   binder: Add extra...
2867
2868
  			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld-%lld
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2869
2870
  			     proc->pid, thread->pid, t->debug_id,
  			     target_proc->pid, target_node->debug_id,
da49889de   Arve Hjønnevåg   staging: binder: ...
2871
2872
  			     (u64)tr->data.ptr.buffer,
  			     (u64)tr->data.ptr.offsets,
4bfac80af   Martijn Coenen   binder: Add extra...
2873
2874
  			     (u64)tr->data_size, (u64)tr->offsets_size,
  			     (u64)extra_buffers_size);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2875
2876
2877
2878
2879
  
  	if (!reply && !(tr->flags & TF_ONE_WAY))
  		t->from = thread;
  	else
  		t->from = NULL;
57bab7cb3   Tair Rzayev   staging: android:...
2880
  	t->sender_euid = task_euid(proc->tsk);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2881
2882
2883
2884
2885
  	t->to_proc = target_proc;
  	t->to_thread = target_thread;
  	t->code = tr->code;
  	t->flags = tr->flags;
  	t->priority = task_nice(current);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
2886
2887
  
  	trace_binder_transaction(reply, t, target_node);
19c987241   Todd Kjos   binder: separate ...
2888
  	t->buffer = binder_alloc_new_buf(&target_proc->alloc, tr->data_size,
4bfac80af   Martijn Coenen   binder: Add extra...
2889
2890
  		tr->offsets_size, extra_buffers_size,
  		!reply && (t->flags & TF_ONE_WAY));
57ada2fb2   Todd Kjos   binder: add log i...
2891
2892
2893
2894
2895
2896
2897
2898
2899
  	if (IS_ERR(t->buffer)) {
  		/*
  		 * -ESRCH indicates VMA cleared. The target is dying.
  		 */
  		return_error_param = PTR_ERR(t->buffer);
  		return_error = return_error_param == -ESRCH ?
  			BR_DEAD_REPLY : BR_FAILED_REPLY;
  		return_error_line = __LINE__;
  		t->buffer = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2900
2901
  		goto err_binder_alloc_buf_failed;
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2902
2903
2904
  	t->buffer->debug_id = t->debug_id;
  	t->buffer->transaction = t;
  	t->buffer->target_node = target_node;
975a1ac9a   Arve Hjønnevåg   Staging: android:...
2905
  	trace_binder_transaction_alloc_buf(t->buffer);
7980240b6   Martijn Coenen   binder: Add suppo...
2906
2907
2908
  	off_start = (binder_size_t *)(t->buffer->data +
  				      ALIGN(tr->data_size, sizeof(void *)));
  	offp = off_start;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2909

da49889de   Arve Hjønnevåg   staging: binder: ...
2910
2911
  	if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
  			   tr->data.ptr.buffer, tr->data_size)) {
56b468fc7   Anmol Sarma   Staging: android:...
2912
2913
2914
  		binder_user_error("%d:%d got transaction with invalid data ptr
  ",
  				proc->pid, thread->pid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2915
  		return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2916
2917
  		return_error_param = -EFAULT;
  		return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2918
2919
  		goto err_copy_data_failed;
  	}
da49889de   Arve Hjønnevåg   staging: binder: ...
2920
2921
  	if (copy_from_user(offp, (const void __user *)(uintptr_t)
  			   tr->data.ptr.offsets, tr->offsets_size)) {
56b468fc7   Anmol Sarma   Staging: android:...
2922
2923
2924
  		binder_user_error("%d:%d got transaction with invalid offsets ptr
  ",
  				proc->pid, thread->pid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2925
  		return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2926
2927
  		return_error_param = -EFAULT;
  		return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2928
2929
  		goto err_copy_data_failed;
  	}
da49889de   Arve Hjønnevåg   staging: binder: ...
2930
2931
2932
2933
  	if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) {
  		binder_user_error("%d:%d got transaction with invalid offsets size, %lld
  ",
  				proc->pid, thread->pid, (u64)tr->offsets_size);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2934
  		return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2935
2936
  		return_error_param = -EINVAL;
  		return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2937
2938
  		goto err_bad_offset;
  	}
7980240b6   Martijn Coenen   binder: Add suppo...
2939
2940
2941
2942
2943
2944
  	if (!IS_ALIGNED(extra_buffers_size, sizeof(u64))) {
  		binder_user_error("%d:%d got transaction with unaligned buffers size, %lld
  ",
  				  proc->pid, thread->pid,
  				  (u64)extra_buffers_size);
  		return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2945
2946
  		return_error_param = -EINVAL;
  		return_error_line = __LINE__;
7980240b6   Martijn Coenen   binder: Add suppo...
2947
2948
2949
2950
2951
  		goto err_bad_offset;
  	}
  	off_end = (void *)off_start + tr->offsets_size;
  	sg_bufp = (u8 *)(PTR_ALIGN(off_end, sizeof(void *)));
  	sg_buf_end = sg_bufp + extra_buffers_size;
212265e5a   Arve Hjønnevåg   android: binder: ...
2952
  	off_min = 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2953
  	for (; offp < off_end; offp++) {
feba3900c   Martijn Coenen   binder: Split fla...
2954
2955
  		struct binder_object_header *hdr;
  		size_t object_size = binder_validate_object(t->buffer, *offp);
10f62861b   Seunghun Lee   staging: android:...
2956

feba3900c   Martijn Coenen   binder: Split fla...
2957
2958
2959
  		if (object_size == 0 || *offp < off_min) {
  			binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.
  ",
212265e5a   Arve Hjønnevåg   android: binder: ...
2960
2961
  					  proc->pid, thread->pid, (u64)*offp,
  					  (u64)off_min,
feba3900c   Martijn Coenen   binder: Split fla...
2962
  					  (u64)t->buffer->data_size);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2963
  			return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2964
2965
  			return_error_param = -EINVAL;
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2966
2967
  			goto err_bad_offset;
  		}
feba3900c   Martijn Coenen   binder: Split fla...
2968
2969
2970
2971
  
  		hdr = (struct binder_object_header *)(t->buffer->data + *offp);
  		off_min = *offp + object_size;
  		switch (hdr->type) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2972
2973
  		case BINDER_TYPE_BINDER:
  		case BINDER_TYPE_WEAK_BINDER: {
feba3900c   Martijn Coenen   binder: Split fla...
2974
  			struct flat_binder_object *fp;
10f62861b   Seunghun Lee   staging: android:...
2975

feba3900c   Martijn Coenen   binder: Split fla...
2976
  			fp = to_flat_binder_object(hdr);
a056af420   Martijn Coenen   binder: Refactor ...
2977
2978
  			ret = binder_translate_binder(fp, t, thread);
  			if (ret < 0) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2979
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2980
2981
  				return_error_param = ret;
  				return_error_line = __LINE__;
a056af420   Martijn Coenen   binder: Refactor ...
2982
  				goto err_translate_failed;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2983
  			}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2984
2985
2986
  		} break;
  		case BINDER_TYPE_HANDLE:
  		case BINDER_TYPE_WEAK_HANDLE: {
feba3900c   Martijn Coenen   binder: Split fla...
2987
  			struct flat_binder_object *fp;
0a3ffab93   Arve Hjønnevåg   ANDROID: binder: ...
2988

feba3900c   Martijn Coenen   binder: Split fla...
2989
  			fp = to_flat_binder_object(hdr);
a056af420   Martijn Coenen   binder: Refactor ...
2990
2991
  			ret = binder_translate_handle(fp, t, thread);
  			if (ret < 0) {
79af73079   Stephen Smalley   Add security hook...
2992
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
2993
2994
  				return_error_param = ret;
  				return_error_line = __LINE__;
a056af420   Martijn Coenen   binder: Refactor ...
2995
  				goto err_translate_failed;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
2996
2997
2998
2999
  			}
  		} break;
  
  		case BINDER_TYPE_FD: {
feba3900c   Martijn Coenen   binder: Split fla...
3000
  			struct binder_fd_object *fp = to_binder_fd_object(hdr);
a056af420   Martijn Coenen   binder: Refactor ...
3001
3002
  			int target_fd = binder_translate_fd(fp->fd, t, thread,
  							    in_reply_to);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3003

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3004
  			if (target_fd < 0) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3005
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3006
3007
  				return_error_param = target_fd;
  				return_error_line = __LINE__;
a056af420   Martijn Coenen   binder: Refactor ...
3008
  				goto err_translate_failed;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3009
  			}
feba3900c   Martijn Coenen   binder: Split fla...
3010
3011
  			fp->pad_binder = 0;
  			fp->fd = target_fd;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3012
  		} break;
def95c735   Martijn Coenen   binder: Add suppo...
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
  		case BINDER_TYPE_FDA: {
  			struct binder_fd_array_object *fda =
  				to_binder_fd_array_object(hdr);
  			struct binder_buffer_object *parent =
  				binder_validate_ptr(t->buffer, fda->parent,
  						    off_start,
  						    offp - off_start);
  			if (!parent) {
  				binder_user_error("%d:%d got transaction with invalid parent offset or type
  ",
  						  proc->pid, thread->pid);
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3025
3026
  				return_error_param = -EINVAL;
  				return_error_line = __LINE__;
def95c735   Martijn Coenen   binder: Add suppo...
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
  				goto err_bad_parent;
  			}
  			if (!binder_validate_fixup(t->buffer, off_start,
  						   parent, fda->parent_offset,
  						   last_fixup_obj,
  						   last_fixup_min_off)) {
  				binder_user_error("%d:%d got transaction with out-of-order buffer fixup
  ",
  						  proc->pid, thread->pid);
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3037
3038
  				return_error_param = -EINVAL;
  				return_error_line = __LINE__;
def95c735   Martijn Coenen   binder: Add suppo...
3039
3040
3041
3042
3043
3044
  				goto err_bad_parent;
  			}
  			ret = binder_translate_fd_array(fda, parent, t, thread,
  							in_reply_to);
  			if (ret < 0) {
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3045
3046
  				return_error_param = ret;
  				return_error_line = __LINE__;
def95c735   Martijn Coenen   binder: Add suppo...
3047
3048
3049
3050
3051
3052
  				goto err_translate_failed;
  			}
  			last_fixup_obj = parent;
  			last_fixup_min_off =
  				fda->parent_offset + sizeof(u32) * fda->num_fds;
  		} break;
7980240b6   Martijn Coenen   binder: Add suppo...
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
  		case BINDER_TYPE_PTR: {
  			struct binder_buffer_object *bp =
  				to_binder_buffer_object(hdr);
  			size_t buf_left = sg_buf_end - sg_bufp;
  
  			if (bp->length > buf_left) {
  				binder_user_error("%d:%d got transaction with too large buffer
  ",
  						  proc->pid, thread->pid);
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3063
3064
  				return_error_param = -EINVAL;
  				return_error_line = __LINE__;
7980240b6   Martijn Coenen   binder: Add suppo...
3065
3066
3067
3068
3069
3070
3071
3072
  				goto err_bad_offset;
  			}
  			if (copy_from_user(sg_bufp,
  					   (const void __user *)(uintptr_t)
  					   bp->buffer, bp->length)) {
  				binder_user_error("%d:%d got transaction with invalid offsets ptr
  ",
  						  proc->pid, thread->pid);
57ada2fb2   Todd Kjos   binder: add log i...
3073
  				return_error_param = -EFAULT;
7980240b6   Martijn Coenen   binder: Add suppo...
3074
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3075
  				return_error_line = __LINE__;
7980240b6   Martijn Coenen   binder: Add suppo...
3076
3077
3078
3079
  				goto err_copy_data_failed;
  			}
  			/* Fixup buffer pointer to target proc address space */
  			bp->buffer = (uintptr_t)sg_bufp +
19c987241   Todd Kjos   binder: separate ...
3080
3081
  				binder_alloc_get_user_buffer_offset(
  						&target_proc->alloc);
7980240b6   Martijn Coenen   binder: Add suppo...
3082
3083
3084
3085
3086
3087
3088
3089
  			sg_bufp += ALIGN(bp->length, sizeof(u64));
  
  			ret = binder_fixup_parent(t, thread, bp, off_start,
  						  offp - off_start,
  						  last_fixup_obj,
  						  last_fixup_min_off);
  			if (ret < 0) {
  				return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3090
3091
  				return_error_param = ret;
  				return_error_line = __LINE__;
7980240b6   Martijn Coenen   binder: Add suppo...
3092
3093
3094
3095
3096
  				goto err_translate_failed;
  			}
  			last_fixup_obj = bp;
  			last_fixup_min_off = 0;
  		} break;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3097
  		default:
64dcfe6b8   Serban Constantinescu   staging: android:...
3098
3099
  			binder_user_error("%d:%d got transaction with invalid object type, %x
  ",
feba3900c   Martijn Coenen   binder: Split fla...
3100
  				proc->pid, thread->pid, hdr->type);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3101
  			return_error = BR_FAILED_REPLY;
57ada2fb2   Todd Kjos   binder: add log i...
3102
3103
  			return_error_param = -EINVAL;
  			return_error_line = __LINE__;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3104
3105
3106
  			goto err_bad_object_type;
  		}
  	}
ccae6f676   Todd Kjos   binder: avoid rac...
3107
  	tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
72196393a   Todd Kjos   binder: add spinl...
3108
  	binder_enqueue_work(proc, tcomplete, &thread->todo);
673068eee   Todd Kjos   binder: add spinl...
3109
  	t->work.type = BINDER_WORK_TRANSACTION;
ccae6f676   Todd Kjos   binder: avoid rac...
3110

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3111
  	if (reply) {
0b89d69a9   Martijn Coenen   binder: protect t...
3112
3113
3114
  		binder_inner_proc_lock(target_proc);
  		if (target_thread->is_dead) {
  			binder_inner_proc_unlock(target_proc);
7a4408c6b   Todd Kjos   binder: make sure...
3115
  			goto err_dead_proc_or_thread;
0b89d69a9   Martijn Coenen   binder: protect t...
3116
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3117
  		BUG_ON(t->buffer->async_transaction != 0);
0b89d69a9   Martijn Coenen   binder: protect t...
3118
  		binder_pop_transaction_ilocked(target_thread, in_reply_to);
408c68b17   Martijn Coenen   ANDROID: binder: ...
3119
  		binder_enqueue_work_ilocked(&t->work, &target_thread->todo);
0b89d69a9   Martijn Coenen   binder: protect t...
3120
  		binder_inner_proc_unlock(target_proc);
408c68b17   Martijn Coenen   ANDROID: binder: ...
3121
  		wake_up_interruptible_sync(&target_thread->wait);
b6d282cea   Todd Kjos   binder: refactor ...
3122
  		binder_free_transaction(in_reply_to);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3123
3124
  	} else if (!(t->flags & TF_ONE_WAY)) {
  		BUG_ON(t->buffer->async_transaction != 0);
0b89d69a9   Martijn Coenen   binder: protect t...
3125
  		binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3126
3127
3128
  		t->need_reply = 1;
  		t->from_parent = thread->transaction_stack;
  		thread->transaction_stack = t;
0b89d69a9   Martijn Coenen   binder: protect t...
3129
  		binder_inner_proc_unlock(proc);
408c68b17   Martijn Coenen   ANDROID: binder: ...
3130
  		if (!binder_proc_transaction(t, target_proc, target_thread)) {
0b89d69a9   Martijn Coenen   binder: protect t...
3131
3132
3133
  			binder_inner_proc_lock(proc);
  			binder_pop_transaction_ilocked(thread, t);
  			binder_inner_proc_unlock(proc);
7a4408c6b   Todd Kjos   binder: make sure...
3134
3135
  			goto err_dead_proc_or_thread;
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3136
3137
3138
  	} else {
  		BUG_ON(target_node == NULL);
  		BUG_ON(t->buffer->async_transaction != 1);
408c68b17   Martijn Coenen   ANDROID: binder: ...
3139
  		if (!binder_proc_transaction(t, target_proc, NULL))
7a4408c6b   Todd Kjos   binder: make sure...
3140
  			goto err_dead_proc_or_thread;
00b40d613   Riley Andrews   binder: Use wake ...
3141
  	}
7a4408c6b   Todd Kjos   binder: make sure...
3142
3143
3144
  	if (target_thread)
  		binder_thread_dec_tmpref(target_thread);
  	binder_proc_dec_tmpref(target_proc);
512cf465e   Todd Kjos   binder: fix use-a...
3145
3146
  	if (target_node)
  		binder_dec_node_tmpref(target_node);
d99c7333a   Todd Kjos   binder: use atomi...
3147
3148
3149
3150
3151
3152
  	/*
  	 * write barrier to synchronize with initialization
  	 * of log entry
  	 */
  	smp_wmb();
  	WRITE_ONCE(e->debug_id_done, t_debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3153
  	return;
7a4408c6b   Todd Kjos   binder: make sure...
3154
3155
3156
  err_dead_proc_or_thread:
  	return_error = BR_DEAD_REPLY;
  	return_error_line = __LINE__;
d53bebdf4   Xu YiPing   binder: fix memor...
3157
  	binder_dequeue_work(proc, tcomplete);
a056af420   Martijn Coenen   binder: Refactor ...
3158
  err_translate_failed:
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3159
3160
  err_bad_object_type:
  err_bad_offset:
def95c735   Martijn Coenen   binder: Add suppo...
3161
  err_bad_parent:
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3162
  err_copy_data_failed:
975a1ac9a   Arve Hjønnevåg   Staging: android:...
3163
  	trace_binder_transaction_failed_buffer_release(t->buffer);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3164
  	binder_transaction_buffer_release(target_proc, t->buffer, offp);
512cf465e   Todd Kjos   binder: fix use-a...
3165
3166
  	if (target_node)
  		binder_dec_node_tmpref(target_node);
eb34983ba   Todd Kjos   binder: make sure...
3167
  	target_node = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3168
  	t->buffer->transaction = NULL;
19c987241   Todd Kjos   binder: separate ...
3169
  	binder_alloc_free_buf(&target_proc->alloc, t->buffer);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
  err_binder_alloc_buf_failed:
  	kfree(tcomplete);
  	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
  err_alloc_tcomplete_failed:
  	kfree(t);
  	binder_stats_deleted(BINDER_STAT_TRANSACTION);
  err_alloc_t_failed:
  err_bad_call_stack:
  err_empty_call_stack:
  err_dead_binder:
  err_invalid_target_handle:
7a4408c6b   Todd Kjos   binder: make sure...
3181
3182
3183
3184
  	if (target_thread)
  		binder_thread_dec_tmpref(target_thread);
  	if (target_proc)
  		binder_proc_dec_tmpref(target_proc);
512cf465e   Todd Kjos   binder: fix use-a...
3185
  	if (target_node) {
eb34983ba   Todd Kjos   binder: make sure...
3186
  		binder_dec_node(target_node, 1, 0);
512cf465e   Todd Kjos   binder: fix use-a...
3187
3188
  		binder_dec_node_tmpref(target_node);
  	}
eb34983ba   Todd Kjos   binder: make sure...
3189

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3190
  	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
57ada2fb2   Todd Kjos   binder: add log i...
3191
3192
3193
3194
3195
  		     "%d:%d transaction failed %d/%d, size %lld-%lld line %d
  ",
  		     proc->pid, thread->pid, return_error, return_error_param,
  		     (u64)tr->data_size, (u64)tr->offsets_size,
  		     return_error_line);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3196
3197
3198
  
  	{
  		struct binder_transaction_log_entry *fe;
10f62861b   Seunghun Lee   staging: android:...
3199

57ada2fb2   Todd Kjos   binder: add log i...
3200
3201
3202
  		e->return_error = return_error;
  		e->return_error_param = return_error_param;
  		e->return_error_line = return_error_line;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3203
3204
  		fe = binder_transaction_log_add(&binder_transaction_log_failed);
  		*fe = *e;
d99c7333a   Todd Kjos   binder: use atomi...
3205
3206
3207
3208
3209
3210
3211
  		/*
  		 * write barrier to synchronize with initialization
  		 * of log entry
  		 */
  		smp_wmb();
  		WRITE_ONCE(e->debug_id_done, t_debug_id);
  		WRITE_ONCE(fe->debug_id_done, t_debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3212
  	}
26549d177   Todd Kjos   binder: guarantee...
3213
  	BUG_ON(thread->return_error.cmd != BR_OK);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3214
  	if (in_reply_to) {
26549d177   Todd Kjos   binder: guarantee...
3215
  		thread->return_error.cmd = BR_TRANSACTION_COMPLETE;
72196393a   Todd Kjos   binder: add spinl...
3216
3217
3218
  		binder_enqueue_work(thread->proc,
  				    &thread->return_error.work,
  				    &thread->todo);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3219
  		binder_send_failed_reply(in_reply_to, return_error);
26549d177   Todd Kjos   binder: guarantee...
3220
3221
  	} else {
  		thread->return_error.cmd = return_error;
72196393a   Todd Kjos   binder: add spinl...
3222
3223
3224
  		binder_enqueue_work(thread->proc,
  				    &thread->return_error.work,
  				    &thread->todo);
26549d177   Todd Kjos   binder: guarantee...
3225
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3226
  }
fb07ebc3e   Bojan Prtvar   Staging: android:...
3227
3228
  static int binder_thread_write(struct binder_proc *proc,
  			struct binder_thread *thread,
da49889de   Arve Hjønnevåg   staging: binder: ...
3229
3230
  			binder_uintptr_t binder_buffer, size_t size,
  			binder_size_t *consumed)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3231
3232
  {
  	uint32_t cmd;
342e5c90b   Martijn Coenen   binder: Support m...
3233
  	struct binder_context *context = proc->context;
da49889de   Arve Hjønnevåg   staging: binder: ...
3234
  	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3235
3236
  	void __user *ptr = buffer + *consumed;
  	void __user *end = buffer + size;
26549d177   Todd Kjos   binder: guarantee...
3237
  	while (ptr < end && thread->return_error.cmd == BR_OK) {
372e3147d   Todd Kjos   binder: refactor ...
3238
  		int ret;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3239
3240
3241
  		if (get_user(cmd, (uint32_t __user *)ptr))
  			return -EFAULT;
  		ptr += sizeof(uint32_t);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
3242
  		trace_binder_command(cmd);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3243
  		if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
3244
3245
3246
  			atomic_inc(&binder_stats.bc[_IOC_NR(cmd)]);
  			atomic_inc(&proc->stats.bc[_IOC_NR(cmd)]);
  			atomic_inc(&thread->stats.bc[_IOC_NR(cmd)]);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3247
3248
3249
3250
3251
3252
3253
  		}
  		switch (cmd) {
  		case BC_INCREFS:
  		case BC_ACQUIRE:
  		case BC_RELEASE:
  		case BC_DECREFS: {
  			uint32_t target;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3254
  			const char *debug_string;
372e3147d   Todd Kjos   binder: refactor ...
3255
3256
3257
  			bool strong = cmd == BC_ACQUIRE || cmd == BC_RELEASE;
  			bool increment = cmd == BC_INCREFS || cmd == BC_ACQUIRE;
  			struct binder_ref_data rdata;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3258
3259
3260
  
  			if (get_user(target, (uint32_t __user *)ptr))
  				return -EFAULT;
c44b1231f   Todd Kjos   binder: add prote...
3261

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3262
  			ptr += sizeof(uint32_t);
372e3147d   Todd Kjos   binder: refactor ...
3263
3264
  			ret = -1;
  			if (increment && !target) {
c44b1231f   Todd Kjos   binder: add prote...
3265
  				struct binder_node *ctx_mgr_node;
c44b1231f   Todd Kjos   binder: add prote...
3266
3267
  				mutex_lock(&context->context_mgr_node_lock);
  				ctx_mgr_node = context->binder_context_mgr_node;
372e3147d   Todd Kjos   binder: refactor ...
3268
3269
3270
3271
  				if (ctx_mgr_node)
  					ret = binder_inc_ref_for_node(
  							proc, ctx_mgr_node,
  							strong, NULL, &rdata);
c44b1231f   Todd Kjos   binder: add prote...
3272
3273
  				mutex_unlock(&context->context_mgr_node_lock);
  			}
372e3147d   Todd Kjos   binder: refactor ...
3274
3275
3276
3277
3278
3279
3280
3281
3282
  			if (ret)
  				ret = binder_update_ref_for_handle(
  						proc, target, increment, strong,
  						&rdata);
  			if (!ret && rdata.desc != target) {
  				binder_user_error("%d:%d tried to acquire reference to desc %d, got %d instead
  ",
  					proc->pid, thread->pid,
  					target, rdata.desc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3283
3284
3285
3286
  			}
  			switch (cmd) {
  			case BC_INCREFS:
  				debug_string = "IncRefs";
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3287
3288
3289
  				break;
  			case BC_ACQUIRE:
  				debug_string = "Acquire";
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3290
3291
3292
  				break;
  			case BC_RELEASE:
  				debug_string = "Release";
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3293
3294
3295
3296
  				break;
  			case BC_DECREFS:
  			default:
  				debug_string = "DecRefs";
372e3147d   Todd Kjos   binder: refactor ...
3297
3298
3299
3300
3301
3302
3303
  				break;
  			}
  			if (ret) {
  				binder_user_error("%d:%d %s %d refcount change on invalid ref %d ret %d
  ",
  					proc->pid, thread->pid, debug_string,
  					strong, target, ret);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3304
3305
3306
  				break;
  			}
  			binder_debug(BINDER_DEBUG_USER_REFS,
372e3147d   Todd Kjos   binder: refactor ...
3307
3308
3309
3310
3311
  				     "%d:%d %s ref %d desc %d s %d w %d
  ",
  				     proc->pid, thread->pid, debug_string,
  				     rdata.debug_id, rdata.desc, rdata.strong,
  				     rdata.weak);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3312
3313
3314
3315
  			break;
  		}
  		case BC_INCREFS_DONE:
  		case BC_ACQUIRE_DONE: {
da49889de   Arve Hjønnevåg   staging: binder: ...
3316
3317
  			binder_uintptr_t node_ptr;
  			binder_uintptr_t cookie;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3318
  			struct binder_node *node;
673068eee   Todd Kjos   binder: add spinl...
3319
  			bool free_node;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3320

da49889de   Arve Hjønnevåg   staging: binder: ...
3321
  			if (get_user(node_ptr, (binder_uintptr_t __user *)ptr))
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3322
  				return -EFAULT;
da49889de   Arve Hjønnevåg   staging: binder: ...
3323
3324
  			ptr += sizeof(binder_uintptr_t);
  			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3325
  				return -EFAULT;
da49889de   Arve Hjønnevåg   staging: binder: ...
3326
  			ptr += sizeof(binder_uintptr_t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3327
3328
  			node = binder_get_node(proc, node_ptr);
  			if (node == NULL) {
da49889de   Arve Hjønnevåg   staging: binder: ...
3329
3330
  				binder_user_error("%d:%d %s u%016llx no match
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3331
3332
3333
3334
  					proc->pid, thread->pid,
  					cmd == BC_INCREFS_DONE ?
  					"BC_INCREFS_DONE" :
  					"BC_ACQUIRE_DONE",
da49889de   Arve Hjønnevåg   staging: binder: ...
3335
  					(u64)node_ptr);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3336
3337
3338
  				break;
  			}
  			if (cookie != node->cookie) {
da49889de   Arve Hjønnevåg   staging: binder: ...
3339
3340
  				binder_user_error("%d:%d %s u%016llx node %d cookie mismatch %016llx != %016llx
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3341
3342
3343
  					proc->pid, thread->pid,
  					cmd == BC_INCREFS_DONE ?
  					"BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
da49889de   Arve Hjønnevåg   staging: binder: ...
3344
3345
  					(u64)node_ptr, node->debug_id,
  					(u64)cookie, (u64)node->cookie);
adc188422   Todd Kjos   binder: use node-...
3346
  				binder_put_node(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3347
3348
  				break;
  			}
673068eee   Todd Kjos   binder: add spinl...
3349
  			binder_node_inner_lock(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3350
3351
  			if (cmd == BC_ACQUIRE_DONE) {
  				if (node->pending_strong_ref == 0) {
56b468fc7   Anmol Sarma   Staging: android:...
3352
3353
  					binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no pending acquire request
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3354
3355
  						proc->pid, thread->pid,
  						node->debug_id);
673068eee   Todd Kjos   binder: add spinl...
3356
  					binder_node_inner_unlock(node);
adc188422   Todd Kjos   binder: use node-...
3357
  					binder_put_node(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3358
3359
3360
3361
3362
  					break;
  				}
  				node->pending_strong_ref = 0;
  			} else {
  				if (node->pending_weak_ref == 0) {
56b468fc7   Anmol Sarma   Staging: android:...
3363
3364
  					binder_user_error("%d:%d BC_INCREFS_DONE node %d has no pending increfs request
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3365
3366
  						proc->pid, thread->pid,
  						node->debug_id);
673068eee   Todd Kjos   binder: add spinl...
3367
  					binder_node_inner_unlock(node);
adc188422   Todd Kjos   binder: use node-...
3368
  					binder_put_node(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3369
3370
3371
3372
  					break;
  				}
  				node->pending_weak_ref = 0;
  			}
673068eee   Todd Kjos   binder: add spinl...
3373
3374
3375
  			free_node = binder_dec_node_nilocked(node,
  					cmd == BC_ACQUIRE_DONE, 0);
  			WARN_ON(free_node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3376
  			binder_debug(BINDER_DEBUG_USER_REFS,
adc188422   Todd Kjos   binder: use node-...
3377
3378
  				     "%d:%d %s node %d ls %d lw %d tr %d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3379
3380
  				     proc->pid, thread->pid,
  				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
adc188422   Todd Kjos   binder: use node-...
3381
3382
  				     node->debug_id, node->local_strong_refs,
  				     node->local_weak_refs, node->tmp_refs);
673068eee   Todd Kjos   binder: add spinl...
3383
  			binder_node_inner_unlock(node);
adc188422   Todd Kjos   binder: use node-...
3384
  			binder_put_node(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3385
3386
3387
  			break;
  		}
  		case BC_ATTEMPT_ACQUIRE:
56b468fc7   Anmol Sarma   Staging: android:...
3388
3389
  			pr_err("BC_ATTEMPT_ACQUIRE not supported
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3390
3391
  			return -EINVAL;
  		case BC_ACQUIRE_RESULT:
56b468fc7   Anmol Sarma   Staging: android:...
3392
3393
  			pr_err("BC_ACQUIRE_RESULT not supported
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3394
3395
3396
  			return -EINVAL;
  
  		case BC_FREE_BUFFER: {
da49889de   Arve Hjønnevåg   staging: binder: ...
3397
  			binder_uintptr_t data_ptr;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3398
  			struct binder_buffer *buffer;
da49889de   Arve Hjønnevåg   staging: binder: ...
3399
  			if (get_user(data_ptr, (binder_uintptr_t __user *)ptr))
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3400
  				return -EFAULT;
da49889de   Arve Hjønnevåg   staging: binder: ...
3401
  			ptr += sizeof(binder_uintptr_t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3402

53d311cfa   Todd Kjos   binder: protect a...
3403
3404
  			buffer = binder_alloc_prepare_to_free(&proc->alloc,
  							      data_ptr);
fd6cc33d0   Todd Kjos   binder: fix race ...
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
  			if (IS_ERR_OR_NULL(buffer)) {
  				if (PTR_ERR(buffer) == -EPERM) {
  					binder_user_error(
  						"%d:%d BC_FREE_BUFFER u%016llx matched unreturned or currently freeing buffer
  ",
  						proc->pid, thread->pid,
  						(u64)data_ptr);
  				} else {
  					binder_user_error(
  						"%d:%d BC_FREE_BUFFER u%016llx no match
  ",
  						proc->pid, thread->pid,
  						(u64)data_ptr);
  				}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3419
3420
3421
  				break;
  			}
  			binder_debug(BINDER_DEBUG_FREE_BUFFER,
da49889de   Arve Hjønnevåg   staging: binder: ...
3422
3423
3424
3425
  				     "%d:%d BC_FREE_BUFFER u%016llx found buffer %d for %s transaction
  ",
  				     proc->pid, thread->pid, (u64)data_ptr,
  				     buffer->debug_id,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3426
3427
3428
3429
3430
3431
3432
  				     buffer->transaction ? "active" : "finished");
  
  			if (buffer->transaction) {
  				buffer->transaction->buffer = NULL;
  				buffer->transaction = NULL;
  			}
  			if (buffer->async_transaction && buffer->target_node) {
72196393a   Todd Kjos   binder: add spinl...
3433
3434
3435
3436
  				struct binder_node *buf_node;
  				struct binder_work *w;
  
  				buf_node = buffer->target_node;
673068eee   Todd Kjos   binder: add spinl...
3437
  				binder_node_inner_lock(buf_node);
72196393a   Todd Kjos   binder: add spinl...
3438
3439
  				BUG_ON(!buf_node->has_async_transaction);
  				BUG_ON(buf_node->proc != proc);
72196393a   Todd Kjos   binder: add spinl...
3440
3441
  				w = binder_dequeue_work_head_ilocked(
  						&buf_node->async_todo);
3a6430ce4   Martijn Coenen   ANDROID: binder: ...
3442
  				if (!w) {
72196393a   Todd Kjos   binder: add spinl...
3443
  					buf_node->has_async_transaction = 0;
3a6430ce4   Martijn Coenen   ANDROID: binder: ...
3444
  				} else {
72196393a   Todd Kjos   binder: add spinl...
3445
  					binder_enqueue_work_ilocked(
3a6430ce4   Martijn Coenen   ANDROID: binder: ...
3446
3447
3448
  							w, &proc->todo);
  					binder_wakeup_proc_ilocked(proc);
  				}
673068eee   Todd Kjos   binder: add spinl...
3449
  				binder_node_inner_unlock(buf_node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3450
  			}
975a1ac9a   Arve Hjønnevåg   Staging: android:...
3451
  			trace_binder_transaction_buffer_release(buffer);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3452
  			binder_transaction_buffer_release(proc, buffer, NULL);
19c987241   Todd Kjos   binder: separate ...
3453
  			binder_alloc_free_buf(&proc->alloc, buffer);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3454
3455
  			break;
  		}
7980240b6   Martijn Coenen   binder: Add suppo...
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
  		case BC_TRANSACTION_SG:
  		case BC_REPLY_SG: {
  			struct binder_transaction_data_sg tr;
  
  			if (copy_from_user(&tr, ptr, sizeof(tr)))
  				return -EFAULT;
  			ptr += sizeof(tr);
  			binder_transaction(proc, thread, &tr.transaction_data,
  					   cmd == BC_REPLY_SG, tr.buffers_size);
  			break;
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3467
3468
3469
3470
3471
3472
3473
  		case BC_TRANSACTION:
  		case BC_REPLY: {
  			struct binder_transaction_data tr;
  
  			if (copy_from_user(&tr, ptr, sizeof(tr)))
  				return -EFAULT;
  			ptr += sizeof(tr);
4bfac80af   Martijn Coenen   binder: Add extra...
3474
3475
  			binder_transaction(proc, thread, &tr,
  					   cmd == BC_REPLY, 0);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3476
3477
3478
3479
3480
  			break;
  		}
  
  		case BC_REGISTER_LOOPER:
  			binder_debug(BINDER_DEBUG_THREADS,
56b468fc7   Anmol Sarma   Staging: android:...
3481
3482
  				     "%d:%d BC_REGISTER_LOOPER
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3483
  				     proc->pid, thread->pid);
b3e686128   Todd Kjos   binder: use inner...
3484
  			binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3485
3486
  			if (thread->looper & BINDER_LOOPER_STATE_ENTERED) {
  				thread->looper |= BINDER_LOOPER_STATE_INVALID;
56b468fc7   Anmol Sarma   Staging: android:...
3487
3488
  				binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called after BC_ENTER_LOOPER
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3489
3490
3491
  					proc->pid, thread->pid);
  			} else if (proc->requested_threads == 0) {
  				thread->looper |= BINDER_LOOPER_STATE_INVALID;
56b468fc7   Anmol Sarma   Staging: android:...
3492
3493
  				binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called without request
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3494
3495
3496
3497
3498
3499
  					proc->pid, thread->pid);
  			} else {
  				proc->requested_threads--;
  				proc->requested_threads_started++;
  			}
  			thread->looper |= BINDER_LOOPER_STATE_REGISTERED;
b3e686128   Todd Kjos   binder: use inner...
3500
  			binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3501
3502
3503
  			break;
  		case BC_ENTER_LOOPER:
  			binder_debug(BINDER_DEBUG_THREADS,
56b468fc7   Anmol Sarma   Staging: android:...
3504
3505
  				     "%d:%d BC_ENTER_LOOPER
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3506
3507
3508
  				     proc->pid, thread->pid);
  			if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) {
  				thread->looper |= BINDER_LOOPER_STATE_INVALID;
56b468fc7   Anmol Sarma   Staging: android:...
3509
3510
  				binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3511
3512
3513
3514
3515
3516
  					proc->pid, thread->pid);
  			}
  			thread->looper |= BINDER_LOOPER_STATE_ENTERED;
  			break;
  		case BC_EXIT_LOOPER:
  			binder_debug(BINDER_DEBUG_THREADS,
56b468fc7   Anmol Sarma   Staging: android:...
3517
3518
  				     "%d:%d BC_EXIT_LOOPER
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3519
3520
3521
3522
3523
3524
3525
  				     proc->pid, thread->pid);
  			thread->looper |= BINDER_LOOPER_STATE_EXITED;
  			break;
  
  		case BC_REQUEST_DEATH_NOTIFICATION:
  		case BC_CLEAR_DEATH_NOTIFICATION: {
  			uint32_t target;
da49889de   Arve Hjønnevåg   staging: binder: ...
3526
  			binder_uintptr_t cookie;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3527
  			struct binder_ref *ref;
2c1838dc6   Todd Kjos   binder: protect b...
3528
  			struct binder_ref_death *death = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3529
3530
3531
3532
  
  			if (get_user(target, (uint32_t __user *)ptr))
  				return -EFAULT;
  			ptr += sizeof(uint32_t);
da49889de   Arve Hjønnevåg   staging: binder: ...
3533
  			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3534
  				return -EFAULT;
da49889de   Arve Hjønnevåg   staging: binder: ...
3535
  			ptr += sizeof(binder_uintptr_t);
2c1838dc6   Todd Kjos   binder: protect b...
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
  			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
  				/*
  				 * Allocate memory for death notification
  				 * before taking lock
  				 */
  				death = kzalloc(sizeof(*death), GFP_KERNEL);
  				if (death == NULL) {
  					WARN_ON(thread->return_error.cmd !=
  						BR_OK);
  					thread->return_error.cmd = BR_ERROR;
  					binder_enqueue_work(
  						thread->proc,
  						&thread->return_error.work,
  						&thread->todo);
  					binder_debug(
  						BINDER_DEBUG_FAILED_TRANSACTION,
  						"%d:%d BC_REQUEST_DEATH_NOTIFICATION failed
  ",
  						proc->pid, thread->pid);
  					break;
  				}
  			}
  			binder_proc_lock(proc);
  			ref = binder_get_ref_olocked(proc, target, false);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3560
  			if (ref == NULL) {
56b468fc7   Anmol Sarma   Staging: android:...
3561
3562
  				binder_user_error("%d:%d %s invalid ref %d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3563
3564
3565
3566
3567
  					proc->pid, thread->pid,
  					cmd == BC_REQUEST_DEATH_NOTIFICATION ?
  					"BC_REQUEST_DEATH_NOTIFICATION" :
  					"BC_CLEAR_DEATH_NOTIFICATION",
  					target);
2c1838dc6   Todd Kjos   binder: protect b...
3568
3569
  				binder_proc_unlock(proc);
  				kfree(death);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3570
3571
3572
3573
  				break;
  			}
  
  			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
da49889de   Arve Hjønnevåg   staging: binder: ...
3574
3575
  				     "%d:%d %s %016llx ref %d desc %d s %d w %d for node %d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3576
3577
3578
3579
  				     proc->pid, thread->pid,
  				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
  				     "BC_REQUEST_DEATH_NOTIFICATION" :
  				     "BC_CLEAR_DEATH_NOTIFICATION",
372e3147d   Todd Kjos   binder: refactor ...
3580
3581
3582
  				     (u64)cookie, ref->data.debug_id,
  				     ref->data.desc, ref->data.strong,
  				     ref->data.weak, ref->node->debug_id);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3583

ab51ec6bd   Martijn Coenen   binder: fix death...
3584
  			binder_node_lock(ref->node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3585
3586
  			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
  				if (ref->death) {
56b468fc7   Anmol Sarma   Staging: android:...
3587
3588
  					binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3589
  						proc->pid, thread->pid);
ab51ec6bd   Martijn Coenen   binder: fix death...
3590
  					binder_node_unlock(ref->node);
2c1838dc6   Todd Kjos   binder: protect b...
3591
3592
  					binder_proc_unlock(proc);
  					kfree(death);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3593
3594
3595
3596
3597
3598
3599
3600
  					break;
  				}
  				binder_stats_created(BINDER_STAT_DEATH);
  				INIT_LIST_HEAD(&death->work.entry);
  				death->cookie = cookie;
  				ref->death = death;
  				if (ref->node->proc == NULL) {
  					ref->death->work.type = BINDER_WORK_DEAD_BINDER;
bb74562a7   Martijn Coenen   ANDROID: binder: ...
3601
3602
3603
3604
3605
3606
  
  					binder_inner_proc_lock(proc);
  					binder_enqueue_work_ilocked(
  						&ref->death->work, &proc->todo);
  					binder_wakeup_proc_ilocked(proc);
  					binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3607
3608
3609
  				}
  			} else {
  				if (ref->death == NULL) {
56b468fc7   Anmol Sarma   Staging: android:...
3610
3611
  					binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3612
  						proc->pid, thread->pid);
673068eee   Todd Kjos   binder: add spinl...
3613
  					binder_node_unlock(ref->node);
2c1838dc6   Todd Kjos   binder: protect b...
3614
  					binder_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3615
3616
3617
3618
  					break;
  				}
  				death = ref->death;
  				if (death->cookie != cookie) {
da49889de   Arve Hjønnevåg   staging: binder: ...
3619
3620
  					binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %016llx != %016llx
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3621
  						proc->pid, thread->pid,
da49889de   Arve Hjønnevåg   staging: binder: ...
3622
3623
  						(u64)death->cookie,
  						(u64)cookie);
673068eee   Todd Kjos   binder: add spinl...
3624
  					binder_node_unlock(ref->node);
2c1838dc6   Todd Kjos   binder: protect b...
3625
  					binder_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3626
3627
3628
  					break;
  				}
  				ref->death = NULL;
72196393a   Todd Kjos   binder: add spinl...
3629
  				binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3630
3631
  				if (list_empty(&death->work.entry)) {
  					death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;
72196393a   Todd Kjos   binder: add spinl...
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
  					if (thread->looper &
  					    (BINDER_LOOPER_STATE_REGISTERED |
  					     BINDER_LOOPER_STATE_ENTERED))
  						binder_enqueue_work_ilocked(
  								&death->work,
  								&thread->todo);
  					else {
  						binder_enqueue_work_ilocked(
  								&death->work,
  								&proc->todo);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
3642
  						binder_wakeup_proc_ilocked(
408c68b17   Martijn Coenen   ANDROID: binder: ...
3643
  								proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3644
3645
3646
3647
3648
  					}
  				} else {
  					BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER);
  					death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR;
  				}
72196393a   Todd Kjos   binder: add spinl...
3649
  				binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3650
  			}
ab51ec6bd   Martijn Coenen   binder: fix death...
3651
  			binder_node_unlock(ref->node);
2c1838dc6   Todd Kjos   binder: protect b...
3652
  			binder_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3653
3654
3655
  		} break;
  		case BC_DEAD_BINDER_DONE: {
  			struct binder_work *w;
da49889de   Arve Hjønnevåg   staging: binder: ...
3656
  			binder_uintptr_t cookie;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3657
  			struct binder_ref_death *death = NULL;
10f62861b   Seunghun Lee   staging: android:...
3658

da49889de   Arve Hjønnevåg   staging: binder: ...
3659
  			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3660
  				return -EFAULT;
7a64cd887   Lisa Du   drivers: android:...
3661
  			ptr += sizeof(cookie);
72196393a   Todd Kjos   binder: add spinl...
3662
3663
3664
3665
3666
3667
3668
  			binder_inner_proc_lock(proc);
  			list_for_each_entry(w, &proc->delivered_death,
  					    entry) {
  				struct binder_ref_death *tmp_death =
  					container_of(w,
  						     struct binder_ref_death,
  						     work);
10f62861b   Seunghun Lee   staging: android:...
3669

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3670
3671
3672
3673
3674
3675
  				if (tmp_death->cookie == cookie) {
  					death = tmp_death;
  					break;
  				}
  			}
  			binder_debug(BINDER_DEBUG_DEAD_BINDER,
b46af094b   Todd Kjos   binder: replace "...
3676
3677
  				     "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK
  ",
da49889de   Arve Hjønnevåg   staging: binder: ...
3678
3679
  				     proc->pid, thread->pid, (u64)cookie,
  				     death);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3680
  			if (death == NULL) {
da49889de   Arve Hjønnevåg   staging: binder: ...
3681
3682
3683
  				binder_user_error("%d:%d BC_DEAD_BINDER_DONE %016llx not found
  ",
  					proc->pid, thread->pid, (u64)cookie);
72196393a   Todd Kjos   binder: add spinl...
3684
  				binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3685
3686
  				break;
  			}
72196393a   Todd Kjos   binder: add spinl...
3687
  			binder_dequeue_work_ilocked(&death->work);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3688
3689
  			if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) {
  				death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;
72196393a   Todd Kjos   binder: add spinl...
3690
3691
3692
3693
3694
3695
3696
3697
3698
  				if (thread->looper &
  					(BINDER_LOOPER_STATE_REGISTERED |
  					 BINDER_LOOPER_STATE_ENTERED))
  					binder_enqueue_work_ilocked(
  						&death->work, &thread->todo);
  				else {
  					binder_enqueue_work_ilocked(
  							&death->work,
  							&proc->todo);
408c68b17   Martijn Coenen   ANDROID: binder: ...
3699
  					binder_wakeup_proc_ilocked(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3700
3701
  				}
  			}
72196393a   Todd Kjos   binder: add spinl...
3702
  			binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3703
3704
3705
  		} break;
  
  		default:
56b468fc7   Anmol Sarma   Staging: android:...
3706
3707
  			pr_err("%d:%d unknown command %d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3708
3709
3710
3711
3712
3713
3714
  			       proc->pid, thread->pid, cmd);
  			return -EINVAL;
  		}
  		*consumed = ptr - buffer;
  	}
  	return 0;
  }
fb07ebc3e   Bojan Prtvar   Staging: android:...
3715
3716
  static void binder_stat_br(struct binder_proc *proc,
  			   struct binder_thread *thread, uint32_t cmd)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3717
  {
975a1ac9a   Arve Hjønnevåg   Staging: android:...
3718
  	trace_binder_return(cmd);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3719
  	if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
3720
3721
3722
  		atomic_inc(&binder_stats.br[_IOC_NR(cmd)]);
  		atomic_inc(&proc->stats.br[_IOC_NR(cmd)]);
  		atomic_inc(&thread->stats.br[_IOC_NR(cmd)]);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3723
3724
  	}
  }
26b47d8a1   Todd Kjos   binder: refactor ...
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
  static int binder_put_node_cmd(struct binder_proc *proc,
  			       struct binder_thread *thread,
  			       void __user **ptrp,
  			       binder_uintptr_t node_ptr,
  			       binder_uintptr_t node_cookie,
  			       int node_debug_id,
  			       uint32_t cmd, const char *cmd_name)
  {
  	void __user *ptr = *ptrp;
  
  	if (put_user(cmd, (uint32_t __user *)ptr))
  		return -EFAULT;
  	ptr += sizeof(uint32_t);
  
  	if (put_user(node_ptr, (binder_uintptr_t __user *)ptr))
  		return -EFAULT;
  	ptr += sizeof(binder_uintptr_t);
  
  	if (put_user(node_cookie, (binder_uintptr_t __user *)ptr))
  		return -EFAULT;
  	ptr += sizeof(binder_uintptr_t);
  
  	binder_stat_br(proc, thread, cmd);
  	binder_debug(BINDER_DEBUG_USER_REFS, "%d:%d %s %d u%016llx c%016llx
  ",
  		     proc->pid, thread->pid, cmd_name, node_debug_id,
  		     (u64)node_ptr, (u64)node_cookie);
  
  	*ptrp = ptr;
  	return 0;
  }
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
  static int binder_wait_for_work(struct binder_thread *thread,
  				bool do_proc_work)
  {
  	DEFINE_WAIT(wait);
  	struct binder_proc *proc = thread->proc;
  	int ret = 0;
  
  	freezer_do_not_count();
  	binder_inner_proc_lock(proc);
  	for (;;) {
  		prepare_to_wait(&thread->wait, &wait, TASK_INTERRUPTIBLE);
  		if (binder_has_work_ilocked(thread, do_proc_work))
  			break;
  		if (do_proc_work)
  			list_add(&thread->waiting_thread_node,
  				 &proc->waiting_threads);
  		binder_inner_proc_unlock(proc);
  		schedule();
  		binder_inner_proc_lock(proc);
  		list_del_init(&thread->waiting_thread_node);
  		if (signal_pending(current)) {
  			ret = -ERESTARTSYS;
  			break;
  		}
  	}
  	finish_wait(&thread->wait, &wait);
  	binder_inner_proc_unlock(proc);
  	freezer_count();
  
  	return ret;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3787
3788
  static int binder_thread_read(struct binder_proc *proc,
  			      struct binder_thread *thread,
da49889de   Arve Hjønnevåg   staging: binder: ...
3789
3790
  			      binder_uintptr_t binder_buffer, size_t size,
  			      binder_size_t *consumed, int non_block)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3791
  {
da49889de   Arve Hjønnevåg   staging: binder: ...
3792
  	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
  	void __user *ptr = buffer + *consumed;
  	void __user *end = buffer + size;
  
  	int ret = 0;
  	int wait_for_proc_work;
  
  	if (*consumed == 0) {
  		if (put_user(BR_NOOP, (uint32_t __user *)ptr))
  			return -EFAULT;
  		ptr += sizeof(uint32_t);
  	}
  
  retry:
0b89d69a9   Martijn Coenen   binder: protect t...
3806
  	binder_inner_proc_lock(proc);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
3807
  	wait_for_proc_work = binder_available_for_proc_work_ilocked(thread);
0b89d69a9   Martijn Coenen   binder: protect t...
3808
  	binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3809

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3810
  	thread->looper |= BINDER_LOOPER_STATE_WAITING;
975a1ac9a   Arve Hjønnevåg   Staging: android:...
3811

975a1ac9a   Arve Hjønnevåg   Staging: android:...
3812
3813
  	trace_binder_wait_for_work(wait_for_proc_work,
  				   !!thread->transaction_stack,
72196393a   Todd Kjos   binder: add spinl...
3814
  				   !binder_worklist_empty(proc, &thread->todo));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3815
3816
3817
  	if (wait_for_proc_work) {
  		if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
  					BINDER_LOOPER_STATE_ENTERED))) {
56b468fc7   Anmol Sarma   Staging: android:...
3818
3819
  			binder_user_error("%d:%d ERROR: Thread waiting for process work before calling BC_REGISTER_LOOPER or BC_ENTER_LOOPER (state %x)
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3820
3821
3822
3823
3824
  				proc->pid, thread->pid, thread->looper);
  			wait_event_interruptible(binder_user_error_wait,
  						 binder_stop_on_user_error < 2);
  		}
  		binder_set_nice(proc->default_priority);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
3825
3826
3827
3828
3829
  	}
  
  	if (non_block) {
  		if (!binder_has_work(thread, wait_for_proc_work))
  			ret = -EAGAIN;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3830
  	} else {
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
3831
  		ret = binder_wait_for_work(thread, wait_for_proc_work);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3832
  	}
975a1ac9a   Arve Hjønnevåg   Staging: android:...
3833

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3834
3835
3836
3837
3838
3839
3840
3841
  	thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
  
  	if (ret)
  		return ret;
  
  	while (1) {
  		uint32_t cmd;
  		struct binder_transaction_data tr;
72196393a   Todd Kjos   binder: add spinl...
3842
3843
  		struct binder_work *w = NULL;
  		struct list_head *list = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3844
  		struct binder_transaction *t = NULL;
7a4408c6b   Todd Kjos   binder: make sure...
3845
  		struct binder_thread *t_from;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3846

ed29721e2   Todd Kjos   binder: use inner...
3847
  		binder_inner_proc_lock(proc);
72196393a   Todd Kjos   binder: add spinl...
3848
3849
3850
3851
3852
3853
3854
  		if (!binder_worklist_empty_ilocked(&thread->todo))
  			list = &thread->todo;
  		else if (!binder_worklist_empty_ilocked(&proc->todo) &&
  			   wait_for_proc_work)
  			list = &proc->todo;
  		else {
  			binder_inner_proc_unlock(proc);
395262a9e   Dmitry Voytik   staging: binder: ...
3855
  			/* no data added */
08dabceef   Todd Kjos   binder: don't mod...
3856
  			if (ptr - buffer == 4 && !thread->looper_need_return)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3857
3858
3859
  				goto retry;
  			break;
  		}
ed29721e2   Todd Kjos   binder: use inner...
3860
3861
  		if (end - ptr < sizeof(tr) + 4) {
  			binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3862
  			break;
ed29721e2   Todd Kjos   binder: use inner...
3863
  		}
72196393a   Todd Kjos   binder: add spinl...
3864
  		w = binder_dequeue_work_head_ilocked(list);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3865
3866
3867
  
  		switch (w->type) {
  		case BINDER_WORK_TRANSACTION: {
ed29721e2   Todd Kjos   binder: use inner...
3868
  			binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3869
3870
  			t = container_of(w, struct binder_transaction, work);
  		} break;
26549d177   Todd Kjos   binder: guarantee...
3871
3872
3873
3874
3875
  		case BINDER_WORK_RETURN_ERROR: {
  			struct binder_error *e = container_of(
  					w, struct binder_error, work);
  
  			WARN_ON(e->cmd == BR_OK);
ed29721e2   Todd Kjos   binder: use inner...
3876
  			binder_inner_proc_unlock(proc);
26549d177   Todd Kjos   binder: guarantee...
3877
3878
3879
3880
  			if (put_user(e->cmd, (uint32_t __user *)ptr))
  				return -EFAULT;
  			e->cmd = BR_OK;
  			ptr += sizeof(uint32_t);
4f9adc8f9   Todd Kjos   binder: fix incor...
3881
  			binder_stat_br(proc, thread, e->cmd);
26549d177   Todd Kjos   binder: guarantee...
3882
  		} break;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3883
  		case BINDER_WORK_TRANSACTION_COMPLETE: {
ed29721e2   Todd Kjos   binder: use inner...
3884
  			binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3885
3886
3887
3888
3889
3890
3891
  			cmd = BR_TRANSACTION_COMPLETE;
  			if (put_user(cmd, (uint32_t __user *)ptr))
  				return -EFAULT;
  			ptr += sizeof(uint32_t);
  
  			binder_stat_br(proc, thread, cmd);
  			binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE,
56b468fc7   Anmol Sarma   Staging: android:...
3892
3893
  				     "%d:%d BR_TRANSACTION_COMPLETE
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3894
  				     proc->pid, thread->pid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3895
3896
3897
3898
3899
  			kfree(w);
  			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
  		} break;
  		case BINDER_WORK_NODE: {
  			struct binder_node *node = container_of(w, struct binder_node, work);
26b47d8a1   Todd Kjos   binder: refactor ...
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
  			int strong, weak;
  			binder_uintptr_t node_ptr = node->ptr;
  			binder_uintptr_t node_cookie = node->cookie;
  			int node_debug_id = node->debug_id;
  			int has_weak_ref;
  			int has_strong_ref;
  			void __user *orig_ptr = ptr;
  
  			BUG_ON(proc != node->proc);
  			strong = node->internal_strong_refs ||
  					node->local_strong_refs;
  			weak = !hlist_empty(&node->refs) ||
adc188422   Todd Kjos   binder: use node-...
3912
3913
  					node->local_weak_refs ||
  					node->tmp_refs || strong;
26b47d8a1   Todd Kjos   binder: refactor ...
3914
3915
3916
3917
  			has_strong_ref = node->has_strong_ref;
  			has_weak_ref = node->has_weak_ref;
  
  			if (weak && !has_weak_ref) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3918
3919
3920
  				node->has_weak_ref = 1;
  				node->pending_weak_ref = 1;
  				node->local_weak_refs++;
26b47d8a1   Todd Kjos   binder: refactor ...
3921
3922
  			}
  			if (strong && !has_strong_ref) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3923
3924
3925
  				node->has_strong_ref = 1;
  				node->pending_strong_ref = 1;
  				node->local_strong_refs++;
26b47d8a1   Todd Kjos   binder: refactor ...
3926
3927
  			}
  			if (!strong && has_strong_ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3928
  				node->has_strong_ref = 0;
26b47d8a1   Todd Kjos   binder: refactor ...
3929
  			if (!weak && has_weak_ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3930
  				node->has_weak_ref = 0;
26b47d8a1   Todd Kjos   binder: refactor ...
3931
3932
3933
3934
3935
3936
3937
3938
3939
  			if (!weak && !strong) {
  				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
  					     "%d:%d node %d u%016llx c%016llx deleted
  ",
  					     proc->pid, thread->pid,
  					     node_debug_id,
  					     (u64)node_ptr,
  					     (u64)node_cookie);
  				rb_erase(&node->rb_node, &proc->nodes);
ed29721e2   Todd Kjos   binder: use inner...
3940
  				binder_inner_proc_unlock(proc);
673068eee   Todd Kjos   binder: add spinl...
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
  				binder_node_lock(node);
  				/*
  				 * Acquire the node lock before freeing the
  				 * node to serialize with other threads that
  				 * may have been holding the node lock while
  				 * decrementing this node (avoids race where
  				 * this thread frees while the other thread
  				 * is unlocking the node after the final
  				 * decrement)
  				 */
  				binder_node_unlock(node);
ed29721e2   Todd Kjos   binder: use inner...
3952
3953
3954
  				binder_free_node(node);
  			} else
  				binder_inner_proc_unlock(proc);
26b47d8a1   Todd Kjos   binder: refactor ...
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
  			if (weak && !has_weak_ref)
  				ret = binder_put_node_cmd(
  						proc, thread, &ptr, node_ptr,
  						node_cookie, node_debug_id,
  						BR_INCREFS, "BR_INCREFS");
  			if (!ret && strong && !has_strong_ref)
  				ret = binder_put_node_cmd(
  						proc, thread, &ptr, node_ptr,
  						node_cookie, node_debug_id,
  						BR_ACQUIRE, "BR_ACQUIRE");
  			if (!ret && !strong && has_strong_ref)
  				ret = binder_put_node_cmd(
  						proc, thread, &ptr, node_ptr,
  						node_cookie, node_debug_id,
  						BR_RELEASE, "BR_RELEASE");
  			if (!ret && !weak && has_weak_ref)
  				ret = binder_put_node_cmd(
  						proc, thread, &ptr, node_ptr,
  						node_cookie, node_debug_id,
  						BR_DECREFS, "BR_DECREFS");
  			if (orig_ptr == ptr)
  				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
  					     "%d:%d node %d u%016llx c%016llx state unchanged
  ",
  					     proc->pid, thread->pid,
  					     node_debug_id,
  					     (u64)node_ptr,
  					     (u64)node_cookie);
  			if (ret)
  				return ret;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3985
3986
3987
3988
3989
3990
  		} break;
  		case BINDER_WORK_DEAD_BINDER:
  		case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
  		case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
  			struct binder_ref_death *death;
  			uint32_t cmd;
ab51ec6bd   Martijn Coenen   binder: fix death...
3991
  			binder_uintptr_t cookie;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3992
3993
3994
3995
3996
3997
  
  			death = container_of(w, struct binder_ref_death, work);
  			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION)
  				cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
  			else
  				cmd = BR_DEAD_BINDER;
ab51ec6bd   Martijn Coenen   binder: fix death...
3998
  			cookie = death->cookie;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
3999
  			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
da49889de   Arve Hjønnevåg   staging: binder: ...
4000
4001
  				     "%d:%d %s %016llx
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4002
4003
4004
4005
  				      proc->pid, thread->pid,
  				      cmd == BR_DEAD_BINDER ?
  				      "BR_DEAD_BINDER" :
  				      "BR_CLEAR_DEATH_NOTIFICATION_DONE",
ab51ec6bd   Martijn Coenen   binder: fix death...
4006
  				      (u64)cookie);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4007
  			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {
ab51ec6bd   Martijn Coenen   binder: fix death...
4008
  				binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4009
4010
  				kfree(death);
  				binder_stats_deleted(BINDER_STAT_DEATH);
ed29721e2   Todd Kjos   binder: use inner...
4011
  			} else {
72196393a   Todd Kjos   binder: add spinl...
4012
4013
  				binder_enqueue_work_ilocked(
  						w, &proc->delivered_death);
ed29721e2   Todd Kjos   binder: use inner...
4014
4015
  				binder_inner_proc_unlock(proc);
  			}
ab51ec6bd   Martijn Coenen   binder: fix death...
4016
4017
4018
4019
4020
4021
4022
4023
  			if (put_user(cmd, (uint32_t __user *)ptr))
  				return -EFAULT;
  			ptr += sizeof(uint32_t);
  			if (put_user(cookie,
  				     (binder_uintptr_t __user *)ptr))
  				return -EFAULT;
  			ptr += sizeof(binder_uintptr_t);
  			binder_stat_br(proc, thread, cmd);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
  			if (cmd == BR_DEAD_BINDER)
  				goto done; /* DEAD_BINDER notifications can cause transactions */
  		} break;
  		}
  
  		if (!t)
  			continue;
  
  		BUG_ON(t->buffer == NULL);
  		if (t->buffer->target_node) {
  			struct binder_node *target_node = t->buffer->target_node;
10f62861b   Seunghun Lee   staging: android:...
4035

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
  			tr.target.ptr = target_node->ptr;
  			tr.cookie =  target_node->cookie;
  			t->saved_priority = task_nice(current);
  			if (t->priority < target_node->min_priority &&
  			    !(t->flags & TF_ONE_WAY))
  				binder_set_nice(t->priority);
  			else if (!(t->flags & TF_ONE_WAY) ||
  				 t->saved_priority > target_node->min_priority)
  				binder_set_nice(target_node->min_priority);
  			cmd = BR_TRANSACTION;
  		} else {
da49889de   Arve Hjønnevåg   staging: binder: ...
4047
4048
  			tr.target.ptr = 0;
  			tr.cookie = 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4049
4050
4051
4052
  			cmd = BR_REPLY;
  		}
  		tr.code = t->code;
  		tr.flags = t->flags;
4a2ebb93b   Eric W. Biederman   userns: Convert b...
4053
  		tr.sender_euid = from_kuid(current_user_ns(), t->sender_euid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4054

7a4408c6b   Todd Kjos   binder: make sure...
4055
4056
4057
  		t_from = binder_get_txn_from(t);
  		if (t_from) {
  			struct task_struct *sender = t_from->proc->tsk;
10f62861b   Seunghun Lee   staging: android:...
4058

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4059
  			tr.sender_pid = task_tgid_nr_ns(sender,
17cf22c33   Eric W. Biederman   pidns: Use task_a...
4060
  							task_active_pid_ns(current));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4061
4062
4063
4064
4065
4066
  		} else {
  			tr.sender_pid = 0;
  		}
  
  		tr.data_size = t->buffer->data_size;
  		tr.offsets_size = t->buffer->offsets_size;
19c987241   Todd Kjos   binder: separate ...
4067
4068
4069
  		tr.data.ptr.buffer = (binder_uintptr_t)
  			((uintptr_t)t->buffer->data +
  			binder_alloc_get_user_buffer_offset(&proc->alloc));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4070
4071
4072
  		tr.data.ptr.offsets = tr.data.ptr.buffer +
  					ALIGN(t->buffer->data_size,
  					    sizeof(void *));
7a4408c6b   Todd Kjos   binder: make sure...
4073
4074
4075
  		if (put_user(cmd, (uint32_t __user *)ptr)) {
  			if (t_from)
  				binder_thread_dec_tmpref(t_from);
22ad53793   Martijn Coenen   ANDROID: binder: ...
4076
4077
4078
  
  			binder_cleanup_transaction(t, "put_user failed",
  						   BR_FAILED_REPLY);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4079
  			return -EFAULT;
7a4408c6b   Todd Kjos   binder: make sure...
4080
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4081
  		ptr += sizeof(uint32_t);
7a4408c6b   Todd Kjos   binder: make sure...
4082
4083
4084
  		if (copy_to_user(ptr, &tr, sizeof(tr))) {
  			if (t_from)
  				binder_thread_dec_tmpref(t_from);
22ad53793   Martijn Coenen   ANDROID: binder: ...
4085
4086
4087
  
  			binder_cleanup_transaction(t, "copy_to_user failed",
  						   BR_FAILED_REPLY);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4088
  			return -EFAULT;
7a4408c6b   Todd Kjos   binder: make sure...
4089
  		}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4090
  		ptr += sizeof(tr);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4091
  		trace_binder_transaction_received(t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4092
4093
  		binder_stat_br(proc, thread, cmd);
  		binder_debug(BINDER_DEBUG_TRANSACTION,
da49889de   Arve Hjønnevåg   staging: binder: ...
4094
4095
  			     "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4096
4097
4098
  			     proc->pid, thread->pid,
  			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
  			     "BR_REPLY",
7a4408c6b   Todd Kjos   binder: make sure...
4099
4100
  			     t->debug_id, t_from ? t_from->proc->pid : 0,
  			     t_from ? t_from->pid : 0, cmd,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4101
  			     t->buffer->data_size, t->buffer->offsets_size,
da49889de   Arve Hjønnevåg   staging: binder: ...
4102
  			     (u64)tr.data.ptr.buffer, (u64)tr.data.ptr.offsets);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4103

7a4408c6b   Todd Kjos   binder: make sure...
4104
4105
  		if (t_from)
  			binder_thread_dec_tmpref(t_from);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4106
4107
  		t->buffer->allow_user_free = 1;
  		if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) {
0b89d69a9   Martijn Coenen   binder: protect t...
4108
  			binder_inner_proc_lock(thread->proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4109
4110
4111
  			t->to_parent = thread->transaction_stack;
  			t->to_thread = thread;
  			thread->transaction_stack = t;
0b89d69a9   Martijn Coenen   binder: protect t...
4112
  			binder_inner_proc_unlock(thread->proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4113
  		} else {
b6d282cea   Todd Kjos   binder: refactor ...
4114
  			binder_free_transaction(t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4115
4116
4117
4118
4119
4120
4121
  		}
  		break;
  	}
  
  done:
  
  	*consumed = ptr - buffer;
b3e686128   Todd Kjos   binder: use inner...
4122
  	binder_inner_proc_lock(proc);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4123
4124
  	if (proc->requested_threads == 0 &&
  	    list_empty(&thread->proc->waiting_threads) &&
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4125
4126
4127
4128
4129
  	    proc->requested_threads_started < proc->max_threads &&
  	    (thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
  	     BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
  	     /*spawn a new thread if we leave this out */) {
  		proc->requested_threads++;
b3e686128   Todd Kjos   binder: use inner...
4130
  		binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4131
  		binder_debug(BINDER_DEBUG_THREADS,
56b468fc7   Anmol Sarma   Staging: android:...
4132
4133
  			     "%d:%d BR_SPAWN_LOOPER
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4134
4135
4136
  			     proc->pid, thread->pid);
  		if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
  			return -EFAULT;
89334ab4d   Arve Hjønnevåg   Staging: android:...
4137
  		binder_stat_br(proc, thread, BR_SPAWN_LOOPER);
b3e686128   Todd Kjos   binder: use inner...
4138
4139
  	} else
  		binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4140
4141
  	return 0;
  }
72196393a   Todd Kjos   binder: add spinl...
4142
4143
  static void binder_release_work(struct binder_proc *proc,
  				struct list_head *list)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4144
4145
  {
  	struct binder_work *w;
10f62861b   Seunghun Lee   staging: android:...
4146

72196393a   Todd Kjos   binder: add spinl...
4147
4148
4149
4150
  	while (1) {
  		w = binder_dequeue_work_head(proc, list);
  		if (!w)
  			return;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4151
4152
4153
4154
4155
  		switch (w->type) {
  		case BINDER_WORK_TRANSACTION: {
  			struct binder_transaction *t;
  
  			t = container_of(w, struct binder_transaction, work);
22ad53793   Martijn Coenen   ANDROID: binder: ...
4156
4157
4158
  
  			binder_cleanup_transaction(t, "process died.",
  						   BR_DEAD_REPLY);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4159
  		} break;
26549d177   Todd Kjos   binder: guarantee...
4160
4161
4162
4163
4164
4165
4166
4167
4168
  		case BINDER_WORK_RETURN_ERROR: {
  			struct binder_error *e = container_of(
  					w, struct binder_error, work);
  
  			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
  				"undelivered TRANSACTION_ERROR: %u
  ",
  				e->cmd);
  		} break;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4169
  		case BINDER_WORK_TRANSACTION_COMPLETE: {
675d66b0e   Arve Hjønnevåg   Staging: android:...
4170
  			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
56b468fc7   Anmol Sarma   Staging: android:...
4171
4172
  				"undelivered TRANSACTION_COMPLETE
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4173
4174
4175
  			kfree(w);
  			binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
  		} break;
675d66b0e   Arve Hjønnevåg   Staging: android:...
4176
4177
4178
4179
4180
4181
  		case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
  		case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
  			struct binder_ref_death *death;
  
  			death = container_of(w, struct binder_ref_death, work);
  			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
da49889de   Arve Hjønnevåg   staging: binder: ...
4182
4183
4184
  				"undelivered death notification, %016llx
  ",
  				(u64)death->cookie);
675d66b0e   Arve Hjønnevåg   Staging: android:...
4185
4186
4187
  			kfree(death);
  			binder_stats_deleted(BINDER_STAT_DEATH);
  		} break;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4188
  		default:
56b468fc7   Anmol Sarma   Staging: android:...
4189
4190
  			pr_err("unexpected work type, %d, not freed
  ",
675d66b0e   Arve Hjønnevåg   Staging: android:...
4191
  			       w->type);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4192
4193
4194
4195
4196
  			break;
  		}
  	}
  
  }
7bd7b0e63   Todd Kjos   binder: protect p...
4197
4198
  static struct binder_thread *binder_get_thread_ilocked(
  		struct binder_proc *proc, struct binder_thread *new_thread)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
  {
  	struct binder_thread *thread = NULL;
  	struct rb_node *parent = NULL;
  	struct rb_node **p = &proc->threads.rb_node;
  
  	while (*p) {
  		parent = *p;
  		thread = rb_entry(parent, struct binder_thread, rb_node);
  
  		if (current->pid < thread->pid)
  			p = &(*p)->rb_left;
  		else if (current->pid > thread->pid)
  			p = &(*p)->rb_right;
  		else
7bd7b0e63   Todd Kjos   binder: protect p...
4213
  			return thread;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4214
  	}
7bd7b0e63   Todd Kjos   binder: protect p...
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
  	if (!new_thread)
  		return NULL;
  	thread = new_thread;
  	binder_stats_created(BINDER_STAT_THREAD);
  	thread->proc = proc;
  	thread->pid = current->pid;
  	atomic_set(&thread->tmp_ref, 0);
  	init_waitqueue_head(&thread->wait);
  	INIT_LIST_HEAD(&thread->todo);
  	rb_link_node(&thread->rb_node, parent, p);
  	rb_insert_color(&thread->rb_node, &proc->threads);
  	thread->looper_need_return = true;
  	thread->return_error.work.type = BINDER_WORK_RETURN_ERROR;
  	thread->return_error.cmd = BR_OK;
  	thread->reply_error.work.type = BINDER_WORK_RETURN_ERROR;
  	thread->reply_error.cmd = BR_OK;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4231
  	INIT_LIST_HEAD(&new_thread->waiting_thread_node);
7bd7b0e63   Todd Kjos   binder: protect p...
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
  	return thread;
  }
  
  static struct binder_thread *binder_get_thread(struct binder_proc *proc)
  {
  	struct binder_thread *thread;
  	struct binder_thread *new_thread;
  
  	binder_inner_proc_lock(proc);
  	thread = binder_get_thread_ilocked(proc, NULL);
  	binder_inner_proc_unlock(proc);
  	if (!thread) {
  		new_thread = kzalloc(sizeof(*thread), GFP_KERNEL);
  		if (new_thread == NULL)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4246
  			return NULL;
7bd7b0e63   Todd Kjos   binder: protect p...
4247
4248
4249
4250
4251
  		binder_inner_proc_lock(proc);
  		thread = binder_get_thread_ilocked(proc, new_thread);
  		binder_inner_proc_unlock(proc);
  		if (thread != new_thread)
  			kfree(new_thread);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4252
4253
4254
  	}
  	return thread;
  }
7a4408c6b   Todd Kjos   binder: make sure...
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
  static void binder_free_proc(struct binder_proc *proc)
  {
  	BUG_ON(!list_empty(&proc->todo));
  	BUG_ON(!list_empty(&proc->delivered_death));
  	binder_alloc_deferred_release(&proc->alloc);
  	put_task_struct(proc->tsk);
  	binder_stats_deleted(BINDER_STAT_PROC);
  	kfree(proc);
  }
  
  static void binder_free_thread(struct binder_thread *thread)
  {
  	BUG_ON(!list_empty(&thread->todo));
  	binder_stats_deleted(BINDER_STAT_THREAD);
  	binder_proc_dec_tmpref(thread->proc);
  	kfree(thread);
  }
  
  static int binder_thread_release(struct binder_proc *proc,
  				 struct binder_thread *thread)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4275
4276
4277
4278
  {
  	struct binder_transaction *t;
  	struct binder_transaction *send_reply = NULL;
  	int active_transactions = 0;
7a4408c6b   Todd Kjos   binder: make sure...
4279
  	struct binder_transaction *last_t = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4280

7bd7b0e63   Todd Kjos   binder: protect p...
4281
  	binder_inner_proc_lock(thread->proc);
7a4408c6b   Todd Kjos   binder: make sure...
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
  	/*
  	 * take a ref on the proc so it survives
  	 * after we remove this thread from proc->threads.
  	 * The corresponding dec is when we actually
  	 * free the thread in binder_free_thread()
  	 */
  	proc->tmp_ref++;
  	/*
  	 * take a ref on this thread to ensure it
  	 * survives while we are releasing it
  	 */
  	atomic_inc(&thread->tmp_ref);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4294
4295
  	rb_erase(&thread->rb_node, &proc->threads);
  	t = thread->transaction_stack;
7a4408c6b   Todd Kjos   binder: make sure...
4296
4297
4298
4299
4300
4301
  	if (t) {
  		spin_lock(&t->lock);
  		if (t->to_thread == thread)
  			send_reply = t;
  	}
  	thread->is_dead = true;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4302
  	while (t) {
7a4408c6b   Todd Kjos   binder: make sure...
4303
  		last_t = t;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4304
4305
  		active_transactions++;
  		binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
56b468fc7   Anmol Sarma   Staging: android:...
4306
4307
4308
  			     "release %d:%d transaction %d %s, still active
  ",
  			      proc->pid, thread->pid,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
  			     t->debug_id,
  			     (t->to_thread == thread) ? "in" : "out");
  
  		if (t->to_thread == thread) {
  			t->to_proc = NULL;
  			t->to_thread = NULL;
  			if (t->buffer) {
  				t->buffer->transaction = NULL;
  				t->buffer = NULL;
  			}
  			t = t->to_parent;
  		} else if (t->from == thread) {
  			t->from = NULL;
  			t = t->from_parent;
  		} else
  			BUG();
7a4408c6b   Todd Kjos   binder: make sure...
4325
4326
4327
  		spin_unlock(&last_t->lock);
  		if (t)
  			spin_lock(&t->lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4328
  	}
7a3cee43e   Martijn Coenen   ANDROID: binder: ...
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
  
  	/*
  	 * If this thread used poll, make sure we remove the waitqueue
  	 * from any epoll data structures holding it with POLLFREE.
  	 * waitqueue_active() is safe to use here because we're holding
  	 * the inner lock.
  	 */
  	if ((thread->looper & BINDER_LOOPER_STATE_POLL) &&
  	    waitqueue_active(&thread->wait)) {
  		wake_up_poll(&thread->wait, POLLHUP | POLLFREE);
  	}
7bd7b0e63   Todd Kjos   binder: protect p...
4340
  	binder_inner_proc_unlock(thread->proc);
7a4408c6b   Todd Kjos   binder: make sure...
4341

441b5d10e   Martijn Coenen   ANDROID: binder: ...
4342
4343
4344
4345
4346
4347
4348
4349
  	/*
  	 * This is needed to avoid races between wake_up_poll() above and
  	 * and ep_remove_waitqueue() called for other reasons (eg the epoll file
  	 * descriptor being closed); ep_remove_waitqueue() holds an RCU read
  	 * lock, so we can be sure it's done after calling synchronize_rcu().
  	 */
  	if (thread->looper & BINDER_LOOPER_STATE_POLL)
  		synchronize_rcu();
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4350
4351
  	if (send_reply)
  		binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
72196393a   Todd Kjos   binder: add spinl...
4352
  	binder_release_work(proc, &thread->todo);
7a4408c6b   Todd Kjos   binder: make sure...
4353
  	binder_thread_dec_tmpref(thread);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4354
4355
4356
4357
4358
4359
4360
4361
  	return active_transactions;
  }
  
  static unsigned int binder_poll(struct file *filp,
  				struct poll_table_struct *wait)
  {
  	struct binder_proc *proc = filp->private_data;
  	struct binder_thread *thread = NULL;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4362
  	bool wait_for_proc_work;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4363

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4364
  	thread = binder_get_thread(proc);
047ba51a5   Eric Biggers   binder: check for...
4365
4366
  	if (!thread)
  		return POLLERR;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4367

0b89d69a9   Martijn Coenen   binder: protect t...
4368
  	binder_inner_proc_lock(thread->proc);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4369
4370
  	thread->looper |= BINDER_LOOPER_STATE_POLL;
  	wait_for_proc_work = binder_available_for_proc_work_ilocked(thread);
0b89d69a9   Martijn Coenen   binder: protect t...
4371
  	binder_inner_proc_unlock(thread->proc);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4372

1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4373
  	poll_wait(filp, &thread->wait, wait);
66b83a4cd   Martijn Coenen   binder: call poll...
4374
  	if (binder_has_work(thread, wait_for_proc_work))
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4375
  		return POLLIN;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4376
4377
  	return 0;
  }
78260ac62   Tair Rzayev   staging: android:...
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
  static int binder_ioctl_write_read(struct file *filp,
  				unsigned int cmd, unsigned long arg,
  				struct binder_thread *thread)
  {
  	int ret = 0;
  	struct binder_proc *proc = filp->private_data;
  	unsigned int size = _IOC_SIZE(cmd);
  	void __user *ubuf = (void __user *)arg;
  	struct binder_write_read bwr;
  
  	if (size != sizeof(struct binder_write_read)) {
  		ret = -EINVAL;
  		goto out;
  	}
  	if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
  		ret = -EFAULT;
  		goto out;
  	}
  	binder_debug(BINDER_DEBUG_READ_WRITE,
  		     "%d:%d write %lld at %016llx, read %lld at %016llx
  ",
  		     proc->pid, thread->pid,
  		     (u64)bwr.write_size, (u64)bwr.write_buffer,
  		     (u64)bwr.read_size, (u64)bwr.read_buffer);
  
  	if (bwr.write_size > 0) {
  		ret = binder_thread_write(proc, thread,
  					  bwr.write_buffer,
  					  bwr.write_size,
  					  &bwr.write_consumed);
  		trace_binder_write_done(ret);
  		if (ret < 0) {
  			bwr.read_consumed = 0;
  			if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  				ret = -EFAULT;
  			goto out;
  		}
  	}
  	if (bwr.read_size > 0) {
  		ret = binder_thread_read(proc, thread, bwr.read_buffer,
  					 bwr.read_size,
  					 &bwr.read_consumed,
  					 filp->f_flags & O_NONBLOCK);
  		trace_binder_read_done(ret);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4422
4423
  		binder_inner_proc_lock(proc);
  		if (!binder_worklist_empty_ilocked(&proc->todo))
408c68b17   Martijn Coenen   ANDROID: binder: ...
4424
  			binder_wakeup_proc_ilocked(proc);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4425
  		binder_inner_proc_unlock(proc);
78260ac62   Tair Rzayev   staging: android:...
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
  		if (ret < 0) {
  			if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
  				ret = -EFAULT;
  			goto out;
  		}
  	}
  	binder_debug(BINDER_DEBUG_READ_WRITE,
  		     "%d:%d wrote %lld of %lld, read return %lld of %lld
  ",
  		     proc->pid, thread->pid,
  		     (u64)bwr.write_consumed, (u64)bwr.write_size,
  		     (u64)bwr.read_consumed, (u64)bwr.read_size);
  	if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
  		ret = -EFAULT;
  		goto out;
  	}
  out:
  	return ret;
  }
  
  static int binder_ioctl_set_ctx_mgr(struct file *filp)
  {
  	int ret = 0;
  	struct binder_proc *proc = filp->private_data;
342e5c90b   Martijn Coenen   binder: Support m...
4450
  	struct binder_context *context = proc->context;
c44b1231f   Todd Kjos   binder: add prote...
4451
  	struct binder_node *new_node;
78260ac62   Tair Rzayev   staging: android:...
4452
  	kuid_t curr_euid = current_euid();
c44b1231f   Todd Kjos   binder: add prote...
4453
  	mutex_lock(&context->context_mgr_node_lock);
342e5c90b   Martijn Coenen   binder: Support m...
4454
  	if (context->binder_context_mgr_node) {
78260ac62   Tair Rzayev   staging: android:...
4455
4456
4457
4458
4459
  		pr_err("BINDER_SET_CONTEXT_MGR already set
  ");
  		ret = -EBUSY;
  		goto out;
  	}
79af73079   Stephen Smalley   Add security hook...
4460
4461
4462
  	ret = security_binder_set_context_mgr(proc->tsk);
  	if (ret < 0)
  		goto out;
342e5c90b   Martijn Coenen   binder: Support m...
4463
4464
  	if (uid_valid(context->binder_context_mgr_uid)) {
  		if (!uid_eq(context->binder_context_mgr_uid, curr_euid)) {
78260ac62   Tair Rzayev   staging: android:...
4465
4466
4467
4468
  			pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d
  ",
  			       from_kuid(&init_user_ns, curr_euid),
  			       from_kuid(&init_user_ns,
342e5c90b   Martijn Coenen   binder: Support m...
4469
  					 context->binder_context_mgr_uid));
78260ac62   Tair Rzayev   staging: android:...
4470
4471
4472
4473
  			ret = -EPERM;
  			goto out;
  		}
  	} else {
342e5c90b   Martijn Coenen   binder: Support m...
4474
  		context->binder_context_mgr_uid = curr_euid;
78260ac62   Tair Rzayev   staging: android:...
4475
  	}
673068eee   Todd Kjos   binder: add spinl...
4476
  	new_node = binder_new_node(proc, NULL);
c44b1231f   Todd Kjos   binder: add prote...
4477
  	if (!new_node) {
78260ac62   Tair Rzayev   staging: android:...
4478
4479
4480
  		ret = -ENOMEM;
  		goto out;
  	}
673068eee   Todd Kjos   binder: add spinl...
4481
  	binder_node_lock(new_node);
c44b1231f   Todd Kjos   binder: add prote...
4482
4483
4484
4485
4486
  	new_node->local_weak_refs++;
  	new_node->local_strong_refs++;
  	new_node->has_strong_ref = 1;
  	new_node->has_weak_ref = 1;
  	context->binder_context_mgr_node = new_node;
673068eee   Todd Kjos   binder: add spinl...
4487
  	binder_node_unlock(new_node);
adc188422   Todd Kjos   binder: use node-...
4488
  	binder_put_node(new_node);
78260ac62   Tair Rzayev   staging: android:...
4489
  out:
c44b1231f   Todd Kjos   binder: add prote...
4490
  	mutex_unlock(&context->context_mgr_node_lock);
78260ac62   Tair Rzayev   staging: android:...
4491
4492
  	return ret;
  }
abcc61537   Colin Cross   ANDROID: binder: ...
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
  static int binder_ioctl_get_node_debug_info(struct binder_proc *proc,
  				struct binder_node_debug_info *info)
  {
  	struct rb_node *n;
  	binder_uintptr_t ptr = info->ptr;
  
  	memset(info, 0, sizeof(*info));
  
  	binder_inner_proc_lock(proc);
  	for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) {
  		struct binder_node *node = rb_entry(n, struct binder_node,
  						    rb_node);
  		if (node->ptr > ptr) {
  			info->ptr = node->ptr;
  			info->cookie = node->cookie;
  			info->has_strong_ref = node->has_strong_ref;
  			info->has_weak_ref = node->has_weak_ref;
  			break;
  		}
  	}
  	binder_inner_proc_unlock(proc);
  
  	return 0;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4517
4518
4519
4520
4521
4522
4523
  static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  {
  	int ret;
  	struct binder_proc *proc = filp->private_data;
  	struct binder_thread *thread;
  	unsigned int size = _IOC_SIZE(cmd);
  	void __user *ubuf = (void __user *)arg;
78260ac62   Tair Rzayev   staging: android:...
4524
4525
4526
  	/*pr_info("binder_ioctl: %d:%d %x %lx
  ",
  			proc->pid, current->pid, cmd, arg);*/
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4527

4175e2b46   Sherry Yang   android: binder: ...
4528
  	binder_selftest_alloc(&proc->alloc);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4529
  	trace_binder_ioctl(cmd, arg);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4530
4531
  	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  	if (ret)
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4532
  		goto err_unlocked;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4533

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4534
4535
4536
4537
4538
4539
4540
  	thread = binder_get_thread(proc);
  	if (thread == NULL) {
  		ret = -ENOMEM;
  		goto err;
  	}
  
  	switch (cmd) {
78260ac62   Tair Rzayev   staging: android:...
4541
4542
4543
  	case BINDER_WRITE_READ:
  		ret = binder_ioctl_write_read(filp, cmd, arg, thread);
  		if (ret)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4544
  			goto err;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4545
  		break;
b3e686128   Todd Kjos   binder: use inner...
4546
4547
4548
4549
4550
  	case BINDER_SET_MAX_THREADS: {
  		int max_threads;
  
  		if (copy_from_user(&max_threads, ubuf,
  				   sizeof(max_threads))) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4551
4552
4553
  			ret = -EINVAL;
  			goto err;
  		}
b3e686128   Todd Kjos   binder: use inner...
4554
4555
4556
  		binder_inner_proc_lock(proc);
  		proc->max_threads = max_threads;
  		binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4557
  		break;
b3e686128   Todd Kjos   binder: use inner...
4558
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4559
  	case BINDER_SET_CONTEXT_MGR:
78260ac62   Tair Rzayev   staging: android:...
4560
4561
  		ret = binder_ioctl_set_ctx_mgr(filp);
  		if (ret)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4562
  			goto err;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4563
4564
  		break;
  	case BINDER_THREAD_EXIT:
56b468fc7   Anmol Sarma   Staging: android:...
4565
4566
  		binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4567
  			     proc->pid, thread->pid);
7a4408c6b   Todd Kjos   binder: make sure...
4568
  		binder_thread_release(proc, thread);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4569
4570
  		thread = NULL;
  		break;
36c89c0a6   Mathieu Maret   staging: binder: ...
4571
4572
  	case BINDER_VERSION: {
  		struct binder_version __user *ver = ubuf;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4573
4574
4575
4576
  		if (size != sizeof(struct binder_version)) {
  			ret = -EINVAL;
  			goto err;
  		}
36c89c0a6   Mathieu Maret   staging: binder: ...
4577
4578
  		if (put_user(BINDER_CURRENT_PROTOCOL_VERSION,
  			     &ver->protocol_version)) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4579
4580
4581
4582
  			ret = -EINVAL;
  			goto err;
  		}
  		break;
36c89c0a6   Mathieu Maret   staging: binder: ...
4583
  	}
abcc61537   Colin Cross   ANDROID: binder: ...
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
  	case BINDER_GET_NODE_DEBUG_INFO: {
  		struct binder_node_debug_info info;
  
  		if (copy_from_user(&info, ubuf, sizeof(info))) {
  			ret = -EFAULT;
  			goto err;
  		}
  
  		ret = binder_ioctl_get_node_debug_info(proc, &info);
  		if (ret < 0)
  			goto err;
  
  		if (copy_to_user(ubuf, &info, sizeof(info))) {
  			ret = -EFAULT;
  			goto err;
  		}
  		break;
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4602
4603
4604
4605
4606
4607
4608
  	default:
  		ret = -EINVAL;
  		goto err;
  	}
  	ret = 0;
  err:
  	if (thread)
08dabceef   Todd Kjos   binder: don't mod...
4609
  		thread->looper_need_return = false;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4610
4611
  	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
  	if (ret && ret != -ERESTARTSYS)
56b468fc7   Anmol Sarma   Staging: android:...
4612
4613
  		pr_info("%d:%d ioctl %x %lx returned %d
  ", proc->pid, current->pid, cmd, arg, ret);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4614
4615
  err_unlocked:
  	trace_binder_ioctl_done(ret);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4616
4617
4618
4619
4620
4621
  	return ret;
  }
  
  static void binder_vma_open(struct vm_area_struct *vma)
  {
  	struct binder_proc *proc = vma->vm_private_data;
10f62861b   Seunghun Lee   staging: android:...
4622

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4623
  	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
56b468fc7   Anmol Sarma   Staging: android:...
4624
4625
  		     "%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4626
4627
4628
  		     proc->pid, vma->vm_start, vma->vm_end,
  		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
  		     (unsigned long)pgprot_val(vma->vm_page_prot));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4629
4630
4631
4632
4633
  }
  
  static void binder_vma_close(struct vm_area_struct *vma)
  {
  	struct binder_proc *proc = vma->vm_private_data;
10f62861b   Seunghun Lee   staging: android:...
4634

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4635
  	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
56b468fc7   Anmol Sarma   Staging: android:...
4636
4637
  		     "%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4638
4639
4640
  		     proc->pid, vma->vm_start, vma->vm_end,
  		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
  		     (unsigned long)pgprot_val(vma->vm_page_prot));
19c987241   Todd Kjos   binder: separate ...
4641
  	binder_alloc_vma_close(&proc->alloc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4642
4643
  	binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES);
  }
11bac8000   Dave Jiang   mm, fs: reduce fa...
4644
  static int binder_vm_fault(struct vm_fault *vmf)
ddac7d5fb   Vinayak Menon   staging: binder: ...
4645
4646
4647
  {
  	return VM_FAULT_SIGBUS;
  }
7cbea8dc0   Kirill A. Shutemov   mm: mark most vm_...
4648
  static const struct vm_operations_struct binder_vm_ops = {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4649
4650
  	.open = binder_vma_open,
  	.close = binder_vma_close,
ddac7d5fb   Vinayak Menon   staging: binder: ...
4651
  	.fault = binder_vm_fault,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4652
  };
19c987241   Todd Kjos   binder: separate ...
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
  static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
  {
  	int ret;
  	struct binder_proc *proc = filp->private_data;
  	const char *failure_string;
  
  	if (proc->tsk != current->group_leader)
  		return -EINVAL;
  
  	if ((vma->vm_end - vma->vm_start) > SZ_4M)
  		vma->vm_end = vma->vm_start + SZ_4M;
  
  	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
  		     "%s: %d %lx-%lx (%ld K) vma %lx pagep %lx
  ",
  		     __func__, proc->pid, vma->vm_start, vma->vm_end,
  		     (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
  		     (unsigned long)pgprot_val(vma->vm_page_prot));
  
  	if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
  		ret = -EPERM;
  		failure_string = "bad vm_flags";
  		goto err_bad_arg;
  	}
  	vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE;
  	vma->vm_ops = &binder_vm_ops;
  	vma->vm_private_data = proc;
  
  	ret = binder_alloc_mmap_handler(&proc->alloc, vma);
  	if (ret)
  		return ret;
d87f1bc7d   Todd Kjos   binder: fix proc-...
4684
  	mutex_lock(&proc->files_lock);
19c987241   Todd Kjos   binder: separate ...
4685
  	proc->files = get_files_struct(current);
d87f1bc7d   Todd Kjos   binder: fix proc-...
4686
  	mutex_unlock(&proc->files_lock);
19c987241   Todd Kjos   binder: separate ...
4687
  	return 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4688
  err_bad_arg:
258767fed   Sherwin Soltani   drivers: staging:...
4689
4690
  	pr_err("binder_mmap: %d %lx-%lx %s failed %d
  ",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4691
4692
4693
4694
4695
4696
4697
  	       proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
  	return ret;
  }
  
  static int binder_open(struct inode *nodp, struct file *filp)
  {
  	struct binder_proc *proc;
ac4812c5f   Martijn Coenen   binder: Support m...
4698
  	struct binder_device *binder_dev;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4699
4700
4701
4702
4703
4704
4705
4706
  
  	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d
  ",
  		     current->group_leader->pid, current->pid);
  
  	proc = kzalloc(sizeof(*proc), GFP_KERNEL);
  	if (proc == NULL)
  		return -ENOMEM;
9630fe883   Todd Kjos   binder: introduce...
4707
4708
  	spin_lock_init(&proc->inner_lock);
  	spin_lock_init(&proc->outer_lock);
c4ea41ba1   Todd Kjos   binder: use group...
4709
4710
  	get_task_struct(current->group_leader);
  	proc->tsk = current->group_leader;
d87f1bc7d   Todd Kjos   binder: fix proc-...
4711
  	mutex_init(&proc->files_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4712
  	INIT_LIST_HEAD(&proc->todo);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4713
  	proc->default_priority = task_nice(current);
ac4812c5f   Martijn Coenen   binder: Support m...
4714
4715
4716
  	binder_dev = container_of(filp->private_data, struct binder_device,
  				  miscdev);
  	proc->context = &binder_dev->context;
19c987241   Todd Kjos   binder: separate ...
4717
  	binder_alloc_init(&proc->alloc);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4718

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4719
  	binder_stats_created(BINDER_STAT_PROC);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4720
4721
  	proc->pid = current->group_leader->pid;
  	INIT_LIST_HEAD(&proc->delivered_death);
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
4722
  	INIT_LIST_HEAD(&proc->waiting_threads);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4723
  	filp->private_data = proc;
975a1ac9a   Arve Hjønnevåg   Staging: android:...
4724

c44b1231f   Todd Kjos   binder: add prote...
4725
4726
4727
  	mutex_lock(&binder_procs_lock);
  	hlist_add_head(&proc->proc_node, &binder_procs);
  	mutex_unlock(&binder_procs_lock);
16b665543   Arve Hjønnevåg   staging: android:...
4728
  	if (binder_debugfs_dir_entry_proc) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4729
  		char strbuf[11];
10f62861b   Seunghun Lee   staging: android:...
4730

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4731
  		snprintf(strbuf, sizeof(strbuf), "%u", proc->pid);
14db31814   Martijn Coenen   binder: Deal with...
4732
4733
4734
4735
4736
4737
4738
  		/*
  		 * proc debug entries are shared between contexts, so
  		 * this will fail if the process tries to open the driver
  		 * again with a different context. The priting code will
  		 * anyway print all contexts that a given PID has, so this
  		 * is not a problem.
  		 */
16b665543   Arve Hjønnevåg   staging: android:...
4739
  		proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO,
14db31814   Martijn Coenen   binder: Deal with...
4740
4741
4742
  			binder_debugfs_dir_entry_proc,
  			(void *)(unsigned long)proc->pid,
  			&binder_proc_fops);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
  	}
  
  	return 0;
  }
  
  static int binder_flush(struct file *filp, fl_owner_t id)
  {
  	struct binder_proc *proc = filp->private_data;
  
  	binder_defer_work(proc, BINDER_DEFERRED_FLUSH);
  
  	return 0;
  }
  
  static void binder_deferred_flush(struct binder_proc *proc)
  {
  	struct rb_node *n;
  	int wake_count = 0;
10f62861b   Seunghun Lee   staging: android:...
4761

7bd7b0e63   Todd Kjos   binder: protect p...
4762
  	binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4763
4764
  	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) {
  		struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node);
10f62861b   Seunghun Lee   staging: android:...
4765

08dabceef   Todd Kjos   binder: don't mod...
4766
  		thread->looper_need_return = true;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4767
4768
4769
4770
4771
  		if (thread->looper & BINDER_LOOPER_STATE_WAITING) {
  			wake_up_interruptible(&thread->wait);
  			wake_count++;
  		}
  	}
7bd7b0e63   Todd Kjos   binder: protect p...
4772
  	binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
  
  	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
  		     "binder_flush: %d woke %d threads
  ", proc->pid,
  		     wake_count);
  }
  
  static int binder_release(struct inode *nodp, struct file *filp)
  {
  	struct binder_proc *proc = filp->private_data;
10f62861b   Seunghun Lee   staging: android:...
4783

16b665543   Arve Hjønnevåg   staging: android:...
4784
  	debugfs_remove(proc->debugfs_entry);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4785
4786
4787
4788
  	binder_defer_work(proc, BINDER_DEFERRED_RELEASE);
  
  	return 0;
  }
008fa749e   Mirsal Ennaime   drivers: android:...
4789
4790
4791
4792
  static int binder_node_release(struct binder_node *node, int refs)
  {
  	struct binder_ref *ref;
  	int death = 0;
ed29721e2   Todd Kjos   binder: use inner...
4793
  	struct binder_proc *proc = node->proc;
008fa749e   Mirsal Ennaime   drivers: android:...
4794

72196393a   Todd Kjos   binder: add spinl...
4795
  	binder_release_work(proc, &node->async_todo);
ed29721e2   Todd Kjos   binder: use inner...
4796

673068eee   Todd Kjos   binder: add spinl...
4797
  	binder_node_lock(node);
ed29721e2   Todd Kjos   binder: use inner...
4798
  	binder_inner_proc_lock(proc);
72196393a   Todd Kjos   binder: add spinl...
4799
  	binder_dequeue_work_ilocked(&node->work);
adc188422   Todd Kjos   binder: use node-...
4800
4801
4802
4803
4804
  	/*
  	 * The caller must have taken a temporary ref on the node,
  	 */
  	BUG_ON(!node->tmp_refs);
  	if (hlist_empty(&node->refs) && node->tmp_refs == 1) {
ed29721e2   Todd Kjos   binder: use inner...
4805
  		binder_inner_proc_unlock(proc);
673068eee   Todd Kjos   binder: add spinl...
4806
  		binder_node_unlock(node);
ed29721e2   Todd Kjos   binder: use inner...
4807
  		binder_free_node(node);
008fa749e   Mirsal Ennaime   drivers: android:...
4808
4809
4810
4811
4812
4813
4814
  
  		return refs;
  	}
  
  	node->proc = NULL;
  	node->local_strong_refs = 0;
  	node->local_weak_refs = 0;
ed29721e2   Todd Kjos   binder: use inner...
4815
  	binder_inner_proc_unlock(proc);
c44b1231f   Todd Kjos   binder: add prote...
4816
4817
  
  	spin_lock(&binder_dead_nodes_lock);
008fa749e   Mirsal Ennaime   drivers: android:...
4818
  	hlist_add_head(&node->dead_node, &binder_dead_nodes);
c44b1231f   Todd Kjos   binder: add prote...
4819
  	spin_unlock(&binder_dead_nodes_lock);
008fa749e   Mirsal Ennaime   drivers: android:...
4820
4821
4822
  
  	hlist_for_each_entry(ref, &node->refs, node_entry) {
  		refs++;
ab51ec6bd   Martijn Coenen   binder: fix death...
4823
4824
4825
4826
4827
4828
4829
4830
4831
  		/*
  		 * Need the node lock to synchronize
  		 * with new notification requests and the
  		 * inner lock to synchronize with queued
  		 * death notifications.
  		 */
  		binder_inner_proc_lock(ref->proc);
  		if (!ref->death) {
  			binder_inner_proc_unlock(ref->proc);
e194fd8a5   Arve Hjønnevåg   staging: binder: ...
4832
  			continue;
ab51ec6bd   Martijn Coenen   binder: fix death...
4833
  		}
008fa749e   Mirsal Ennaime   drivers: android:...
4834
4835
  
  		death++;
ab51ec6bd   Martijn Coenen   binder: fix death...
4836
4837
4838
4839
  		BUG_ON(!list_empty(&ref->death->work.entry));
  		ref->death->work.type = BINDER_WORK_DEAD_BINDER;
  		binder_enqueue_work_ilocked(&ref->death->work,
  					    &ref->proc->todo);
408c68b17   Martijn Coenen   ANDROID: binder: ...
4840
  		binder_wakeup_proc_ilocked(ref->proc);
72196393a   Todd Kjos   binder: add spinl...
4841
  		binder_inner_proc_unlock(ref->proc);
008fa749e   Mirsal Ennaime   drivers: android:...
4842
  	}
008fa749e   Mirsal Ennaime   drivers: android:...
4843
4844
4845
4846
  	binder_debug(BINDER_DEBUG_DEAD_BINDER,
  		     "node %d now dead, refs %d, death %d
  ",
  		     node->debug_id, refs, death);
673068eee   Todd Kjos   binder: add spinl...
4847
  	binder_node_unlock(node);
adc188422   Todd Kjos   binder: use node-...
4848
  	binder_put_node(node);
008fa749e   Mirsal Ennaime   drivers: android:...
4849
4850
4851
  
  	return refs;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4852
4853
  static void binder_deferred_release(struct binder_proc *proc)
  {
342e5c90b   Martijn Coenen   binder: Support m...
4854
  	struct binder_context *context = proc->context;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4855
  	struct rb_node *n;
19c987241   Todd Kjos   binder: separate ...
4856
  	int threads, nodes, incoming_refs, outgoing_refs, active_transactions;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4857

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4858
  	BUG_ON(proc->files);
c44b1231f   Todd Kjos   binder: add prote...
4859
  	mutex_lock(&binder_procs_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4860
  	hlist_del(&proc->proc_node);
c44b1231f   Todd Kjos   binder: add prote...
4861
  	mutex_unlock(&binder_procs_lock);
53413e7dc   Mirsal Ennaime   drivers: android:...
4862

c44b1231f   Todd Kjos   binder: add prote...
4863
  	mutex_lock(&context->context_mgr_node_lock);
342e5c90b   Martijn Coenen   binder: Support m...
4864
4865
  	if (context->binder_context_mgr_node &&
  	    context->binder_context_mgr_node->proc == proc) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4866
  		binder_debug(BINDER_DEBUG_DEAD_BINDER,
c07c933fc   Mirsal Ennaime   drivers: android:...
4867
4868
4869
  			     "%s: %d context_mgr_node gone
  ",
  			     __func__, proc->pid);
342e5c90b   Martijn Coenen   binder: Support m...
4870
  		context->binder_context_mgr_node = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4871
  	}
c44b1231f   Todd Kjos   binder: add prote...
4872
  	mutex_unlock(&context->context_mgr_node_lock);
7bd7b0e63   Todd Kjos   binder: protect p...
4873
  	binder_inner_proc_lock(proc);
7a4408c6b   Todd Kjos   binder: make sure...
4874
4875
4876
4877
4878
  	/*
  	 * Make sure proc stays alive after we
  	 * remove all the threads
  	 */
  	proc->tmp_ref++;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4879

7a4408c6b   Todd Kjos   binder: make sure...
4880
  	proc->is_dead = true;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4881
4882
4883
  	threads = 0;
  	active_transactions = 0;
  	while ((n = rb_first(&proc->threads))) {
53413e7dc   Mirsal Ennaime   drivers: android:...
4884
4885
4886
  		struct binder_thread *thread;
  
  		thread = rb_entry(n, struct binder_thread, rb_node);
7bd7b0e63   Todd Kjos   binder: protect p...
4887
  		binder_inner_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4888
  		threads++;
7a4408c6b   Todd Kjos   binder: make sure...
4889
  		active_transactions += binder_thread_release(proc, thread);
7bd7b0e63   Todd Kjos   binder: protect p...
4890
  		binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4891
  	}
53413e7dc   Mirsal Ennaime   drivers: android:...
4892

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4893
4894
4895
  	nodes = 0;
  	incoming_refs = 0;
  	while ((n = rb_first(&proc->nodes))) {
53413e7dc   Mirsal Ennaime   drivers: android:...
4896
  		struct binder_node *node;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4897

53413e7dc   Mirsal Ennaime   drivers: android:...
4898
  		node = rb_entry(n, struct binder_node, rb_node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4899
  		nodes++;
adc188422   Todd Kjos   binder: use node-...
4900
4901
4902
4903
4904
  		/*
  		 * take a temporary ref on the node before
  		 * calling binder_node_release() which will either
  		 * kfree() the node or call binder_put_node()
  		 */
da0fa9e4e   Todd Kjos   binder: protect p...
4905
  		binder_inc_node_tmpref_ilocked(node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4906
  		rb_erase(&node->rb_node, &proc->nodes);
da0fa9e4e   Todd Kjos   binder: protect p...
4907
  		binder_inner_proc_unlock(proc);
008fa749e   Mirsal Ennaime   drivers: android:...
4908
  		incoming_refs = binder_node_release(node, incoming_refs);
da0fa9e4e   Todd Kjos   binder: protect p...
4909
  		binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4910
  	}
da0fa9e4e   Todd Kjos   binder: protect p...
4911
  	binder_inner_proc_unlock(proc);
53413e7dc   Mirsal Ennaime   drivers: android:...
4912

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4913
  	outgoing_refs = 0;
2c1838dc6   Todd Kjos   binder: protect b...
4914
  	binder_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4915
  	while ((n = rb_first(&proc->refs_by_desc))) {
53413e7dc   Mirsal Ennaime   drivers: android:...
4916
4917
4918
  		struct binder_ref *ref;
  
  		ref = rb_entry(n, struct binder_ref, rb_node_desc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4919
  		outgoing_refs++;
2c1838dc6   Todd Kjos   binder: protect b...
4920
4921
  		binder_cleanup_ref_olocked(ref);
  		binder_proc_unlock(proc);
372e3147d   Todd Kjos   binder: refactor ...
4922
  		binder_free_ref(ref);
2c1838dc6   Todd Kjos   binder: protect b...
4923
  		binder_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4924
  	}
2c1838dc6   Todd Kjos   binder: protect b...
4925
  	binder_proc_unlock(proc);
53413e7dc   Mirsal Ennaime   drivers: android:...
4926

72196393a   Todd Kjos   binder: add spinl...
4927
4928
  	binder_release_work(proc, &proc->todo);
  	binder_release_work(proc, &proc->delivered_death);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4929

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4930
  	binder_debug(BINDER_DEBUG_OPEN_CLOSE,
19c987241   Todd Kjos   binder: separate ...
4931
4932
  		     "%s: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d
  ",
c07c933fc   Mirsal Ennaime   drivers: android:...
4933
  		     __func__, proc->pid, threads, nodes, incoming_refs,
19c987241   Todd Kjos   binder: separate ...
4934
  		     outgoing_refs, active_transactions);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4935

7a4408c6b   Todd Kjos   binder: make sure...
4936
  	binder_proc_dec_tmpref(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4937
4938
4939
4940
4941
4942
4943
4944
  }
  
  static void binder_deferred_func(struct work_struct *work)
  {
  	struct binder_proc *proc;
  	struct files_struct *files;
  
  	int defer;
10f62861b   Seunghun Lee   staging: android:...
4945

355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4946
  	do {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
  		mutex_lock(&binder_deferred_lock);
  		if (!hlist_empty(&binder_deferred_list)) {
  			proc = hlist_entry(binder_deferred_list.first,
  					struct binder_proc, deferred_work_node);
  			hlist_del_init(&proc->deferred_work_node);
  			defer = proc->deferred_work;
  			proc->deferred_work = 0;
  		} else {
  			proc = NULL;
  			defer = 0;
  		}
  		mutex_unlock(&binder_deferred_lock);
  
  		files = NULL;
  		if (defer & BINDER_DEFERRED_PUT_FILES) {
d87f1bc7d   Todd Kjos   binder: fix proc-...
4962
  			mutex_lock(&proc->files_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4963
4964
4965
  			files = proc->files;
  			if (files)
  				proc->files = NULL;
d87f1bc7d   Todd Kjos   binder: fix proc-...
4966
  			mutex_unlock(&proc->files_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4967
4968
4969
4970
4971
4972
4973
  		}
  
  		if (defer & BINDER_DEFERRED_FLUSH)
  			binder_deferred_flush(proc);
  
  		if (defer & BINDER_DEFERRED_RELEASE)
  			binder_deferred_release(proc); /* frees proc */
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
  		if (files)
  			put_files_struct(files);
  	} while (proc);
  }
  static DECLARE_WORK(binder_deferred_work, binder_deferred_func);
  
  static void
  binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer)
  {
  	mutex_lock(&binder_deferred_lock);
  	proc->deferred_work |= defer;
  	if (hlist_unhashed(&proc->deferred_work_node)) {
  		hlist_add_head(&proc->deferred_work_node,
  				&binder_deferred_list);
1beba52d4   Bhaktipriya Shridhar   android: binder: ...
4988
  		schedule_work(&binder_deferred_work);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
4989
4990
4991
  	}
  	mutex_unlock(&binder_deferred_lock);
  }
5f2f63696   Todd Kjos   binder: protect a...
4992
4993
4994
4995
  static void print_binder_transaction_ilocked(struct seq_file *m,
  					     struct binder_proc *proc,
  					     const char *prefix,
  					     struct binder_transaction *t)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
4996
  {
5f2f63696   Todd Kjos   binder: protect a...
4997
4998
  	struct binder_proc *to_proc;
  	struct binder_buffer *buffer = t->buffer;
7a4408c6b   Todd Kjos   binder: make sure...
4999
  	spin_lock(&t->lock);
5f2f63696   Todd Kjos   binder: protect a...
5000
  	to_proc = t->to_proc;
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5001
  	seq_printf(m,
b46af094b   Todd Kjos   binder: replace "...
5002
  		   "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d",
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5003
5004
5005
  		   prefix, t->debug_id, t,
  		   t->from ? t->from->proc->pid : 0,
  		   t->from ? t->from->pid : 0,
5f2f63696   Todd Kjos   binder: protect a...
5006
  		   to_proc ? to_proc->pid : 0,
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5007
5008
  		   t->to_thread ? t->to_thread->pid : 0,
  		   t->code, t->flags, t->priority, t->need_reply);
7a4408c6b   Todd Kjos   binder: make sure...
5009
  	spin_unlock(&t->lock);
5f2f63696   Todd Kjos   binder: protect a...
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
  	if (proc != to_proc) {
  		/*
  		 * Can only safely deref buffer if we are holding the
  		 * correct proc inner lock for this node
  		 */
  		seq_puts(m, "
  ");
  		return;
  	}
  
  	if (buffer == NULL) {
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5021
5022
5023
  		seq_puts(m, " buffer free
  ");
  		return;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5024
  	}
5f2f63696   Todd Kjos   binder: protect a...
5025
5026
  	if (buffer->target_node)
  		seq_printf(m, " node %d", buffer->target_node->debug_id);
b46af094b   Todd Kjos   binder: replace "...
5027
5028
  	seq_printf(m, " size %zd:%zd data %pK
  ",
5f2f63696   Todd Kjos   binder: protect a...
5029
5030
  		   buffer->data_size, buffer->offsets_size,
  		   buffer->data);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5031
  }
5f2f63696   Todd Kjos   binder: protect a...
5032
5033
5034
5035
5036
  static void print_binder_work_ilocked(struct seq_file *m,
  				     struct binder_proc *proc,
  				     const char *prefix,
  				     const char *transaction_prefix,
  				     struct binder_work *w)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5037
5038
5039
5040
5041
5042
5043
  {
  	struct binder_node *node;
  	struct binder_transaction *t;
  
  	switch (w->type) {
  	case BINDER_WORK_TRANSACTION:
  		t = container_of(w, struct binder_transaction, work);
5f2f63696   Todd Kjos   binder: protect a...
5044
5045
  		print_binder_transaction_ilocked(
  				m, proc, transaction_prefix, t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5046
  		break;
26549d177   Todd Kjos   binder: guarantee...
5047
5048
5049
5050
5051
5052
5053
5054
  	case BINDER_WORK_RETURN_ERROR: {
  		struct binder_error *e = container_of(
  				w, struct binder_error, work);
  
  		seq_printf(m, "%stransaction error: %u
  ",
  			   prefix, e->cmd);
  	} break;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5055
  	case BINDER_WORK_TRANSACTION_COMPLETE:
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5056
5057
  		seq_printf(m, "%stransaction complete
  ", prefix);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5058
5059
5060
  		break;
  	case BINDER_WORK_NODE:
  		node = container_of(w, struct binder_node, work);
da49889de   Arve Hjønnevåg   staging: binder: ...
5061
5062
5063
5064
  		seq_printf(m, "%snode work %d: u%016llx c%016llx
  ",
  			   prefix, node->debug_id,
  			   (u64)node->ptr, (u64)node->cookie);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5065
5066
  		break;
  	case BINDER_WORK_DEAD_BINDER:
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5067
5068
  		seq_printf(m, "%shas dead binder
  ", prefix);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5069
5070
  		break;
  	case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5071
5072
  		seq_printf(m, "%shas cleared dead binder
  ", prefix);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5073
5074
  		break;
  	case BINDER_WORK_CLEAR_DEATH_NOTIFICATION:
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5075
5076
  		seq_printf(m, "%shas cleared death notification
  ", prefix);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5077
5078
  		break;
  	default:
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5079
5080
  		seq_printf(m, "%sunknown work: type %d
  ", prefix, w->type);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5081
5082
  		break;
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5083
  }
72196393a   Todd Kjos   binder: add spinl...
5084
5085
5086
  static void print_binder_thread_ilocked(struct seq_file *m,
  					struct binder_thread *thread,
  					int print_always)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5087
5088
5089
  {
  	struct binder_transaction *t;
  	struct binder_work *w;
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5090
5091
  	size_t start_pos = m->count;
  	size_t header_pos;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5092

7a4408c6b   Todd Kjos   binder: make sure...
5093
5094
  	seq_printf(m, "  thread %d: l %02x need_return %d tr %d
  ",
08dabceef   Todd Kjos   binder: don't mod...
5095
  			thread->pid, thread->looper,
7a4408c6b   Todd Kjos   binder: make sure...
5096
5097
  			thread->looper_need_return,
  			atomic_read(&thread->tmp_ref));
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5098
  	header_pos = m->count;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5099
5100
  	t = thread->transaction_stack;
  	while (t) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5101
  		if (t->from == thread) {
5f2f63696   Todd Kjos   binder: protect a...
5102
5103
  			print_binder_transaction_ilocked(m, thread->proc,
  					"    outgoing transaction", t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5104
5105
  			t = t->from_parent;
  		} else if (t->to_thread == thread) {
5f2f63696   Todd Kjos   binder: protect a...
5106
  			print_binder_transaction_ilocked(m, thread->proc,
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5107
  						 "    incoming transaction", t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5108
5109
  			t = t->to_parent;
  		} else {
5f2f63696   Todd Kjos   binder: protect a...
5110
5111
  			print_binder_transaction_ilocked(m, thread->proc,
  					"    bad transaction", t);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5112
5113
5114
5115
  			t = NULL;
  		}
  	}
  	list_for_each_entry(w, &thread->todo, entry) {
5f2f63696   Todd Kjos   binder: protect a...
5116
  		print_binder_work_ilocked(m, thread->proc, "    ",
72196393a   Todd Kjos   binder: add spinl...
5117
  					  "    pending transaction", w);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5118
  	}
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5119
5120
  	if (!print_always && m->count == header_pos)
  		m->count = start_pos;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5121
  }
da0fa9e4e   Todd Kjos   binder: protect p...
5122
5123
  static void print_binder_node_nilocked(struct seq_file *m,
  				       struct binder_node *node)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5124
5125
  {
  	struct binder_ref *ref;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5126
5127
5128
5129
  	struct binder_work *w;
  	int count;
  
  	count = 0;
b67bfe0d4   Sasha Levin   hlist: drop the n...
5130
  	hlist_for_each_entry(ref, &node->refs, node_entry)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5131
  		count++;
adc188422   Todd Kjos   binder: use node-...
5132
  	seq_printf(m, "  node %d: u%016llx c%016llx hs %d hw %d ls %d lw %d is %d iw %d tr %d",
da49889de   Arve Hjønnevåg   staging: binder: ...
5133
  		   node->debug_id, (u64)node->ptr, (u64)node->cookie,
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5134
5135
  		   node->has_strong_ref, node->has_weak_ref,
  		   node->local_strong_refs, node->local_weak_refs,
adc188422   Todd Kjos   binder: use node-...
5136
  		   node->internal_strong_refs, count, node->tmp_refs);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5137
  	if (count) {
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5138
  		seq_puts(m, " proc");
b67bfe0d4   Sasha Levin   hlist: drop the n...
5139
  		hlist_for_each_entry(ref, &node->refs, node_entry)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5140
  			seq_printf(m, " %d", ref->proc->pid);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5141
  	}
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5142
5143
  	seq_puts(m, "
  ");
72196393a   Todd Kjos   binder: add spinl...
5144
  	if (node->proc) {
72196393a   Todd Kjos   binder: add spinl...
5145
  		list_for_each_entry(w, &node->async_todo, entry)
5f2f63696   Todd Kjos   binder: protect a...
5146
  			print_binder_work_ilocked(m, node->proc, "    ",
72196393a   Todd Kjos   binder: add spinl...
5147
  					  "    pending async transaction", w);
72196393a   Todd Kjos   binder: add spinl...
5148
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5149
  }
2c1838dc6   Todd Kjos   binder: protect b...
5150
5151
  static void print_binder_ref_olocked(struct seq_file *m,
  				     struct binder_ref *ref)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5152
  {
673068eee   Todd Kjos   binder: add spinl...
5153
  	binder_node_lock(ref->node);
372e3147d   Todd Kjos   binder: refactor ...
5154
5155
5156
5157
5158
5159
  	seq_printf(m, "  ref %d: desc %d %snode %d s %d w %d d %pK
  ",
  		   ref->data.debug_id, ref->data.desc,
  		   ref->node->proc ? "" : "dead ",
  		   ref->node->debug_id, ref->data.strong,
  		   ref->data.weak, ref->death);
673068eee   Todd Kjos   binder: add spinl...
5160
  	binder_node_unlock(ref->node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5161
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5162
5163
  static void print_binder_proc(struct seq_file *m,
  			      struct binder_proc *proc, int print_all)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5164
5165
5166
  {
  	struct binder_work *w;
  	struct rb_node *n;
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5167
5168
  	size_t start_pos = m->count;
  	size_t header_pos;
da0fa9e4e   Todd Kjos   binder: protect p...
5169
  	struct binder_node *last_node = NULL;
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5170
5171
5172
  
  	seq_printf(m, "proc %d
  ", proc->pid);
14db31814   Martijn Coenen   binder: Deal with...
5173
5174
  	seq_printf(m, "context %s
  ", proc->context->name);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5175
  	header_pos = m->count;
72196393a   Todd Kjos   binder: add spinl...
5176
  	binder_inner_proc_lock(proc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5177
  	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
72196393a   Todd Kjos   binder: add spinl...
5178
  		print_binder_thread_ilocked(m, rb_entry(n, struct binder_thread,
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5179
  						rb_node), print_all);
da0fa9e4e   Todd Kjos   binder: protect p...
5180

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5181
  	for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5182
5183
  		struct binder_node *node = rb_entry(n, struct binder_node,
  						    rb_node);
da0fa9e4e   Todd Kjos   binder: protect p...
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
  		/*
  		 * take a temporary reference on the node so it
  		 * survives and isn't removed from the tree
  		 * while we print it.
  		 */
  		binder_inc_node_tmpref_ilocked(node);
  		/* Need to drop inner lock to take node lock */
  		binder_inner_proc_unlock(proc);
  		if (last_node)
  			binder_put_node(last_node);
  		binder_node_inner_lock(node);
  		print_binder_node_nilocked(m, node);
  		binder_node_inner_unlock(node);
  		last_node = node;
  		binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5199
  	}
da0fa9e4e   Todd Kjos   binder: protect p...
5200
5201
5202
  	binder_inner_proc_unlock(proc);
  	if (last_node)
  		binder_put_node(last_node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5203
  	if (print_all) {
2c1838dc6   Todd Kjos   binder: protect b...
5204
  		binder_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5205
  		for (n = rb_first(&proc->refs_by_desc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5206
  		     n != NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5207
  		     n = rb_next(n))
2c1838dc6   Todd Kjos   binder: protect b...
5208
5209
5210
5211
  			print_binder_ref_olocked(m, rb_entry(n,
  							    struct binder_ref,
  							    rb_node_desc));
  		binder_proc_unlock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5212
  	}
19c987241   Todd Kjos   binder: separate ...
5213
  	binder_alloc_print_allocated(m, &proc->alloc);
72196393a   Todd Kjos   binder: add spinl...
5214
  	binder_inner_proc_lock(proc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5215
  	list_for_each_entry(w, &proc->todo, entry)
5f2f63696   Todd Kjos   binder: protect a...
5216
5217
  		print_binder_work_ilocked(m, proc, "  ",
  					  "  pending transaction", w);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5218
  	list_for_each_entry(w, &proc->delivered_death, entry) {
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5219
5220
  		seq_puts(m, "  has delivered dead binder
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5221
5222
  		break;
  	}
72196393a   Todd Kjos   binder: add spinl...
5223
  	binder_inner_proc_unlock(proc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5224
5225
  	if (!print_all && m->count == header_pos)
  		m->count = start_pos;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5226
  }
167bccbd8   Cruz Julian Bishop   staging: android:...
5227
  static const char * const binder_return_strings[] = {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
  	"BR_ERROR",
  	"BR_OK",
  	"BR_TRANSACTION",
  	"BR_REPLY",
  	"BR_ACQUIRE_RESULT",
  	"BR_DEAD_REPLY",
  	"BR_TRANSACTION_COMPLETE",
  	"BR_INCREFS",
  	"BR_ACQUIRE",
  	"BR_RELEASE",
  	"BR_DECREFS",
  	"BR_ATTEMPT_ACQUIRE",
  	"BR_NOOP",
  	"BR_SPAWN_LOOPER",
  	"BR_FINISHED",
  	"BR_DEAD_BINDER",
  	"BR_CLEAR_DEATH_NOTIFICATION_DONE",
  	"BR_FAILED_REPLY"
  };
167bccbd8   Cruz Julian Bishop   staging: android:...
5247
  static const char * const binder_command_strings[] = {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
  	"BC_TRANSACTION",
  	"BC_REPLY",
  	"BC_ACQUIRE_RESULT",
  	"BC_FREE_BUFFER",
  	"BC_INCREFS",
  	"BC_ACQUIRE",
  	"BC_RELEASE",
  	"BC_DECREFS",
  	"BC_INCREFS_DONE",
  	"BC_ACQUIRE_DONE",
  	"BC_ATTEMPT_ACQUIRE",
  	"BC_REGISTER_LOOPER",
  	"BC_ENTER_LOOPER",
  	"BC_EXIT_LOOPER",
  	"BC_REQUEST_DEATH_NOTIFICATION",
  	"BC_CLEAR_DEATH_NOTIFICATION",
7980240b6   Martijn Coenen   binder: Add suppo...
5264
5265
5266
  	"BC_DEAD_BINDER_DONE",
  	"BC_TRANSACTION_SG",
  	"BC_REPLY_SG",
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5267
  };
167bccbd8   Cruz Julian Bishop   staging: android:...
5268
  static const char * const binder_objstat_strings[] = {
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5269
5270
5271
5272
5273
5274
5275
5276
  	"proc",
  	"thread",
  	"node",
  	"ref",
  	"death",
  	"transaction",
  	"transaction_complete"
  };
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5277
5278
  static void print_binder_stats(struct seq_file *m, const char *prefix,
  			       struct binder_stats *stats)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5279
5280
5281
5282
  {
  	int i;
  
  	BUILD_BUG_ON(ARRAY_SIZE(stats->bc) !=
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5283
  		     ARRAY_SIZE(binder_command_strings));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5284
  	for (i = 0; i < ARRAY_SIZE(stats->bc); i++) {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
5285
5286
5287
  		int temp = atomic_read(&stats->bc[i]);
  
  		if (temp)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5288
5289
  			seq_printf(m, "%s%s: %d
  ", prefix,
0953c7976   Badhri Jagan Sridharan   binder: change bi...
5290
  				   binder_command_strings[i], temp);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5291
5292
5293
  	}
  
  	BUILD_BUG_ON(ARRAY_SIZE(stats->br) !=
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5294
  		     ARRAY_SIZE(binder_return_strings));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5295
  	for (i = 0; i < ARRAY_SIZE(stats->br); i++) {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
5296
5297
5298
  		int temp = atomic_read(&stats->br[i]);
  
  		if (temp)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5299
5300
  			seq_printf(m, "%s%s: %d
  ", prefix,
0953c7976   Badhri Jagan Sridharan   binder: change bi...
5301
  				   binder_return_strings[i], temp);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5302
5303
5304
  	}
  
  	BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5305
  		     ARRAY_SIZE(binder_objstat_strings));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5306
  	BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) !=
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5307
  		     ARRAY_SIZE(stats->obj_deleted));
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5308
  	for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) {
0953c7976   Badhri Jagan Sridharan   binder: change bi...
5309
5310
5311
5312
5313
5314
5315
  		int created = atomic_read(&stats->obj_created[i]);
  		int deleted = atomic_read(&stats->obj_deleted[i]);
  
  		if (created || deleted)
  			seq_printf(m, "%s%s: active %d total %d
  ",
  				prefix,
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5316
  				binder_objstat_strings[i],
0953c7976   Badhri Jagan Sridharan   binder: change bi...
5317
5318
  				created - deleted,
  				created);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5319
  	}
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5320
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5321
5322
  static void print_binder_proc_stats(struct seq_file *m,
  				    struct binder_proc *proc)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5323
5324
  {
  	struct binder_work *w;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
5325
  	struct binder_thread *thread;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5326
  	struct rb_node *n;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
5327
  	int count, strong, weak, ready_threads;
7bd7b0e63   Todd Kjos   binder: protect p...
5328
5329
  	size_t free_async_space =
  		binder_alloc_get_free_async_space(&proc->alloc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5330

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5331
5332
  	seq_printf(m, "proc %d
  ", proc->pid);
14db31814   Martijn Coenen   binder: Deal with...
5333
5334
  	seq_printf(m, "context %s
  ", proc->context->name);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5335
  	count = 0;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
5336
  	ready_threads = 0;
7bd7b0e63   Todd Kjos   binder: protect p...
5337
  	binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5338
5339
  	for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n))
  		count++;
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
5340
5341
5342
  
  	list_for_each_entry(thread, &proc->waiting_threads, waiting_thread_node)
  		ready_threads++;
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5343
5344
5345
5346
  	seq_printf(m, "  threads: %d
  ", count);
  	seq_printf(m, "  requested threads: %d+%d/%d
  "
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5347
5348
5349
5350
5351
  			"  ready threads %d
  "
  			"  free async space %zd
  ", proc->requested_threads,
  			proc->requested_threads_started, proc->max_threads,
1b77e9dcc   Martijn Coenen   ANDROID: binder: ...
5352
  			ready_threads,
7bd7b0e63   Todd Kjos   binder: protect p...
5353
  			free_async_space);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5354
5355
5356
  	count = 0;
  	for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n))
  		count++;
da0fa9e4e   Todd Kjos   binder: protect p...
5357
  	binder_inner_proc_unlock(proc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5358
5359
  	seq_printf(m, "  nodes: %d
  ", count);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5360
5361
5362
  	count = 0;
  	strong = 0;
  	weak = 0;
2c1838dc6   Todd Kjos   binder: protect b...
5363
  	binder_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5364
5365
5366
5367
  	for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) {
  		struct binder_ref *ref = rb_entry(n, struct binder_ref,
  						  rb_node_desc);
  		count++;
372e3147d   Todd Kjos   binder: refactor ...
5368
5369
  		strong += ref->data.strong;
  		weak += ref->data.weak;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5370
  	}
2c1838dc6   Todd Kjos   binder: protect b...
5371
  	binder_proc_unlock(proc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5372
5373
  	seq_printf(m, "  refs: %d s %d w %d
  ", count, strong, weak);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5374

19c987241   Todd Kjos   binder: separate ...
5375
  	count = binder_alloc_get_allocated_count(&proc->alloc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5376
5377
  	seq_printf(m, "  buffers: %d
  ", count);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5378

8ef4665aa   Sherry Yang   android: binder: ...
5379
  	binder_alloc_print_pages(m, &proc->alloc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5380
  	count = 0;
72196393a   Todd Kjos   binder: add spinl...
5381
  	binder_inner_proc_lock(proc);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5382
  	list_for_each_entry(w, &proc->todo, entry) {
72196393a   Todd Kjos   binder: add spinl...
5383
  		if (w->type == BINDER_WORK_TRANSACTION)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5384
  			count++;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5385
  	}
72196393a   Todd Kjos   binder: add spinl...
5386
  	binder_inner_proc_unlock(proc);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5387
5388
  	seq_printf(m, "  pending transactions: %d
  ", count);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5389

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5390
  	print_binder_stats(m, "  ", &proc->stats);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5391
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5392
  static int binder_state_show(struct seq_file *m, void *unused)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5393
5394
  {
  	struct binder_proc *proc;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5395
  	struct binder_node *node;
673068eee   Todd Kjos   binder: add spinl...
5396
  	struct binder_node *last_node = NULL;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5397

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5398
5399
  	seq_puts(m, "binder state:
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5400

c44b1231f   Todd Kjos   binder: add prote...
5401
  	spin_lock(&binder_dead_nodes_lock);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5402
  	if (!hlist_empty(&binder_dead_nodes))
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5403
5404
  		seq_puts(m, "dead nodes:
  ");
673068eee   Todd Kjos   binder: add spinl...
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
  	hlist_for_each_entry(node, &binder_dead_nodes, dead_node) {
  		/*
  		 * take a temporary reference on the node so it
  		 * survives and isn't removed from the list
  		 * while we print it.
  		 */
  		node->tmp_refs++;
  		spin_unlock(&binder_dead_nodes_lock);
  		if (last_node)
  			binder_put_node(last_node);
  		binder_node_lock(node);
da0fa9e4e   Todd Kjos   binder: protect p...
5416
  		print_binder_node_nilocked(m, node);
673068eee   Todd Kjos   binder: add spinl...
5417
5418
5419
5420
  		binder_node_unlock(node);
  		last_node = node;
  		spin_lock(&binder_dead_nodes_lock);
  	}
c44b1231f   Todd Kjos   binder: add prote...
5421
  	spin_unlock(&binder_dead_nodes_lock);
673068eee   Todd Kjos   binder: add spinl...
5422
5423
  	if (last_node)
  		binder_put_node(last_node);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5424

c44b1231f   Todd Kjos   binder: add prote...
5425
  	mutex_lock(&binder_procs_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
5426
  	hlist_for_each_entry(proc, &binder_procs, proc_node)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5427
  		print_binder_proc(m, proc, 1);
c44b1231f   Todd Kjos   binder: add prote...
5428
  	mutex_unlock(&binder_procs_lock);
a60b890f6   Todd Kjos   binder: remove gl...
5429

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5430
  	return 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5431
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5432
  static int binder_stats_show(struct seq_file *m, void *unused)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5433
5434
  {
  	struct binder_proc *proc;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5435

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5436
5437
  	seq_puts(m, "binder stats:
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5438

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5439
  	print_binder_stats(m, "", &binder_stats);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5440

c44b1231f   Todd Kjos   binder: add prote...
5441
  	mutex_lock(&binder_procs_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
5442
  	hlist_for_each_entry(proc, &binder_procs, proc_node)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5443
  		print_binder_proc_stats(m, proc);
c44b1231f   Todd Kjos   binder: add prote...
5444
  	mutex_unlock(&binder_procs_lock);
a60b890f6   Todd Kjos   binder: remove gl...
5445

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5446
  	return 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5447
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5448
  static int binder_transactions_show(struct seq_file *m, void *unused)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5449
5450
  {
  	struct binder_proc *proc;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5451

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5452
5453
  	seq_puts(m, "binder transactions:
  ");
c44b1231f   Todd Kjos   binder: add prote...
5454
  	mutex_lock(&binder_procs_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
5455
  	hlist_for_each_entry(proc, &binder_procs, proc_node)
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5456
  		print_binder_proc(m, proc, 0);
c44b1231f   Todd Kjos   binder: add prote...
5457
  	mutex_unlock(&binder_procs_lock);
a60b890f6   Todd Kjos   binder: remove gl...
5458

5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5459
  	return 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5460
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5461
  static int binder_proc_show(struct seq_file *m, void *unused)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5462
  {
83050a4e2   Riley Andrews   android: drivers:...
5463
  	struct binder_proc *itr;
14db31814   Martijn Coenen   binder: Deal with...
5464
  	int pid = (unsigned long)m->private;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5465

c44b1231f   Todd Kjos   binder: add prote...
5466
  	mutex_lock(&binder_procs_lock);
83050a4e2   Riley Andrews   android: drivers:...
5467
  	hlist_for_each_entry(itr, &binder_procs, proc_node) {
14db31814   Martijn Coenen   binder: Deal with...
5468
5469
5470
5471
  		if (itr->pid == pid) {
  			seq_puts(m, "binder proc state:
  ");
  			print_binder_proc(m, itr, 1);
83050a4e2   Riley Andrews   android: drivers:...
5472
5473
  		}
  	}
c44b1231f   Todd Kjos   binder: add prote...
5474
  	mutex_unlock(&binder_procs_lock);
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5475
  	return 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5476
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5477
  static void print_binder_transaction_log_entry(struct seq_file *m,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5478
5479
  					struct binder_transaction_log_entry *e)
  {
d99c7333a   Todd Kjos   binder: use atomi...
5480
5481
5482
5483
5484
5485
  	int debug_id = READ_ONCE(e->debug_id_done);
  	/*
  	 * read barrier to guarantee debug_id_done read before
  	 * we print the log values
  	 */
  	smp_rmb();
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5486
  	seq_printf(m,
d99c7333a   Todd Kjos   binder: use atomi...
5487
  		   "%d: %s from %d:%d to %d:%d context %s node %d handle %d size %d:%d ret %d/%d l=%d",
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5488
5489
  		   e->debug_id, (e->call_type == 2) ? "reply" :
  		   ((e->call_type == 1) ? "async" : "call "), e->from_proc,
14db31814   Martijn Coenen   binder: Deal with...
5490
  		   e->from_thread, e->to_proc, e->to_thread, e->context_name,
57ada2fb2   Todd Kjos   binder: add log i...
5491
5492
5493
  		   e->to_node, e->target_handle, e->data_size, e->offsets_size,
  		   e->return_error, e->return_error_param,
  		   e->return_error_line);
d99c7333a   Todd Kjos   binder: use atomi...
5494
5495
5496
5497
5498
5499
5500
5501
5502
  	/*
  	 * read-barrier to guarantee read of debug_id_done after
  	 * done printing the fields of the entry
  	 */
  	smp_rmb();
  	seq_printf(m, debug_id && debug_id == READ_ONCE(e->debug_id_done) ?
  			"
  " : " (incomplete)
  ");
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5503
  }
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5504
  static int binder_transaction_log_show(struct seq_file *m, void *unused)
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5505
  {
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5506
  	struct binder_transaction_log *log = m->private;
d99c7333a   Todd Kjos   binder: use atomi...
5507
5508
5509
  	unsigned int log_cur = atomic_read(&log->cur);
  	unsigned int count;
  	unsigned int cur;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5510
  	int i;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5511

d99c7333a   Todd Kjos   binder: use atomi...
5512
5513
5514
5515
5516
5517
5518
5519
5520
  	count = log_cur + 1;
  	cur = count < ARRAY_SIZE(log->entry) && !log->full ?
  		0 : count % ARRAY_SIZE(log->entry);
  	if (count > ARRAY_SIZE(log->entry) || log->full)
  		count = ARRAY_SIZE(log->entry);
  	for (i = 0; i < count; i++) {
  		unsigned int index = cur++ % ARRAY_SIZE(log->entry);
  
  		print_binder_transaction_log_entry(m, &log->entry[index]);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5521
  	}
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5522
  	return 0;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5523
5524
5525
5526
5527
5528
  }
  
  static const struct file_operations binder_fops = {
  	.owner = THIS_MODULE,
  	.poll = binder_poll,
  	.unlocked_ioctl = binder_ioctl,
da49889de   Arve Hjønnevåg   staging: binder: ...
5529
  	.compat_ioctl = binder_ioctl,
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5530
5531
5532
5533
5534
  	.mmap = binder_mmap,
  	.open = binder_open,
  	.flush = binder_flush,
  	.release = binder_release,
  };
5249f4883   Arve Hjønnevåg   binder: Use seq_f...
5535
5536
5537
5538
  BINDER_DEBUG_ENTRY(state);
  BINDER_DEBUG_ENTRY(stats);
  BINDER_DEBUG_ENTRY(transactions);
  BINDER_DEBUG_ENTRY(transaction_log);
ac4812c5f   Martijn Coenen   binder: Support m...
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
  static int __init init_binder_device(const char *name)
  {
  	int ret;
  	struct binder_device *binder_device;
  
  	binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL);
  	if (!binder_device)
  		return -ENOMEM;
  
  	binder_device->miscdev.fops = &binder_fops;
  	binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
  	binder_device->miscdev.name = name;
  
  	binder_device->context.binder_context_mgr_uid = INVALID_UID;
  	binder_device->context.name = name;
c44b1231f   Todd Kjos   binder: add prote...
5554
  	mutex_init(&binder_device->context.context_mgr_node_lock);
ac4812c5f   Martijn Coenen   binder: Support m...
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
  
  	ret = misc_register(&binder_device->miscdev);
  	if (ret < 0) {
  		kfree(binder_device);
  		return ret;
  	}
  
  	hlist_add_head(&binder_device->hlist, &binder_devices);
  
  	return ret;
  }
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5566
5567
5568
  static int __init binder_init(void)
  {
  	int ret;
22eb9476b   Christian Brauner   binder: free memo...
5569
  	char *device_name, *device_names, *device_tmp;
ac4812c5f   Martijn Coenen   binder: Support m...
5570
5571
  	struct binder_device *device;
  	struct hlist_node *tmp;
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5572

f2517eb76   Sherry Yang   android: binder: ...
5573
  	binder_alloc_shrinker_init();
d99c7333a   Todd Kjos   binder: use atomi...
5574
5575
  	atomic_set(&binder_transaction_log.cur, ~0U);
  	atomic_set(&binder_transaction_log_failed.cur, ~0U);
16b665543   Arve Hjønnevåg   staging: android:...
5576
5577
5578
5579
  	binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
  	if (binder_debugfs_dir_entry_root)
  		binder_debugfs_dir_entry_proc = debugfs_create_dir("proc",
  						 binder_debugfs_dir_entry_root);
ac4812c5f   Martijn Coenen   binder: Support m...
5580

16b665543   Arve Hjønnevåg   staging: android:...
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
  	if (binder_debugfs_dir_entry_root) {
  		debugfs_create_file("state",
  				    S_IRUGO,
  				    binder_debugfs_dir_entry_root,
  				    NULL,
  				    &binder_state_fops);
  		debugfs_create_file("stats",
  				    S_IRUGO,
  				    binder_debugfs_dir_entry_root,
  				    NULL,
  				    &binder_stats_fops);
  		debugfs_create_file("transactions",
  				    S_IRUGO,
  				    binder_debugfs_dir_entry_root,
  				    NULL,
  				    &binder_transactions_fops);
  		debugfs_create_file("transaction_log",
  				    S_IRUGO,
  				    binder_debugfs_dir_entry_root,
  				    &binder_transaction_log,
  				    &binder_transaction_log_fops);
  		debugfs_create_file("failed_transaction_log",
  				    S_IRUGO,
  				    binder_debugfs_dir_entry_root,
  				    &binder_transaction_log_failed,
  				    &binder_transaction_log_fops);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5607
  	}
ac4812c5f   Martijn Coenen   binder: Support m...
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
  
  	/*
  	 * Copy the module_parameter string, because we don't want to
  	 * tokenize it in-place.
  	 */
  	device_names = kzalloc(strlen(binder_devices_param) + 1, GFP_KERNEL);
  	if (!device_names) {
  		ret = -ENOMEM;
  		goto err_alloc_device_names_failed;
  	}
  	strcpy(device_names, binder_devices_param);
22eb9476b   Christian Brauner   binder: free memo...
5619
5620
  	device_tmp = device_names;
  	while ((device_name = strsep(&device_tmp, ","))) {
ac4812c5f   Martijn Coenen   binder: Support m...
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
  		ret = init_binder_device(device_name);
  		if (ret)
  			goto err_init_binder_device_failed;
  	}
  
  	return ret;
  
  err_init_binder_device_failed:
  	hlist_for_each_entry_safe(device, tmp, &binder_devices, hlist) {
  		misc_deregister(&device->miscdev);
  		hlist_del(&device->hlist);
  		kfree(device);
  	}
22eb9476b   Christian Brauner   binder: free memo...
5634
5635
  
  	kfree(device_names);
ac4812c5f   Martijn Coenen   binder: Support m...
5636
5637
  err_alloc_device_names_failed:
  	debugfs_remove_recursive(binder_debugfs_dir_entry_root);
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5638
5639
5640
5641
  	return ret;
  }
  
  device_initcall(binder_init);
975a1ac9a   Arve Hjønnevåg   Staging: android:...
5642
5643
  #define CREATE_TRACE_POINTS
  #include "binder_trace.h"
355b0502f   Greg Kroah-Hartman   Revert "Staging: ...
5644
  MODULE_LICENSE("GPL v2");