[PATCH v1 4/9] staging: android: binder: Add align_helper() macro

2013-12-04 Thread Serban Constantinescu
This patch adds align_helper() macro that will be used for enforcing
the desired alignment on 64bit systems where the alignment will differ
depending on the userspace used (32bit /64bit).

This patch is a temporary patch that will be extended with 32bit compat
handling.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 16109cd..6719a53 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -140,6 +140,8 @@ module_param_call(stop_on_user_error, 
binder_set_stop_on_user_error,
binder_stop_on_user_error = 2; \
} while (0)
 
+#define align_helper(ptr)  ALIGN(ptr, sizeof(void *))
+
 enum binder_stat_types {
BINDER_STAT_PROC,
BINDER_STAT_THREAD,
@@ -1239,7 +1241,7 @@ 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 = (size_t *)(buffer->data + align_helper(buffer->data_size));
if (failed_at)
off_end = failed_at;
else
@@ -1472,7 +1474,7 @@ 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 = (size_t *)(t->buffer->data + align_helper(tr->data_size));
 
if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, 
tr->data_size)) {
binder_user_error("%d:%d got transaction with invalid data 
ptr\n",
@@ -2378,8 +2380,7 @@ retry:
tr.data.ptr.buffer = (void *)t->buffer->data +
proc->user_buffer_offset;
tr.data.ptr.offsets = tr.data.ptr.buffer +
-   ALIGN(t->buffer->data_size,
-   sizeof(void *));
+   align_helper(t->buffer->data_size);
 
if (binder_copy_to_user(cmd, &tr, &ptr, sizeof(struct 
binder_transaction_data)))
return -EFAULT;
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 6/9] staging: android: binder: Add size_helper() macro

2013-12-04 Thread Serban Constantinescu
This patch adds size_helper() macro that will be used for indexing into
different buffers on 64bit systems where the size of particular
structures will differ depending on the userspace used (32bit /64bit).

This patch is a temporary patch that will be extended with 32bit compat
handling.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |   17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 95c2581..6d22717 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -142,6 +142,7 @@ module_param_call(stop_on_user_error, 
binder_set_stop_on_user_error,
 
 #define align_helper(ptr)  ALIGN(ptr, sizeof(void *))
 #define deref_helper(ptr)  (*(typeof(size_t *))ptr)
+#define size_helper(x) sizeof(x)
 
 enum binder_stat_types {
BINDER_STAT_PROC,
@@ -1247,10 +1248,10 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
off_end = failed_at;
else
off_end = (void *)offp + buffer->offsets_size;
-   for (; offp < off_end; offp += sizeof(size_t)) {
+   for (; offp < off_end; offp += size_helper(size_t)) {
struct flat_binder_object *fp;
-   if (deref_helper(offp) > buffer->data_size - sizeof(*fp) ||
-   buffer->data_size < sizeof(*fp) ||
+   if (deref_helper(offp) > buffer->data_size - size_helper(*fp) ||
+   buffer->data_size < size_helper(*fp) ||
!IS_ALIGNED(deref_helper(offp), sizeof(u32))) {
pr_err("transaction release %d bad offset %zd, size 
%zd\n",
 debug_id, deref_helper(offp), buffer->data_size);
@@ -1489,17 +1490,17 @@ static void binder_transaction(struct binder_proc *proc,
return_error = BR_FAILED_REPLY;
goto err_copy_data_failed;
}
-   if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
+   if (!IS_ALIGNED(tr->offsets_size, size_helper(size_t))) {
binder_user_error("%d:%d got transaction with invalid offsets 
size, %zd\n",
proc->pid, thread->pid, tr->offsets_size);
return_error = BR_FAILED_REPLY;
goto err_bad_offset;
}
off_end = (void *)offp + tr->offsets_size;
-   for (; offp < off_end; offp += sizeof(size_t)) {
+   for (; offp < off_end; offp += size_helper(size_t)) {
struct flat_binder_object *fp;
-   if (deref_helper(offp) > t->buffer->data_size - sizeof(*fp) ||
-   t->buffer->data_size < sizeof(*fp) ||
+   if (deref_helper(offp) > t->buffer->data_size - 
size_helper(*fp) ||
+   t->buffer->data_size < size_helper(*fp) ||
!IS_ALIGNED(deref_helper(offp), sizeof(u32))) {
binder_user_error("%d:%d got transaction with invalid 
offset, %zd\n",
proc->pid, thread->pid, 
deref_helper(offp));
@@ -2229,7 +2230,7 @@ retry:
break;
}
 
-   if (end - ptr < sizeof(tr) + 4)
+   if (end - ptr < size_helper(tr) + 4)
break;
 
switch (w->type) {
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 2/9] staging: android: binder: Add binder_copy_to_user()

2013-12-04 Thread Serban Constantinescu
This patch adds binder_copy_to_user() to be used for copying binder
commands to user address space. This way we can abstract away the
copy_to_user() calls and add separate handling for the compat layer.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |   39 --
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 233889c..6fbb340 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2117,6 +2117,18 @@ static int binder_has_thread_work(struct binder_thread 
*thread)
(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
 }
 
+static int binder_copy_to_user(uint32_t cmd, void *parcel,
+  void __user **ptr, size_t size)
+{
+   if (put_user(cmd, (uint32_t __user *)*ptr))
+   return -EFAULT;
+   *ptr += sizeof(uint32_t);
+   if (copy_to_user(*ptr, parcel, size))
+   return -EFAULT;
+   *ptr += size;
+   return 0;
+}
+
 static int binder_thread_read(struct binder_proc *proc,
  struct binder_thread *thread,
  void  __user *buffer, size_t size,
@@ -2263,15 +2275,12 @@ retry:
node->has_weak_ref = 0;
}
if (cmd != BR_NOOP) {
-   if (put_user(cmd, (uint32_t __user *)ptr))
-   return -EFAULT;
-   ptr += sizeof(uint32_t);
-   if (put_user(node->ptr, (void * __user *)ptr))
-   return -EFAULT;
-   ptr += sizeof(void *);
-   if (put_user(node->cookie, (void * __user 
*)ptr))
+   struct binder_ptr_cookie tmp;
+
+   tmp.ptr = node->ptr;
+   tmp.cookie = node->cookie;
+   if (binder_copy_to_user(cmd, &tmp, &ptr, 
sizeof(struct binder_ptr_cookie)))
return -EFAULT;
-   ptr += sizeof(void *);
 
binder_stat_br(proc, thread, cmd);
binder_debug(BINDER_DEBUG_USER_REFS,
@@ -2306,12 +2315,10 @@ retry:
cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;
else
cmd = BR_DEAD_BINDER;
-   if (put_user(cmd, (uint32_t __user *)ptr))
-   return -EFAULT;
-   ptr += sizeof(uint32_t);
-   if (put_user(death->cookie, (void * __user *)ptr))
+
+   if (binder_copy_to_user(cmd, &death->cookie, &ptr, 
sizeof(void *)))
return -EFAULT;
-   ptr += sizeof(void *);
+
binder_stat_br(proc, thread, cmd);
binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
 "%d:%d %s %p\n",
@@ -2373,12 +2380,8 @@ retry:
ALIGN(t->buffer->data_size,
sizeof(void *));
 
-   if (put_user(cmd, (uint32_t __user *)ptr))
-   return -EFAULT;
-   ptr += sizeof(uint32_t);
-   if (copy_to_user(ptr, &tr, sizeof(tr)))
+   if (binder_copy_to_user(cmd, &tr, &ptr, sizeof(struct 
binder_transaction_data)))
return -EFAULT;
-   ptr += sizeof(tr);
 
trace_binder_transaction_received(t);
binder_stat_br(proc, thread, cmd);
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 5/9] staging: android: binder: Add deref_helper() macro

2013-12-04 Thread Serban Constantinescu
This patch adds a deref_helper() macro that will be used to dereference
the binder offsets on 64bit systems where the offset is either a 32bit
or a 64bit value, depending on the userpace used (32bit /64bit)

This patch is a temporary patch that will be extended with 32bit compat
handling.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |   25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 6719a53..95c2581 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -141,6 +141,7 @@ module_param_call(stop_on_user_error, 
binder_set_stop_on_user_error,
} while (0)
 
 #define align_helper(ptr)  ALIGN(ptr, sizeof(void *))
+#define deref_helper(ptr)  (*(typeof(size_t *))ptr)
 
 enum binder_stat_types {
BINDER_STAT_PROC,
@@ -1230,7 +1231,7 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
  struct binder_buffer *buffer,
  size_t *failed_at)
 {
-   size_t *offp, *off_end;
+   void *offp, *off_end;
int debug_id = buffer->debug_id;
 
binder_debug(BINDER_DEBUG_TRANSACTION,
@@ -1246,16 +1247,16 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
off_end = failed_at;
else
off_end = (void *)offp + buffer->offsets_size;
-   for (; offp < off_end; offp++) {
+   for (; offp < off_end; offp += sizeof(size_t)) {
struct flat_binder_object *fp;
-   if (*offp > buffer->data_size - sizeof(*fp) ||
+   if (deref_helper(offp) > buffer->data_size - sizeof(*fp) ||
buffer->data_size < sizeof(*fp) ||
-   !IS_ALIGNED(*offp, sizeof(u32))) {
+   !IS_ALIGNED(deref_helper(offp), sizeof(u32))) {
pr_err("transaction release %d bad offset %zd, size 
%zd\n",
-debug_id, *offp, buffer->data_size);
+debug_id, deref_helper(offp), buffer->data_size);
continue;
}
-   fp = (struct flat_binder_object *)(buffer->data + *offp);
+   fp = (struct flat_binder_object *)(buffer->data + 
deref_helper(offp));
switch (fp->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
@@ -1305,7 +1306,7 @@ static void binder_transaction(struct binder_proc *proc,
 {
struct binder_transaction *t;
struct binder_work *tcomplete;
-   size_t *offp, *off_end;
+   void *offp, *off_end;
struct binder_proc *target_proc;
struct binder_thread *target_thread = NULL;
struct binder_node *target_node = NULL;
@@ -1495,17 +1496,17 @@ static void binder_transaction(struct binder_proc *proc,
goto err_bad_offset;
}
off_end = (void *)offp + tr->offsets_size;
-   for (; offp < off_end; offp++) {
+   for (; offp < off_end; offp += sizeof(size_t)) {
struct flat_binder_object *fp;
-   if (*offp > t->buffer->data_size - sizeof(*fp) ||
+   if (deref_helper(offp) > t->buffer->data_size - sizeof(*fp) ||
t->buffer->data_size < sizeof(*fp) ||
-   !IS_ALIGNED(*offp, sizeof(u32))) {
+   !IS_ALIGNED(deref_helper(offp), sizeof(u32))) {
binder_user_error("%d:%d got transaction with invalid 
offset, %zd\n",
-   proc->pid, thread->pid, *offp);
+   proc->pid, thread->pid, 
deref_helper(offp));
return_error = BR_FAILED_REPLY;
goto err_bad_offset;
}
-   fp = (struct flat_binder_object *)(t->buffer->data + *offp);
+   fp = (struct flat_binder_object *)(t->buffer->data + 
deref_helper(offp));
switch (fp->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 0/9] Android: Add Support for Binder Compat

2013-12-04 Thread Serban Constantinescu
Hi all,

The patches attached add support for 32bit userspace running on 64bit
kernels. This is the last series of patches needed for basic 32bit Android
bring-up on 64bit kernels.

The series is split into refactoring the binder driver and the addition
of the compat layer. Please note that the helper macros are extended
with compat handling by the last patch of the series.

The patches have been successfully tested on 32 and 64bit platforms.

Thanks for your help,
Best regards,
Serban Constantinescu

Serban Constantinescu (9):
  staging: android: binder: Move some of the logic into subfunction
  staging: android: binder: Add binder_copy_to_user()
  staging: android: binder: Add cmd == CMD_NAME handling
  staging: android: binder: Add align_helper() macro
  staging: android: binder: Add deref_helper() macro
  staging: android: binder: Add size_helper() macro
  staging: android: binder: Add copy_flat_binder_object()
  staging: android: binder: Add binder compat handling to binder.h
  staging: android: binder: Add binder compat layer

 drivers/staging/android/binder.c |  846 --
 drivers/staging/android/binder.h |  109 +
 2 files changed, 732 insertions(+), 223 deletions(-)

-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 9/9] staging: android: binder: Add binder compat layer

2013-12-04 Thread Serban Constantinescu
This patch adds support for 32bit userspace running on 64bit kernels.
All the changes done in this patch have been tested on 32bit and 64bit
systems.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |  355 +-
 1 file changed, 353 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 855d348..941973a 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -37,6 +37,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "binder.h"
 #include "binder_trace.h"
@@ -140,6 +141,77 @@ module_param_call(stop_on_user_error, 
binder_set_stop_on_user_error,
binder_stop_on_user_error = 2; \
} while (0)
 
+#ifdef CONFIG_COMPAT
+static inline void writeback_flat_binder_object(struct flat_binder_object *fp,
+void __user *ptr)
+{
+   struct compat_flat_binder_object *tmp_fp;
+
+   tmp_fp = (struct compat_flat_binder_object *) ptr;
+   tmp_fp->type = fp->type;
+   tmp_fp->flags = fp->flags;
+   tmp_fp->binder = ptr_to_compat(fp->binder);
+   tmp_fp->cookie = ptr_to_compat(fp->cookie);
+}
+
+static inline struct flat_binder_object *copy_flat_binder_object(void __user 
*ptr)
+{
+   struct flat_binder_object *fp;
+   struct compat_flat_binder_object *tmp_fp;
+
+   if (!is_compat_task())
+   return (struct flat_binder_object *) ptr;
+
+   fp = kzalloc(sizeof(*fp), GFP_KERNEL);
+   if (fp == NULL)
+   return NULL;
+
+   tmp_fp = (struct compat_flat_binder_object *) ptr;
+   /* copy compat struct */
+   fp->type = tmp_fp->type;
+   fp->flags = tmp_fp->flags;
+   fp->binder = compat_ptr(tmp_fp->binder);
+   fp->cookie = compat_ptr(tmp_fp->cookie);
+
+   return fp;
+}
+
+static inline uint32_t compat_change_size(uint32_t cmd, size_t size)
+{
+   uint32_t compat_cmd;
+
+   compat_cmd = cmd & ~IOCSIZE_MASK;
+   compat_cmd = compat_cmd | ((size << _IOC_SIZESHIFT) & IOCSIZE_MASK);
+   return compat_cmd;
+}
+
+#define align_helper(x) (  \
+   is_compat_task() ?  \
+   ALIGN(x, sizeof(compat_uptr_t)) :   \
+   ALIGN(x, sizeof(void *))\
+   )
+
+#define deref_helper(x) (  \
+   is_compat_task() ?  \
+   (size_t) *(compat_size_t *)x :  \
+   *(size_t *)x\
+   )
+
+#define size_helper(x) ({  \
+   size_t __size;  \
+   if (!is_compat_task())  \
+   __size = sizeof(x); \
+   else if (sizeof(x) == sizeof(struct flat_binder_object))\
+   __size = sizeof(struct compat_flat_binder_object);  \
+   else if (sizeof(x) == sizeof(struct binder_transaction_data))   \
+   __size = sizeof(struct compat_binder_transaction_data); \
+   else if (sizeof(x) == sizeof(size_t))   \
+   __size = sizeof(compat_size_t); \
+   else\
+BUG(); \
+   __size; \
+   })
+#else
 #define align_helper(ptr)  ALIGN(ptr, sizeof(void *))
 #define deref_helper(ptr)  (*(typeof(size_t *))ptr)
 #define size_helper(x) sizeof(x)
@@ -148,6 +220,7 @@ static inline struct flat_binder_object 
*copy_flat_binder_object(void __user *pt
 {
return (struct flat_binder_object *)ptr;
 }
+#endif
 
 enum binder_stat_types {
BINDER_STAT_PROC,
@@ -1254,7 +1327,7 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
else
off_end = (void *)offp + buffer->offsets_size;
for (; offp < off_end; offp += size_helper(size_t)) {
-   struct flat_binder_object *fp;
+   struct flat_binder_object *fp = NULL;
if (deref_helper(offp) > buffer->data_size - size_helper(*fp) ||
buffer->data_size < size_helper(*fp) ||
!IS_ALIGNED(deref_helper(offp), sizeof(u32))) {
@@ -1303,6 +1376,8 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,

[PATCH v1 3/9] staging: android: binder: Add cmd == CMD_NAME handling

2013-12-04 Thread Serban Constantinescu
This patch modifies the functions that need to be passed the explicit
command to use a boolean flag. This way we can reuse the code for 64bit
compat commands.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |   35 ++-
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 6fbb340..16109cd 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -1701,7 +1701,7 @@ err_no_context_mgr_node:
 }
 
 static void bc_increfs_done(struct binder_proc *proc,
-   struct binder_thread *thread, uint32_t cmd,
+   struct binder_thread *thread, bool acquire,
void __user *node_ptr, void __user *cookie)
 {
struct binder_node *node;
@@ -1710,22 +1710,22 @@ static void bc_increfs_done(struct binder_proc *proc,
if (node == NULL) {
binder_user_error("%d:%d %s u%p no match\n",
proc->pid, thread->pid,
-   cmd == BC_INCREFS_DONE ?
-   "BC_INCREFS_DONE" :
-   "BC_ACQUIRE_DONE",
+   acquire ?
+   "BC_ACQUIRE_DONE" :
+   "BC_INCREFS_DONE",
node_ptr);
return;
}
if (cookie != node->cookie) {
binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != 
%p\n",
proc->pid, thread->pid,
-   cmd == BC_INCREFS_DONE ?
-   "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
+   acquire ?
+   "BC_ACQUIRE_DONE" : "BC_INCREFS_DONE",
node_ptr, node->debug_id,
cookie, node->cookie);
return;
}
-   if (cmd == BC_ACQUIRE_DONE) {
+   if (acquire) {
if (node->pending_strong_ref == 0) {
binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no 
pending acquire request\n",
proc->pid, thread->pid,
@@ -1742,13 +1742,13 @@ static void bc_increfs_done(struct binder_proc *proc,
}
node->pending_weak_ref = 0;
}
-   binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
+   binder_dec_node(node, acquire, 0);
binder_debug(BINDER_DEBUG_USER_REFS,
 "%d:%d %s node %d ls %d lw %d\n",
 proc->pid, thread->pid,
-cmd == BC_INCREFS_DONE ?
-"BC_INCREFS_DONE" :
-"BC_ACQUIRE_DONE",
+acquire ?
+"BC_ACQUIRE_DONE" :
+"BC_INCREFS_DONE",
 node->debug_id, node->local_strong_refs,
 node->local_weak_refs);
return;
@@ -1793,7 +1793,7 @@ static void bc_free_buffer(struct binder_proc *proc,
 }
 
 static void bc_clear_death_notif(struct binder_proc *proc,
-   struct binder_thread *thread, uint32_t cmd,
+   struct binder_thread *thread, bool request,
uint32_t target, void __user *cookie)
 {
struct binder_ref *ref;
@@ -1803,7 +1803,7 @@ static void bc_clear_death_notif(struct binder_proc *proc,
if (ref == NULL) {
binder_user_error("%d:%d %s invalid ref %d\n",
proc->pid, thread->pid,
-   cmd == BC_REQUEST_DEATH_NOTIFICATION ?
+   request ?
"BC_REQUEST_DEATH_NOTIFICATION" :
"BC_CLEAR_DEATH_NOTIFICATION",
target);
@@ -1813,13 +1813,13 @@ static void bc_clear_death_notif(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",
 proc->pid, thread->pid,
-cmd == BC_REQUEST_DEATH_NOTIFICATION ?
+request ?
 "BC_REQUEST_DEATH_NOTIFICATION" :
 "BC_CLEAR_DEATH_NOTIFICATION",
 cookie, ref->debug_id, ref->desc,
 ref->strong, ref->weak, ref->node->debug_id);
 
-   if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
+   if (request) {
if (ref->death) {
binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION 
death notification already set\n",
proc->pid, thread->pid);
@@ -1993,7 +1993,7 @@ static int binder_thread_write(struct 

[PATCH v1 7/9] staging: android: binder: Add copy_flat_binder_object()

2013-12-04 Thread Serban Constantinescu
This patch adds copy_flat_binder_object macro() that will help
dereference struct flat_binder_object on 64bit systems where the
structure differs between 32bit and 64bit userspace.

This patch is a temporary patch that will be extended with 32bit compat
handling.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 6d22717..855d348 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -144,6 +144,11 @@ module_param_call(stop_on_user_error, 
binder_set_stop_on_user_error,
 #define deref_helper(ptr)  (*(typeof(size_t *))ptr)
 #define size_helper(x) sizeof(x)
 
+static inline struct flat_binder_object *copy_flat_binder_object(void __user 
*ptr)
+{
+   return (struct flat_binder_object *)ptr;
+}
+
 enum binder_stat_types {
BINDER_STAT_PROC,
BINDER_STAT_THREAD,
@@ -1257,7 +1262,7 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
 debug_id, deref_helper(offp), buffer->data_size);
continue;
}
-   fp = (struct flat_binder_object *)(buffer->data + 
deref_helper(offp));
+   fp = copy_flat_binder_object(buffer->data + deref_helper(offp));
switch (fp->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
@@ -1507,7 +1512,7 @@ static void binder_transaction(struct binder_proc *proc,
return_error = BR_FAILED_REPLY;
goto err_bad_offset;
}
-   fp = (struct flat_binder_object *)(t->buffer->data + 
deref_helper(offp));
+   fp = copy_flat_binder_object(t->buffer->data + 
deref_helper(offp));
switch (fp->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
-- 
1.7.9.5

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v1 8/9] staging: android: binder: Add binder compat handling to binder.h

2013-12-04 Thread Serban Constantinescu
This patch adds all the needed compat structures to binder.h. All the
structures defined in this patch mirror the structure and size of 32bit
ones.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.h |  109 ++
 1 file changed, 109 insertions(+)

diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h
index cbe3451..6c9849d 100644
--- a/drivers/staging/android/binder.h
+++ b/drivers/staging/android/binder.h
@@ -22,6 +22,10 @@
 
 #include 
 
+#ifdef CONFIG_COMPAT
+#include 
+#endif
+
 #define B_PACK_CHARS(c1, c2, c3, c4) \
c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
 #define B_TYPE_LARGE 0x85
@@ -326,5 +330,110 @@ enum binder_driver_command_protocol {
 */
 };
 
+/* Support for 32bit userspace on a 64bit system */
+#ifdef CONFIG_COMPAT
+struct compat_flat_binder_object {
+   /* 8 bytes for large_flat_header. */
+   __u32   type;
+   __u32   flags;
+
+   /* 8 bytes of data. */
+   union {
+   compat_uptr_t   binder; /* local object */
+   __u32   handle; /* remote object */
+   };
+
+   /* extra data associated with local object */
+   compat_uptr_t   cookie;
+};
+
+struct compat_binder_write_read {
+   compat_size_t   write_size; /* bytes to write */
+   compat_size_t   write_consumed; /* bytes consumed by driver */
+   compat_ulong_t  write_buffer;
+   compat_size_t   read_size;  /* bytes to read */
+   compat_size_t   read_consumed;  /* bytes consumed by driver */
+   compat_ulong_t  read_buffer;
+};
+
+#define COMPAT_BINDER_WRITE_READ   _IOWR('b', 1, struct 
compat_binder_write_read)
+
+struct compat_binder_transaction_data {
+   /* The first two are only used for bcTRANSACTION and brTRANSACTION,
+* identifying the target and contents of the transaction.
+*/
+   union {
+   __u32   handle; /* target descriptor of command 
transaction */
+   compat_uptr_t   ptr;/* target descriptor of return 
transaction */
+   } target;
+   compat_uptr_t   cookie; /* target object cookie */
+   __u32   code;   /* transaction command */
+
+   /* General information about the transaction. */
+   __u32   flags;
+   pid_t   sender_pid;
+   uid_t   sender_euid;
+   compat_size_t   data_size;  /* number of bytes of data */
+   compat_size_t   offsets_size;   /* number of bytes of offsets */
+
+   /* If this transaction is inline, the data immediately
+* follows here; otherwise, it ends with a pointer to
+* the data buffer.
+*/
+   union {
+   struct {
+   /* transaction data */
+   compat_uptr_t   buffer;
+   /* offsets from buffer to flat_binder_object structs */
+   compat_uptr_t   offsets;
+   } ptr;
+   __u8buf[8];
+   } data;
+};
+
+struct compat_binder_ptr_cookie {
+   compat_uptr_t ptr;
+   compat_uptr_t cookie;
+};
+
+/* legacy - not used anymore */
+struct compat_binder_pri_ptr_cookie {
+   __s32 priority;
+   compat_uptr_t ptr;
+   compat_uptr_t cookie;
+};
+
+enum compat_binder_driver_return_protocol {
+   COMPAT_BR_TRANSACTION = _IOR('r', 2, struct 
compat_binder_transaction_data),
+   COMPAT_BR_REPLY = _IOR('r', 3, struct compat_binder_transaction_data),
+
+   COMPAT_BR_INCREFS = _IOR('r', 7, struct compat_binder_ptr_cookie),
+   COMPAT_BR_ACQUIRE = _IOR('r', 8, struct compat_binder_ptr_cookie),
+   COMPAT_BR_RELEASE = _IOR('r', 9, struct compat_binder_ptr_cookie),
+   COMPAT_BR_DECREFS = _IOR('r', 10, struct compat_binder_ptr_cookie),
+
+   /* legacy - not used anymore */
+   COMPAT_BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct 
compat_binder_pri_ptr_cookie),
+
+   COMPAT_BR_DEAD_BINDER = _IOR('r', 15, compat_uptr_t),
+   COMPAT_BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, compat_uptr_t),
+};
+
+enum compat_binder_driver_command_protocol {
+   COMPAT_BC_TRANSACTION = _IOW('c', 0, struct 
compat_binder_transaction_data),
+   COMPAT_BC_REPLY = _IOW('c', 1, struct compat_binder_transaction_data),
+
+   COMPAT_BC_FREE_BUFFER = _IOW('c', 3, compat_uptr_t),
+
+   COMPAT_BC_INCREFS_DONE = _IOW('c', 8, struct compat_binder_ptr_cookie),
+   COMPAT_BC_ACQUIRE_DONE = _IOW('c', 9, struct compat_binder_ptr_cookie),
+
+   COMPAT_BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct 
compat_binder_ptr_cookie),
+   COMPAT_BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct 
compat_binder_ptr_cookie),
+
+   COMPAT_BC_DEAD_BINDER_DONE = _IOW('c', 1

[PATCH v1 1/9] staging: android: binder: Move some of the logic into subfunction

2013-12-04 Thread Serban Constantinescu
This patch moves some of the logic for binder_thread_write() into
subfunctions. This way we can share more code with the binder compat
layer.

Signed-off-by: Serban Constantinescu 
---
 drivers/staging/android/binder.c |  403 +-
 1 file changed, 220 insertions(+), 183 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index eaec1da..233889c 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -1700,6 +1700,217 @@ err_no_context_mgr_node:
thread->return_error = return_error;
 }
 
+static void bc_increfs_done(struct binder_proc *proc,
+   struct binder_thread *thread, uint32_t cmd,
+   void __user *node_ptr, void __user *cookie)
+{
+   struct binder_node *node;
+
+   node = binder_get_node(proc, node_ptr);
+   if (node == NULL) {
+   binder_user_error("%d:%d %s u%p no match\n",
+   proc->pid, thread->pid,
+   cmd == BC_INCREFS_DONE ?
+   "BC_INCREFS_DONE" :
+   "BC_ACQUIRE_DONE",
+   node_ptr);
+   return;
+   }
+   if (cookie != node->cookie) {
+   binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != 
%p\n",
+   proc->pid, thread->pid,
+   cmd == BC_INCREFS_DONE ?
+   "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
+   node_ptr, node->debug_id,
+   cookie, node->cookie);
+   return;
+   }
+   if (cmd == BC_ACQUIRE_DONE) {
+   if (node->pending_strong_ref == 0) {
+   binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no 
pending acquire request\n",
+   proc->pid, thread->pid,
+   node->debug_id);
+   return;
+   }
+   node->pending_strong_ref = 0;
+   } else {
+   if (node->pending_weak_ref == 0) {
+   binder_user_error("%d:%d BC_INCREFS_DONE node %d has no 
pending increfs request\n",
+   proc->pid, thread->pid,
+   node->debug_id);
+   return;
+   }
+   node->pending_weak_ref = 0;
+   }
+   binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
+   binder_debug(BINDER_DEBUG_USER_REFS,
+"%d:%d %s node %d ls %d lw %d\n",
+proc->pid, thread->pid,
+cmd == BC_INCREFS_DONE ?
+"BC_INCREFS_DONE" :
+"BC_ACQUIRE_DONE",
+node->debug_id, node->local_strong_refs,
+node->local_weak_refs);
+   return;
+}
+
+static void bc_free_buffer(struct binder_proc *proc,
+   struct binder_thread *thread, void __user *data_ptr)
+{
+   struct binder_buffer *buffer;
+
+   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);
+   return;
+   }
+   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);
+   return;
+   }
+   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,
+buffer->transaction ? "active" : "finished");
+
+   if (buffer->transaction) {
+   buffer->transaction->buffer = NULL;
+   buffer->transaction = NULL;
+   }
+   if (buffer->async_transaction && buffer->target_node) {
+   BUG_ON(!buffer->target_node->has_async_transaction);
+   if (list_empty(&buffer->target_node->async_todo))
+   buffer->target_node->has_async_transaction = 0;
+   else
+   list_move_tail(buffer->target_node->async_todo.next, 
&thread->todo);
+   }
+   trace_binder_transaction_buffer_release(buffer);
+   binder_transaction_buffer_release(proc, buffer, NULL);
+   binder_free_buf(proc, buffer);
+   return;
+}
+
+static void bc_clear_death_notif(struct binder_proc *proc,
+   struct binder_thread *thread, uint32_t cmd,
+   uint32_

Re: [PATCH v1 9/9] staging: android: binder: Add binder compat layer

2013-12-05 Thread Serban Constantinescu

Hi all,

Thanks for your feedback! Sadly enough, being in a different time-zone, 
is not useful.


Sorry for the confusion related to why is this patch needed or not. I
should highlight a bit more what is the patch enabling and what would be 
the different alternatives, at least from my perspective.


*64bit kernel/ 32bit userspace*

This patch series adds support for 32bit userspace running on 64bit 
kernels. Thus by applying this patch to your kernel you will be able to 
use any existing 32bit Android userspace on your 64bit platform, running 
a 64bit kernel. That is pure 32bit userspace with no 64bit support!


This means *no modifications to the 32bit userspace*. Therefore any 
applications or userspace side drivers, that uses the binder interface 
at a native level will not have to be modified. These kind of 
applications are not "good citizens" - the native binder API is not 
exposed in the Android NDK. However I do not know how many applications 
do this and if breaking the compatibility is a concernt for 32bit 
userspace running on 64bit kernels.


Below you will find more information on one of the alternative 
solutions, the userspace compat.


*32bit kernel/ 32bit userspace*
*64bit kernel/ 64bit userspace*

My last series of binder patches, accepted into 3.12 revision of the 
Linux kernel, audits the binder interface for 64bit. A kernel with these 
changes applied can be used with a pure 64bit userspace (this does not 
include support for 32bit applications coexisting with 64bit ones). The 
userspace side needs trivial changes to libbinder.so and servicemanager, 
that I will upstream ASAP to AOSP, and that work for 32/32 systems and 
64/64 systems without modifying the existing 32bit interface ABI (most 
of the changes are related to uint32_t != void *).



Author: Serban Constantinescu 
Date:   Thu Jul 4 10:54:48 2013 +0100

staging: android: binder: fix binder interface for 64bit compat layer


*64bit kernel/ 64bit coexisting with 32bit userspace

Please note that *none of the above solutions fix this yet*. To 
understand why this is a special case please take a look at

how the binder driver works, seen from a high level perspective:


  ServiceManager
App1  <-> App2


Thus, for two apps to exchange information between each other they will 
have to communicate with the userspace governor, ServiceManager. All the 
interaction between App1, App2 and ServiceManager is done through a 
combination of libbinder.so (Userspace HAL) and the binder driver. Note 
that there can only been one ServiceManager process, that is set during 
the userspace boot process.


Now lets consider the case that Arve described earlier 32bit 
Applications coexisting with 64bit ones. In this case all the commands 
and interface used will have to be the same, the ones used by the 64bit 
ServiceManager. For this the kernel entry point for 32bit compat will 
have to be changed to:



--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -3893,9 +3893,13 @@ static const struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl,
-#ifdef CONFIG_COMPAT
+#if defined(CONFIG_COMPAT) && !defined(COEXIST_32BIT_64BIT)
.compat_ioctl = compat_binder_ioctl,
 #endif
+
+#if defined(COEXIST_32BIT_64BIT)
+   .compat_ioctl = binder_ioctl,
+#endif
.mmap = binder_mmap,
.open = binder_open,
.flush = binder_flush,


thus from the perspective of a kernel that works with a 64bit userspace 
where 64bit applications coexist with 32bit applications the handling 
will be the same for both 32bit and 64bit processes. This will also 
involve modifying libbinder.so to use 64bit structures like:



--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
+#if defined(COEXIST_32BIT_64BIT) && !defined(__LP64__)
+/*
+ * For running 32-bit processes on a 64-bit system, make the interaction with 
the
+ * binder driver the same from this, when built for 32-bit, as for a 64-bit 
process.
+ */
+struct coexist_binder_write_read {
+uint64_twrite_size; /* __LP64__ size_t: bytes to write */
+uint64_twrite_consumed; /* __LP64__ size_t: bytes consumed by driver */
+uint64_twrite_buffer;   /* __LP64__ unsigned long */
+uint64_tread_size;  /* __LP64__ size_t: bytes to read */
+uint64_tread_consumed;  /* __LP64__ size_t: bytes consumed by driver */
+uint64_tread_buffer;/* __LP64__ unsigned long */
+};


"Good citizen" Android applications will go through these changes (since 
they should only use the binder Java API), and so shouldn't encounter 
any problem. Any 32bit applications that use the binder interface at a 
native level will not work with this model (they should not do so!)ยท 
This is exactly what the kernel compat "guarantees" *only* for 64/32bit 
systems.


The 

Re: [PATCH v1 1/9] staging: android: binder: Move some of the logic into subfunction

2013-12-05 Thread Serban Constantinescu

On 05/12/13 08:00, Dan Carpenter wrote:

On Wed, Dec 04, 2013 at 06:09:33PM +, Serban Constantinescu wrote:

+static void bc_dead_binder_done(struct binder_proc *proc,
+   struct binder_thread *thread, void __user *cookie)
+{
+   struct binder_work *w;
+   struct binder_ref_death *death = NULL;
+
+   list_for_each_entry(w, &proc->delivered_death, entry) {
+   struct binder_ref_death *tmp_death = container_of(w, struct 
binder_ref_death, work);


Put a blank line after the variable declaration block.  Also break it up
into two lines instead of having the lines be a million characters long.


I will do that, I have followed the same conventions used by the code 
allready there.




list_for_each_entry(w, &proc->delivered_death, entry) {
struct binder_ref_death *tmp_death;

tmp_death = container_of(w, struct binder_ref_death, work);


+   if (tmp_death->cookie == cookie) {
+   death = tmp_death;
+   return;


Should be a break here.  This function wasn't tested.


There should be a break there! I have tested the driver with 32bit 
Android tests, none of which seem to hit this.


Thanks for your review,
Serban C

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 1/9] staging: android: binder: Move some of the logic into subfunction

2013-12-05 Thread Serban Constantinescu

On 05/12/13 08:18, Dan Carpenter wrote:

On Wed, Dec 04, 2013 at 06:09:33PM +, Serban Constantinescu wrote:

+static void bc_increfs_done(struct binder_proc *proc,
+   struct binder_thread *thread, uint32_t cmd,
+   void __user *node_ptr, void __user *cookie)
+{
+   struct binder_node *node;
+
+   node = binder_get_node(proc, node_ptr);
+   if (node == NULL) {
+   binder_user_error("%d:%d %s u%p no match\n",
+   proc->pid, thread->pid,
+   cmd == BC_INCREFS_DONE ?
+   "BC_INCREFS_DONE" :
+   "BC_ACQUIRE_DONE",
+   node_ptr);
+   return;
+   }
+   if (cookie != node->cookie) {
+   binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != 
%p\n",
+   proc->pid, thread->pid,
+   cmd == BC_INCREFS_DONE ?
+   "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
+   node_ptr, node->debug_id,
+   cookie, node->cookie);
+   return;
+   }
+   if (cmd == BC_ACQUIRE_DONE) {
+   if (node->pending_strong_ref == 0) {
+   binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no 
pending acquire request\n",
+   proc->pid, thread->pid,
+   node->debug_id);
+   return;
+   }
+   node->pending_strong_ref = 0;
+   } else {
+   if (node->pending_weak_ref == 0) {
+   binder_user_error("%d:%d BC_INCREFS_DONE node %d has no 
pending increfs request\n",
+   proc->pid, thread->pid,
+   node->debug_id);
+   return;
+   }
+   node->pending_weak_ref = 0;
+   }
+   binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0);
+   binder_debug(BINDER_DEBUG_USER_REFS,
+"%d:%d %s node %d ls %d lw %d\n",
+proc->pid, thread->pid,
+cmd == BC_INCREFS_DONE ?
+"BC_INCREFS_DONE" :
+"BC_ACQUIRE_DONE",
+node->debug_id, node->local_strong_refs,
+node->local_weak_refs);
+   return;
+}


This function is 52 lines long but at least 32 of those lines are
debug code.

Just extra of lines of code means you have increased the number of bugs
150%.  But what I know is that from a static analysis perspective, debug
code has more defects per line then regular code it's worse than that.
Plus all the extra noise obscures the actual logic and makes the real
code annoying to look at so it's worse still.

If you want to move this stuff out of staging, then remove all the extra
crap so it doesn't look like barf.


This patch moves code around so that some of it can be shared with the
compat layer. I agree that due to the abundance of debug code it is, at
times, hard to have a clear idea of what is actually happening and adds
extra obscurities to the logic.

Thanks,
Serban C

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v1 2/9] staging: android: binder: Add binder_copy_to_user()

2013-12-05 Thread Serban Constantinescu

On 04/12/13 23:17, Greg KH wrote:

On Wed, Dec 04, 2013 at 06:09:34PM +, Serban Constantinescu wrote:

This patch adds binder_copy_to_user() to be used for copying binder
commands to user address space. This way we can abstract away the
copy_to_user() calls and add separate handling for the compat layer.

Signed-off-by: Serban Constantinescu 
---
  drivers/staging/android/binder.c |   39 --
  1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 233889c..6fbb340 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2117,6 +2117,18 @@ static int binder_has_thread_work(struct binder_thread 
*thread)
(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN);
  }

+static int binder_copy_to_user(uint32_t cmd, void *parcel,
+  void __user **ptr, size_t size)
+{
+   if (put_user(cmd, (uint32_t __user *)*ptr))
+   return -EFAULT;
+   *ptr += sizeof(uint32_t);
+   if (copy_to_user(*ptr, parcel, size))
+   return -EFAULT;
+   *ptr += size;
+   return 0;
+}


I know what you are trying to do here, but ick, why not just use the
structure involved in the copying out here?  Or just copy the thing out
in one "chunk", not two different calls, which should make this go
faster, right?


Ick... agree. I do this split here for the compat handling added in the
next patches, where the cmd will have to be converted to a 32bit compat
cmd and the size, parcel ,passed here will change to a 32bit compat
size, parcel.

This patch makes more sense when looking at the following snippet:

**


+static int binder_copy_to_user(uint32_t cmd, void *parcel,
+  void __user **ptr, size_t size)
+{
+   if (!is_compat_task()) {
+   if (put_user(cmd, (uint32_t __user *)*ptr))
+   return -EFAULT;
+   *ptr += sizeof(uint32_t);
+   if (copy_to_user(*ptr, parcel, size))
+   return -EFAULT;
+   *ptr += size;
+   return 0;
+   }
+   switch (cmd) {
+   case BR_INCREFS:
+   case BR_ACQUIRE:
+   case BR_RELEASE:
+   case BR_DECREFS: {
+   struct binder_ptr_cookie *fp;
+   struct compat_binder_ptr_cookie tmp;
+
+   cmd = compat_change_size(cmd, sizeof(tmp));


Passing the cmd, and the structure to be copied to binder_copy_to_user()
allows me to add this extra handling here. Where, first, cmd is changed
to a compat cmd, and then copied to userspace - i.e:

I change


cmd = BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie)


to


cmd = COMPAT_BR_INCREFS = _IOR('r', 7, struct compat_binder_ptr_cookie)


where


struct binder_ptr_cookie {
void* ptr;
void* cookie;
};


and


struct compat_binder_ptr_cookie {
compat_uptr_t ptr;
compat_uptr_t cookie;
};


Thus BR_INCREFS will be different between 32bit userspace and 64bit kernel.


+   BUG_ON((cmd != COMPAT_BR_INCREFS) &&
+  (cmd != COMPAT_BR_ACQUIRE) &&
+  (cmd != COMPAT_BR_RELEASE) &&
+  (cmd != COMPAT_BR_DECREFS));
+
+   fp = (struct binder_ptr_cookie *) parcel;
+   tmp.ptr = ptr_to_compat(fp->ptr);
+   tmp.cookie = ptr_to_compat(fp->cookie);
+   if (put_user(cmd, (uint32_t __user *)*ptr))
+   return -EFAULT;
+   *ptr += sizeof(uint32_t);
+   if (copy_to_user(*ptr, &tmp, sizeof(tmp)))
+   return -EFAULT;
+   *ptr += sizeof(tmp);


Also, since the size of the parcel will differ when copied to a compat
task (32bit userspace) I increment the buffer ptr here, rather then
doing this in binder_thread_read().

This way we can safely move to the next cmd, by incrementing the buffer
ptr accordingly whether 32 or 64bit structures are needed.

**



+
  static int binder_thread_read(struct binder_proc *proc,
  struct binder_thread *thread,
  void  __user *buffer, size_t size,
@@ -2263,15 +2275,12 @@ retry:
node->has_weak_ref = 0;
}
if (cmd != BR_NOOP) {
-   if (put_user(cmd, (uint32_t __user *)ptr))
-   return -EFAULT;
-   ptr += sizeof(uint32_t);
-   if (put_user(node->ptr, (void * __user *)ptr))
-   return -EFAULT;
-   ptr += sizeof(void *);
-   if (put_user(node->cookie, (void * __user 
*)ptr))
+   str

Re: [PATCH v1 3/9] staging: android: binder: Add cmd == CMD_NAME handling

2013-12-05 Thread Serban Constantinescu

On 05/12/13 08:40, Dan Carpenter wrote:

On Wed, Dec 04, 2013 at 06:09:35PM +, Serban Constantinescu wrote:

This patch modifies the functions that need to be passed the explicit
command to use a boolean flag. This way we can reuse the code for 64bit
compat commands.



I don't understand this at all.  cmd seems like it should be 32 bits
on both arches.
Command is 32bit for both arches but does not have the same value. Here 
is what happens, this patch make more sense when looking at the compat 
layer.


The binder commands differ between 32bit userspace and 64bit kernels. E.g:


BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie)



COMPAT_BR_INCREFS = _IOR('r', 7, struct compat_binder_ptr_cookie)



struct compat_binder_ptr_cookie {
compat_uptr_t ptr;
compat_uptr_t cookie;
};



struct binder_ptr_cookie {
void *ptr;
void *cookie;
};


(the IOR() macro encodes the size of the transaction - struct 
binder_ptr_cookie).


This enables me to use the same handler for:

* native 64bit kernel/ 64bit userspace


  case BC_INCREFS_DONE:
case BC_ACQUIRE_DONE: {
 void __user *node_ptr;
 void *cookie;

 if (get_user(node_ptr, (void * __user *)ptr))
   return -EFAULT;
 ptr += sizeof(void *);
 if (get_user(cookie, (void * __user *)ptr))
   return -EFAULT;
 ptr += sizeof(void *);
 bc_increfs_done(proc, thread, cmd == BC_ACQUIRE_DONE, 
node_ptr, cookie);
 break;
  }


* compat 64bit kernel/ 32bit userspace.


+   case COMPAT_BC_INCREFS_DONE:
+   case COMPAT_BC_ACQUIRE_DONE: {
+   compat_uptr_t node_ptr;
+   compat_uptr_t cookie;
+
+   if (get_user(node_ptr, (compat_uptr_t __user *)*ptr))
+   return -EFAULT;
+   *ptr += sizeof(compat_uptr_t);
+   if (get_user(cookie, (compat_uptr_t __user *)*ptr))
+   return -EFAULT;
+   *ptr += sizeof(compat_uptr_t);
+   bc_increfs_done(proc, thread, cmd == COMPAT_BC_ACQUIRE_DONE,
+   compat_ptr(node_ptr), compat_ptr(cookie));
+   break;


where the prototype for bc_increfs_done() has changed to:


 static void bc_increfs_done(struct binder_proc *proc,
-struct binder_thread *thread, uint32_t cmd,
+struct binder_thread *thread, bool acquire,


Obsucre on its own, I should add more details in the commit message.

Thanks,
Serban C

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel