Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7d95e1b authored by Arve Hjønnevåg's avatar Arve Hjønnevåg Committed by David Ng
Browse files

Staging: android: binder: Support concurrent 32 bit and 64 bit processes.



Add binder_size_t and binder_uintptr_t that is used instead of size_t and
void __user * in the user-space interface.

Use 64 bit pointers on all systems unless CONFIG_ANDROID_BINDER_IPC_32BIT
is set (which enables the old protocol on 32 bit systems).

Change BINDER_CURRENT_PROTOCOL_VERSION to 8 if
CONFIG_ANDROID_BINDER_IPC_32BIT is not set.

Add compat ioctl.

Change-Id: Ifbbde0209da0050011bcab34c547a4c30d6e8c49
Signed-off-by: default avatarArve Hjønnevåg <arve@android.com>
Git-commit: 1c4aa9fb12e8b0a54f056b8402b0bde61b49498f
Git-repo: https://android.googlesource.com/kernel/common/


Signed-off-by: default avatarNeeti Desai <neetid@codeaurora.org>
Signed-off-by: default avatarDavid Ng <dave@codeaurora.org>
Signed-off-by: default avatarAjay Dudani <adudani@codeaurora.org>
parent ae6e0eba
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -19,6 +19,13 @@ config ANDROID_BINDER_IPC
	  Android process, using Binder to identify, invoke and pass arguments
	  between said processes.

config ANDROID_BINDER_IPC_32BIT
	bool "Use old 32-bit binder api"
	depends on !64BIT
	---help---
	  Enable to support an old 32-bit Android user-space. Breaks the new
	  Android user-space.

config ASHMEM
	bool "Enable the Anonymous Shared Memory Subsystem"
	default n
+136 −117
Original line number Diff line number Diff line
@@ -229,8 +229,8 @@ struct binder_node {
	int internal_strong_refs;
	int local_weak_refs;
	int local_strong_refs;
	void __user *ptr;
	void __user *cookie;
	binder_uintptr_t ptr;
	binder_uintptr_t cookie;
	unsigned has_strong_ref:1;
	unsigned pending_strong_ref:1;
	unsigned has_weak_ref:1;
@@ -243,7 +243,7 @@ struct binder_node {

struct binder_ref_death {
	struct binder_work work;
	void __user *cookie;
	binder_uintptr_t cookie;
};

struct binder_ref {
@@ -516,14 +516,14 @@ static void binder_insert_allocated_buffer(struct binder_proc *proc,
}

static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc,
						  void __user *user_ptr)
						  uintptr_t user_ptr)
{
	struct rb_node *n = proc->allocated_buffers.rb_node;
	struct binder_buffer *buffer;
	struct binder_buffer *kern_ptr;

	kern_ptr = user_ptr - proc->user_buffer_offset
		- offsetof(struct binder_buffer, data);
	kern_ptr = (struct binder_buffer *)(user_ptr - proc->user_buffer_offset
		- offsetof(struct binder_buffer, data));

	while (n) {
		buffer = rb_entry(n, struct binder_buffer, rb_node);
@@ -857,7 +857,7 @@ static void binder_free_buf(struct binder_proc *proc,
}

static struct binder_node *binder_get_node(struct binder_proc *proc,
					   void __user *ptr)
					   binder_uintptr_t ptr)
{
	struct rb_node *n = proc->nodes.rb_node;
	struct binder_node *node;
@@ -876,8 +876,8 @@ static struct binder_node *binder_get_node(struct binder_proc *proc,
}

static struct binder_node *binder_new_node(struct binder_proc *proc,
					   void __user *ptr,
					   void __user *cookie)
					   binder_uintptr_t ptr,
					   binder_uintptr_t cookie)
{
	struct rb_node **p = &proc->nodes.rb_node;
	struct rb_node *parent = NULL;
@@ -909,9 +909,9 @@ static struct binder_node *binder_new_node(struct binder_proc *proc,
	INIT_LIST_HEAD(&node->work.entry);
	INIT_LIST_HEAD(&node->async_todo);
	binder_debug(BINDER_DEBUG_INTERNAL_REFS,
		     "%d:%d node %d u%p c%p created\n",
		     "%d:%d node %d u%016llx c%016llx created\n",
		     proc->pid, current->pid, node->debug_id,
		     node->ptr, node->cookie);
		     (u64)node->ptr, (u64)node->cookie);
	return node;
}

@@ -1230,9 +1230,9 @@ static void binder_send_failed_reply(struct binder_transaction *t,

static void binder_transaction_buffer_release(struct binder_proc *proc,
					      struct binder_buffer *buffer,
					      size_t *failed_at)
					      binder_size_t *failed_at)
{
	size_t *offp, *off_end;
	binder_size_t *offp, *off_end;
	int debug_id = buffer->debug_id;

	binder_debug(BINDER_DEBUG_TRANSACTION,
@@ -1243,7 +1243,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
	if (buffer->target_node)
		binder_dec_node(buffer->target_node, 1, 0);

	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
	offp = (binder_size_t *)(buffer->data +
				 ALIGN(buffer->data_size, sizeof(void *)));
	if (failed_at)
		off_end = failed_at;
	else
@@ -1253,8 +1254,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
		if (*offp > buffer->data_size - sizeof(*fp) ||
		    buffer->data_size < sizeof(*fp) ||
		    !IS_ALIGNED(*offp, sizeof(u32))) {
			pr_err("transaction release %d bad offset %zd, size %zd\n",
			 debug_id, *offp, buffer->data_size);
			pr_err("transaction release %d bad offset %lld, size %zd\n",
			       debug_id, (u64)*offp, buffer->data_size);
			continue;
		}
		fp = (struct flat_binder_object *)(buffer->data + *offp);
@@ -1263,13 +1264,13 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
		case BINDER_TYPE_WEAK_BINDER: {
			struct binder_node *node = binder_get_node(proc, fp->binder);
			if (node == NULL) {
				pr_err("transaction release %d bad node %p\n",
					debug_id, fp->binder);
				pr_err("transaction release %d bad node %016llx\n",
				       debug_id, (u64)fp->binder);
				break;
			}
			binder_debug(BINDER_DEBUG_TRANSACTION,
				     "        node %d u%p\n",
				     node->debug_id, node->ptr);
				     "        node %d u%016llx\n",
				     node->debug_id, (u64)node->ptr);
			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
		} break;
		case BINDER_TYPE_HANDLE:
@@ -1307,7 +1308,7 @@ static void binder_transaction(struct binder_proc *proc,
{
	struct binder_transaction *t;
	struct binder_work *tcomplete;
	size_t *offp, *off_end;
	binder_size_t *offp, *off_end;
	struct binder_proc *target_proc;
	struct binder_thread *target_thread = NULL;
	struct binder_node *target_node = NULL;
@@ -1440,18 +1441,20 @@ static void binder_transaction(struct binder_proc *proc,

	if (reply)
		binder_debug(BINDER_DEBUG_TRANSACTION,
			     "%d:%d BC_REPLY %d -> %d:%d, data %p-%p size %zd-%zd\n",
			     "%d:%d BC_REPLY %d -> %d:%d, data %016llx-%016llx size %lld-%lld\n",
			     proc->pid, thread->pid, t->debug_id,
			     target_proc->pid, target_thread->pid,
			     tr->data.ptr.buffer, tr->data.ptr.offsets,
			     tr->data_size, tr->offsets_size);
			     (u64)tr->data.ptr.buffer,
			     (u64)tr->data.ptr.offsets,
			     (u64)tr->data_size, (u64)tr->offsets_size);
	else
		binder_debug(BINDER_DEBUG_TRANSACTION,
			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %p-%p size %zd-%zd\n",
			     "%d:%d BC_TRANSACTION %d -> %d - node %d, data %016llx-%016llx size %lld-%lld\n",
			     proc->pid, thread->pid, t->debug_id,
			     target_proc->pid, target_node->debug_id,
			     tr->data.ptr.buffer, tr->data.ptr.offsets,
			     tr->data_size, tr->offsets_size);
			     (u64)tr->data.ptr.buffer,
			     (u64)tr->data.ptr.offsets,
			     (u64)tr->data_size, (u64)tr->offsets_size);

	if (!reply && !(tr->flags & TF_ONE_WAY))
		t->from = thread;
@@ -1480,23 +1483,26 @@ static void binder_transaction(struct binder_proc *proc,
	if (target_node)
		binder_inc_node(target_node, 1, 0, NULL);

	offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
	offp = (binder_size_t *)(t->buffer->data +
				 ALIGN(tr->data_size, sizeof(void *)));

	if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
	if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
			   tr->data.ptr.buffer, tr->data_size)) {
		binder_user_error("%d:%d got transaction with invalid data ptr\n",
				proc->pid, thread->pid);
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}
	if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
	if (copy_from_user(offp, (const void __user *)(uintptr_t)
			   tr->data.ptr.offsets, tr->offsets_size)) {
		binder_user_error("%d:%d got transaction with invalid offsets ptr\n",
				proc->pid, thread->pid);
		return_error = BR_FAILED_REPLY;
		goto err_copy_data_failed;
	}
	if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
		binder_user_error("%d:%d got transaction with invalid offsets size, %zd\n",
				proc->pid, thread->pid, tr->offsets_size);
	if (!IS_ALIGNED(tr->offsets_size, sizeof(binder_size_t))) {
		binder_user_error("%d:%d got transaction with invalid offsets size, %lld\n",
				proc->pid, thread->pid, (u64)tr->offsets_size);
		return_error = BR_FAILED_REPLY;
		goto err_bad_offset;
	}
@@ -1506,8 +1512,8 @@ static void binder_transaction(struct binder_proc *proc,
		if (*offp > t->buffer->data_size - sizeof(*fp) ||
		    t->buffer->data_size < sizeof(*fp) ||
		    !IS_ALIGNED(*offp, sizeof(u32))) {
			binder_user_error("%d:%d got transaction with invalid offset, %zd\n",
					proc->pid, thread->pid, *offp);
			binder_user_error("%d:%d got transaction with invalid offset, %lld\n",
					  proc->pid, thread->pid, (u64)*offp);
			return_error = BR_FAILED_REPLY;
			goto err_bad_offset;
		}
@@ -1527,10 +1533,10 @@ static void binder_transaction(struct binder_proc *proc,
				node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
			}
			if (fp->cookie != node->cookie) {
				binder_user_error("%d:%d sending u%p node %d, cookie mismatch %p != %p\n",
				binder_user_error("%d:%d sending u%016llx node %d, cookie mismatch %016llx != %016llx\n",
					proc->pid, thread->pid,
					fp->binder, node->debug_id,
					fp->cookie, node->cookie);
					(u64)fp->binder, node->debug_id,
					(u64)fp->cookie, (u64)node->cookie);
				goto err_binder_get_ref_for_node_failed;
			}
			if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
@@ -1552,9 +1558,9 @@ static void binder_transaction(struct binder_proc *proc,

			trace_binder_transaction_node_to_ref(t, node, ref);
			binder_debug(BINDER_DEBUG_TRANSACTION,
				     "        node %d u%p -> ref %d desc %d\n",
				     node->debug_id, node->ptr, ref->debug_id,
				     ref->desc);
				     "        node %d u%016llx -> ref %d desc %d\n",
				     node->debug_id, (u64)node->ptr,
				     ref->debug_id, ref->desc);
		} break;
		case BINDER_TYPE_HANDLE:
		case BINDER_TYPE_WEAK_HANDLE: {
@@ -1580,9 +1586,9 @@ static void binder_transaction(struct binder_proc *proc,
				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
				trace_binder_transaction_ref_to_node(t, ref);
				binder_debug(BINDER_DEBUG_TRANSACTION,
					     "        ref %d desc %d -> node %d u%p\n",
					     "        ref %d desc %d -> node %d u%016llx\n",
					     ref->debug_id, ref->desc, ref->node->debug_id,
					     ref->node->ptr);
					     (u64)ref->node->ptr);
			} else {
				struct binder_ref *new_ref;
				new_ref = binder_get_ref_for_node(target_proc, ref->node);
@@ -1703,9 +1709,9 @@ err_dead_binder:
err_invalid_target_handle:
err_no_context_mgr_node:
	binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
		     "%d:%d transaction failed %d, size %zd-%zd\n",
		     "%d:%d transaction failed %d, size %lld-%lld\n",
		     proc->pid, thread->pid, return_error,
		     tr->data_size, tr->offsets_size);
		     (u64)tr->data_size, (u64)tr->offsets_size);

	{
		struct binder_transaction_log_entry *fe;
@@ -1723,9 +1729,11 @@ err_no_context_mgr_node:

static int binder_thread_write(struct binder_proc *proc,
			struct binder_thread *thread,
			void __user *buffer, size_t size, size_t *consumed)
			binder_uintptr_t binder_buffer, size_t size,
			binder_size_t *consumed)
{
	uint32_t cmd;
	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
	void __user *ptr = buffer + *consumed;
	void __user *end = buffer + size;

@@ -1801,33 +1809,33 @@ static int binder_thread_write(struct binder_proc *proc,
		}
		case BC_INCREFS_DONE:
		case BC_ACQUIRE_DONE: {
			void __user *node_ptr;
			void __user *cookie;
			binder_uintptr_t node_ptr;
			binder_uintptr_t cookie;
			struct binder_node *node;

			if (get_user(node_ptr, (void * __user *)ptr))
			if (get_user(node_ptr, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(void *);
			if (get_user(cookie, (void * __user *)ptr))
			ptr += sizeof(binder_uintptr_t);
			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(void *);
			ptr += sizeof(binder_uintptr_t);
			node = binder_get_node(proc, node_ptr);
			if (node == NULL) {
				binder_user_error("%d:%d %s u%p no match\n",
				binder_user_error("%d:%d %s u%016llx no match\n",
					proc->pid, thread->pid,
					cmd == BC_INCREFS_DONE ?
					"BC_INCREFS_DONE" :
					"BC_ACQUIRE_DONE",
					node_ptr);
					(u64)node_ptr);
				break;
			}
			if (cookie != node->cookie) {
				binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != %p\n",
				binder_user_error("%d:%d %s u%016llx node %d cookie mismatch %016llx != %016llx\n",
					proc->pid, thread->pid,
					cmd == BC_INCREFS_DONE ?
					"BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
					node_ptr, node->debug_id,
					cookie, node->cookie);
					(u64)node_ptr, node->debug_id,
					(u64)cookie, (u64)node->cookie);
				break;
			}
			if (cmd == BC_ACQUIRE_DONE) {
@@ -1863,27 +1871,27 @@ static int binder_thread_write(struct binder_proc *proc,
			return -EINVAL;

		case BC_FREE_BUFFER: {
			void __user *data_ptr;
			binder_uintptr_t data_ptr;
			struct binder_buffer *buffer;

			if (get_user(data_ptr, (void * __user *)ptr))
			if (get_user(data_ptr, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(void *);
			ptr += sizeof(binder_uintptr_t);

			buffer = binder_buffer_lookup(proc, data_ptr);
			if (buffer == NULL) {
				binder_user_error("%d:%d BC_FREE_BUFFER u%p no match\n",
					proc->pid, thread->pid, data_ptr);
				binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n",
					proc->pid, thread->pid, (u64)data_ptr);
				break;
			}
			if (!buffer->allow_user_free) {
				binder_user_error("%d:%d BC_FREE_BUFFER u%p matched unreturned buffer\n",
					proc->pid, thread->pid, data_ptr);
				binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n",
					proc->pid, thread->pid, (u64)data_ptr);
				break;
			}
			binder_debug(BINDER_DEBUG_FREE_BUFFER,
				     "%d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
				     "%d:%d BC_FREE_BUFFER u%016llx found buffer %d for %s transaction\n",
				     proc->pid, thread->pid, (u64)data_ptr, buffer->debug_id,
				     buffer->transaction ? "active" : "finished");

			if (buffer->transaction) {
@@ -1953,16 +1961,16 @@ static int binder_thread_write(struct binder_proc *proc,
		case BC_REQUEST_DEATH_NOTIFICATION:
		case BC_CLEAR_DEATH_NOTIFICATION: {
			uint32_t target;
			void __user *cookie;
			binder_uintptr_t cookie;
			struct binder_ref *ref;
			struct binder_ref_death *death;

			if (get_user(target, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (get_user(cookie, (void __user * __user *)ptr))
			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(void *);
			ptr += sizeof(binder_uintptr_t);
			ref = binder_get_ref(proc, target);
			if (ref == NULL) {
				binder_user_error("%d:%d %s invalid ref %d\n",
@@ -1975,12 +1983,12 @@ static int binder_thread_write(struct binder_proc *proc,
			}

			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
				     "%d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
				     "%d:%d %s %016llx ref %d desc %d s %d w %d for node %d\n",
				     proc->pid, thread->pid,
				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
				     "BC_REQUEST_DEATH_NOTIFICATION" :
				     "BC_CLEAR_DEATH_NOTIFICATION",
				     cookie, ref->debug_id, ref->desc,
				     (u64)cookie, ref->debug_id, ref->desc,
				     ref->strong, ref->weak, ref->node->debug_id);

			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
@@ -2018,9 +2026,9 @@ static int binder_thread_write(struct binder_proc *proc,
				}
				death = ref->death;
				if (death->cookie != cookie) {
					binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %p != %p\n",
					binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %016llx != %016llx\n",
						proc->pid, thread->pid,
						death->cookie, cookie);
						(u64)death->cookie, (u64)cookie);
					break;
				}
				ref->death = NULL;
@@ -2040,9 +2048,9 @@ static int binder_thread_write(struct binder_proc *proc,
		} break;
		case BC_DEAD_BINDER_DONE: {
			struct binder_work *w;
			void __user *cookie;
			binder_uintptr_t cookie;
			struct binder_ref_death *death = NULL;
			if (get_user(cookie, (void __user * __user *)ptr))
			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
				return -EFAULT;

			ptr += sizeof(void *);
@@ -2054,11 +2062,11 @@ static int binder_thread_write(struct binder_proc *proc,
				}
			}
			binder_debug(BINDER_DEBUG_DEAD_BINDER,
				     "%d:%d BC_DEAD_BINDER_DONE %p found %p\n",
				     proc->pid, thread->pid, cookie, death);
				     "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n",
				     proc->pid, thread->pid, (u64)cookie, death);
			if (death == NULL) {
				binder_user_error("%d:%d BC_DEAD_BINDER_DONE %p not found\n",
					proc->pid, thread->pid, cookie);
				binder_user_error("%d:%d BC_DEAD_BINDER_DONE %016llx not found\n",
					proc->pid, thread->pid, (u64)cookie);
				break;
			}

@@ -2110,9 +2118,10 @@ static int binder_has_thread_work(struct binder_thread *thread)

static int binder_thread_read(struct binder_proc *proc,
			      struct binder_thread *thread,
			      void  __user *buffer, size_t size,
			      size_t *consumed, int non_block)
			      binder_uintptr_t binder_buffer, size_t size,
			      binder_size_t *consumed, int non_block)
{
	void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
	void __user *ptr = buffer + *consumed;
	void __user *end = buffer + size;

@@ -2257,32 +2266,36 @@ retry:
				if (put_user(cmd, (uint32_t __user *)ptr))
					return -EFAULT;
				ptr += sizeof(uint32_t);
				if (put_user(node->ptr, (void * __user *)ptr))
				if (put_user(node->ptr,
					     (binder_uintptr_t __user *)ptr))
					return -EFAULT;
				ptr += sizeof(void *);
				if (put_user(node->cookie, (void * __user *)ptr))
				ptr += sizeof(binder_uintptr_t);
				if (put_user(node->cookie,
					     (binder_uintptr_t __user *)ptr))
					return -EFAULT;
				ptr += sizeof(void *);
				ptr += sizeof(binder_uintptr_t);

				binder_stat_br(proc, thread, cmd);
				binder_debug(BINDER_DEBUG_USER_REFS,
					     "%d:%d %s %d u%p c%p\n",
					     proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie);
					     "%d:%d %s %d u%016llx c%016llx\n",
					     proc->pid, thread->pid, cmd_name,
					     node->debug_id,
					     (u64)node->ptr, (u64)node->cookie);
			} else {
				list_del_init(&w->entry);
				if (!weak && !strong) {
					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
						     "%d:%d node %d u%p c%p deleted\n",
						     "%d:%d node %d u%016llx c%016llx deleted\n",
						     proc->pid, thread->pid, node->debug_id,
						     node->ptr, node->cookie);
						     (u64)node->ptr, (u64)node->cookie);
					rb_erase(&node->rb_node, &proc->nodes);
					kfree(node);
					binder_stats_deleted(BINDER_STAT_NODE);
				} else {
					binder_debug(BINDER_DEBUG_INTERNAL_REFS,
						     "%d:%d node %d u%p c%p state unchanged\n",
						     proc->pid, thread->pid, node->debug_id, node->ptr,
						     node->cookie);
						     "%d:%d node %d u%016llx c%016llx state unchanged\n",
						     proc->pid, thread->pid, node->debug_id,
						     (u64)node->ptr, (u64)node->cookie);
				}
			}
		} break;
@@ -2300,17 +2313,18 @@ retry:
			if (put_user(cmd, (uint32_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(uint32_t);
			if (put_user(death->cookie, (void * __user *)ptr))
			if (put_user(death->cookie,
				     (binder_uintptr_t __user *)ptr))
				return -EFAULT;
			ptr += sizeof(void *);
			ptr += sizeof(binder_uintptr_t);
			binder_stat_br(proc, thread, cmd);
			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
				     "%d:%d %s %p\n",
				     "%d:%d %s %016llx\n",
				      proc->pid, thread->pid,
				      cmd == BR_DEAD_BINDER ?
				      "BR_DEAD_BINDER" :
				      "BR_CLEAR_DEATH_NOTIFICATION_DONE",
				      death->cookie);
				      (u64)death->cookie);

			if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {
				list_del(&w->entry);
@@ -2340,8 +2354,8 @@ retry:
				binder_set_nice(target_node->min_priority);
			cmd = BR_TRANSACTION;
		} else {
			tr.target.ptr = NULL;
			tr.cookie = NULL;
			tr.target.ptr = 0;
			tr.cookie = 0;
			cmd = BR_REPLY;
		}
		tr.code = t->code;
@@ -2358,8 +2372,9 @@ retry:

		tr.data_size = t->buffer->data_size;
		tr.offsets_size = t->buffer->offsets_size;
		tr.data.ptr.buffer = (void *)t->buffer->data +
					proc->user_buffer_offset;
		tr.data.ptr.buffer = (binder_uintptr_t)(
					(uintptr_t)t->buffer->data +
					proc->user_buffer_offset);
		tr.data.ptr.offsets = tr.data.ptr.buffer +
					ALIGN(t->buffer->data_size,
					    sizeof(void *));
@@ -2374,14 +2389,14 @@ retry:
		trace_binder_transaction_received(t);
		binder_stat_br(proc, thread, cmd);
		binder_debug(BINDER_DEBUG_TRANSACTION,
			     "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %p-%p\n",
			     "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %016llx-%016llx\n",
			     proc->pid, thread->pid,
			     (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" :
			     "BR_REPLY",
			     t->debug_id, t->from ? t->from->proc->pid : 0,
			     t->from ? t->from->pid : 0, cmd,
			     t->buffer->data_size, t->buffer->offsets_size,
			     tr.data.ptr.buffer, tr.data.ptr.offsets);
			     (u64)tr.data.ptr.buffer, (u64)tr.data.ptr.offsets);

		list_del(&t->work.entry);
		t->buffer->allow_user_free = 1;
@@ -2451,8 +2466,8 @@ static void binder_release_work(struct list_head *list)

			death = container_of(w, struct binder_ref_death, work);
			binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
				"undelivered death notification, %p\n",
				death->cookie);
				"undelivered death notification, %016llx\n",
				(u64)death->cookie);
			kfree(death);
			binder_stats_deleted(BINDER_STAT_DEATH);
		} break;
@@ -2608,12 +2623,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			goto err;
		}
		binder_debug(BINDER_DEBUG_READ_WRITE,
			     "%d:%d write %zd at %016lx, read %zd at %016lx\n",
			     proc->pid, thread->pid, bwr.write_size,
			     bwr.write_buffer, bwr.read_size, bwr.read_buffer);
			     "%d:%d write %lld at %016llx, read %lld at %016llx\n",
			     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, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
			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;
@@ -2623,7 +2639,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			}
		}
		if (bwr.read_size > 0) {
			ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
			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);
			if (!list_empty(&proc->todo))
				wake_up_interruptible(&proc->wait);
@@ -2634,9 +2650,10 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			}
		}
		binder_debug(BINDER_DEBUG_READ_WRITE,
			     "%d:%d wrote %zd of %zd, read return %zd of %zd\n",
			     proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
			     bwr.read_consumed, bwr.read_size);
			     "%d:%d wrote %lld of %lld, read return %lld of %lld\n",
			     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 err;
@@ -2668,7 +2685,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
			}
		} else
			binder_context_mgr_uid = current->cred->euid;
		binder_context_mgr_node = binder_new_node(proc, NULL, NULL);
		binder_context_mgr_node = binder_new_node(proc, 0, 0);
		if (binder_context_mgr_node == NULL) {
			ret = -ENOMEM;
			goto err;
@@ -3163,8 +3180,9 @@ static void print_binder_work(struct seq_file *m, const char *prefix,
		break;
	case BINDER_WORK_NODE:
		node = container_of(w, struct binder_node, work);
		seq_printf(m, "%snode work %d: u%p c%p\n",
			   prefix, node->debug_id, node->ptr, node->cookie);
		seq_printf(m, "%snode work %d: u%016llx c%016llx\n",
			   prefix, node->debug_id,
			   (u64)node->ptr, (u64)node->cookie);
		break;
	case BINDER_WORK_DEAD_BINDER:
		seq_printf(m, "%shas dead binder\n", prefix);
@@ -3224,8 +3242,8 @@ static void print_binder_node(struct seq_file *m, struct binder_node *node)
	hlist_for_each_entry(ref, &node->refs, node_entry)
		count++;

	seq_printf(m, "  node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d",
		   node->debug_id, node->ptr, node->cookie,
	seq_printf(m, "  node %d: u%016llx c%016llx hs %d hw %d ls %d lw %d is %d iw %d",
		   node->debug_id, (u64)node->ptr, (u64)node->cookie,
		   node->has_strong_ref, node->has_weak_ref,
		   node->local_strong_refs, node->local_weak_refs,
		   node->internal_strong_refs, count);
@@ -3527,6 +3545,7 @@ static const struct file_operations binder_fops = {
	.owner = THIS_MODULE,
	.poll = binder_poll,
	.unlocked_ioctl = binder_ioctl,
	.compat_ioctl = binder_ioctl,
	.mmap = binder_mmap,
	.open = binder_open,
	.flush = binder_flush,
+4 −0
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@
#ifndef _LINUX_BINDER_H
#define _LINUX_BINDER_H

#ifdef CONFIG_ANDROID_BINDER_IPC_32BIT
#define BINDER_IPC_32BIT 1
#endif

#include "uapi/binder.h"

#endif /* _LINUX_BINDER_H */
+8 −6
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ TRACE_EVENT(binder_transaction_node_to_ref,
	TP_STRUCT__entry(
		__field(int, debug_id)
		__field(int, node_debug_id)
		__field(void __user *, node_ptr)
		__field(binder_uintptr_t, node_ptr)
		__field(int, ref_debug_id)
		__field(uint32_t, ref_desc)
	),
@@ -163,8 +163,9 @@ TRACE_EVENT(binder_transaction_node_to_ref,
		__entry->ref_debug_id = ref->debug_id;
		__entry->ref_desc = ref->desc;
	),
	TP_printk("transaction=%d node=%d src_ptr=0x%p ==> dest_ref=%d dest_desc=%d",
		  __entry->debug_id, __entry->node_debug_id, __entry->node_ptr,
	TP_printk("transaction=%d node=%d src_ptr=0x%016llx ==> dest_ref=%d dest_desc=%d",
		  __entry->debug_id, __entry->node_debug_id,
		  (u64)__entry->node_ptr,
		  __entry->ref_debug_id, __entry->ref_desc)
);

@@ -177,7 +178,7 @@ TRACE_EVENT(binder_transaction_ref_to_node,
		__field(int, ref_debug_id)
		__field(uint32_t, ref_desc)
		__field(int, node_debug_id)
		__field(void __user *, node_ptr)
		__field(binder_uintptr_t, node_ptr)
	),
	TP_fast_assign(
		__entry->debug_id = t->debug_id;
@@ -186,9 +187,10 @@ TRACE_EVENT(binder_transaction_ref_to_node,
		__entry->node_debug_id = ref->node->debug_id;
		__entry->node_ptr = ref->node->ptr;
	),
	TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%p",
	TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%016llx",
		  __entry->debug_id, __entry->node_debug_id,
		  __entry->ref_debug_id, __entry->ref_desc, __entry->node_ptr)
		  __entry->ref_debug_id, __entry->ref_desc,
		  (u64)__entry->node_ptr)
);

TRACE_EVENT(binder_transaction_ref_to_ref,