From 7bb429f0dc58fbb1248e986638d2b117650025da Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Tue, 7 Jan 2014 14:25:28 -0800 Subject: android: configs: add IPV6 ROUTE INFO Change-Id: I54cba86bce703647c4be8eee5592d55374ad02ef Signed-off-by: JP Abgrall (cherry picked from commit 5e35d662616142d308ce24c9d552e469f60d8695) --- android/configs/android-base.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index a9597658ef1..1fb9bb5b1ac 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -35,6 +35,7 @@ CONFIG_IPV6_MIP6=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTE_INFO=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y -- cgit v1.2.3 From 7b397ae09a9d11abdbb6c3d2f1ce52cd58db3aca Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Thu, 4 Jul 2013 10:54:43 +0100 Subject: staging: android: binder: modify struct binder_write_read to use size_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change mirrors the userspace operation where struct binder_write_read members that specify the buffer size and consumed size are size_t elements. The patch also fixes the binder_thread_write() and binder_thread_read() functions prototypes to conform with the definition of binder_write_read. The changes do not affect existing 32bit ABI. Change-Id: I987246d507b9c5e4627c62a1da971d11869ac5a0 Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/binder.c | 10 +++++----- drivers/staging/android/uapi/binder.h | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index f8d5b03f544..59e714cd8e1 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1719,7 +1719,7 @@ err_no_context_mgr_node: } int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, - void __user *buffer, int size, signed long *consumed) + void __user *buffer, size_t size, size_t *consumed) { uint32_t cmd; void __user *ptr = buffer + *consumed; @@ -2099,8 +2099,8 @@ 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, int size, - signed long *consumed, int non_block) + void __user *buffer, size_t size, + size_t *consumed, int non_block) { void __user *ptr = buffer + *consumed; void __user *end = buffer + size; @@ -2597,7 +2597,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; } binder_debug(BINDER_DEBUG_READ_WRITE, - "%d:%d write %ld at %08lx, read %ld at %08lx\n", + "%d:%d write %zd at %08lx, read %zd at %08lx\n", proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, bwr.read_size, bwr.read_buffer); @@ -2623,7 +2623,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } } binder_debug(BINDER_DEBUG_READ_WRITE, - "%d:%d wrote %ld of %ld, read return %ld of %ld\n", + "%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); if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index b6cb483592c..9e19f64e25a 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -67,11 +67,11 @@ struct flat_binder_object { */ struct binder_write_read { - signed long write_size; /* bytes to write */ - signed long write_consumed; /* bytes consumed by driver */ + size_t write_size; /* bytes to write */ + size_t write_consumed; /* bytes consumed by driver */ unsigned long write_buffer; - signed long read_size; /* bytes to read */ - signed long read_consumed; /* bytes consumed by driver */ + size_t read_size; /* bytes to read */ + size_t read_consumed; /* bytes consumed by driver */ unsigned long read_buffer; }; -- cgit v1.2.3 From b91bf7c0044e13ff0e28bf96c2a8265d3438ba11 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Thu, 4 Jul 2013 10:54:44 +0100 Subject: staging: android: binder: fix BINDER_SET_MAX_THREADS declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change will fix the BINDER_SET_MAX_THREADS ioctl to use __u32 instead of size_t for setting the max threads. Thus using the same handler for 32 and 64bit kernels. This value is stored internally in struct binder_proc and set to 15 on open_binder() in the libbinder API(thus no need for a 64bit size_t on 64bit platforms). The change does not affect existing 32bit ABI. Change-Id: Ibdfe10a70d475a91c247dc36e9cfd74a259d50e4 Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/uapi/binder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index 9e19f64e25a..db9abe37ac9 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -86,7 +86,7 @@ struct binder_version { #define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, __s64) -#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) +#define BINDER_SET_MAX_THREADS _IOW('b', 5, __u32) #define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, __s32) #define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32) #define BINDER_THREAD_EXIT _IOW('b', 8, __s32) -- cgit v1.2.3 From 6fcd5e8cd07c1abc3ed37bd4cc5d87451b3ae191 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Thu, 4 Jul 2013 10:54:45 +0100 Subject: staging: android: binder: fix BC_FREE_BUFFER ioctl declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BinderDriverCommands mirror the ioctl usage. Thus the size of the structure passed through the interface should be used to generate the ioctl No. The change reflects the type being passed from the user space-a pointer to a binder_buffer. This change should not affect the existing 32bit user space since BC_FREE_BUFFER is computed as: #define _IOW(type,nr,size) \ ((type) << _IOC_TYPESHIFT) | \ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) and for a 32bit compiler BC_FREE_BUFFER will have the same computed value. This change will also ease our work in differentiating BC_FREE_BUFFER from COMPAT_BC_FREE_BUFFER. The change does not affect existing 32bit ABI. Change-Id: I2e0ae87bc4e913225a8eb2912913f7e3617cb575 Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/uapi/binder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index db9abe37ac9..3de85afb5b6 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -265,7 +265,7 @@ enum binder_driver_command_protocol { * Else you have acquired a primary reference on the object. */ - BC_FREE_BUFFER = _IOW('c', 3, int), + BC_FREE_BUFFER = _IOW('c', 3, void *), /* * void *: ptr to transaction data received on a read */ -- cgit v1.2.3 From 6780a236302cc482c3261d03aec4f54437533500 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Thu, 4 Jul 2013 10:54:46 +0100 Subject: staging: android: binder: fix alignment issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Android userspace aligns the data written to the binder buffers to 4bytes. Thus for 32bit platforms or 64bit platforms running an 32bit Android userspace we can have a buffer looking like this: platform buffer(binder_cmd pointer) size 32/32 32b 32b 8B 64/32 32b 64b 12B 64/64 32b 64b 12B Thus the kernel needs to check that the buffer size is aligned to 4bytes not to (void *) that will be 8bytes on 64bit machines. The change does not affect existing 32bit ABI. Change-Id: I7535f07301519623ea6334f525d312d687407ed4 Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/binder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 59e714cd8e1..6e8b0e74240 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1249,7 +1249,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, struct flat_binder_object *fp; if (*offp > buffer->data_size - sizeof(*fp) || buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { + !IS_ALIGNED(*offp, sizeof(u32))) { pr_err("transaction release %d bad offset %zd, size %zd\n", debug_id, *offp, buffer->data_size); continue; @@ -1502,7 +1502,7 @@ static void binder_transaction(struct binder_proc *proc, struct flat_binder_object *fp; if (*offp > t->buffer->data_size - sizeof(*fp) || t->buffer->data_size < sizeof(*fp) || - !IS_ALIGNED(*offp, sizeof(void *))) { + !IS_ALIGNED(*offp, sizeof(u32))) { binder_user_error("%d:%d got transaction with invalid offset, %zd\n", proc->pid, thread->pid, *offp); return_error = BR_FAILED_REPLY; -- cgit v1.2.3 From 7e3039eda270f9820a3840f74057dd856bdeff1b Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Thu, 4 Jul 2013 10:54:47 +0100 Subject: staging: android: binder: replace types with portable ones MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since this driver is meant to be used on different types of processors and a portable driver should specify the size a variable expects to be this patch changes the types used throughout the binder interface. We use "userspace" types since this header will be exported and used by the Android filesystem. The patch does not change in any way the functionality of the binder driver. Change-Id: Ib26daab8bc44b92d4a09badc8ecb64d37ee8773b Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/uapi/binder.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index 3de85afb5b6..e1f547bb485 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -123,10 +123,10 @@ struct binder_transaction_data { void *ptr; /* target descriptor of return transaction */ } target; void *cookie; /* target object cookie */ - unsigned int code; /* transaction command */ + __u32 code; /* transaction command */ /* General information about the transaction. */ - unsigned int flags; + __u32 flags; pid_t sender_pid; uid_t sender_euid; size_t data_size; /* number of bytes of data */ @@ -143,7 +143,7 @@ struct binder_transaction_data { /* offsets from buffer to flat_binder_object structs */ const void __user *offsets; } ptr; - uint8_t buf[8]; + __u8 buf[8]; } data; }; @@ -153,18 +153,18 @@ struct binder_ptr_cookie { }; struct binder_pri_desc { - int priority; - int desc; + __s32 priority; + __s32 desc; }; struct binder_pri_ptr_cookie { - int priority; + __s32 priority; void *ptr; void *cookie; }; enum binder_driver_return_protocol { - BR_ERROR = _IOR('r', 0, int), + BR_ERROR = _IOR('r', 0, __s32), /* * int: error code */ @@ -178,7 +178,7 @@ enum binder_driver_return_protocol { * binder_transaction_data: the received command. */ - BR_ACQUIRE_RESULT = _IOR('r', 4, int), + BR_ACQUIRE_RESULT = _IOR('r', 4, __s32), /* * not currently supported * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. @@ -258,7 +258,7 @@ enum binder_driver_command_protocol { * binder_transaction_data: the sent command. */ - BC_ACQUIRE_RESULT = _IOW('c', 2, int), + BC_ACQUIRE_RESULT = _IOW('c', 2, __s32), /* * not currently supported * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. @@ -270,10 +270,10 @@ enum binder_driver_command_protocol { * void *: ptr to transaction data received on a read */ - BC_INCREFS = _IOW('c', 4, int), - BC_ACQUIRE = _IOW('c', 5, int), - BC_RELEASE = _IOW('c', 6, int), - BC_DECREFS = _IOW('c', 7, int), + BC_INCREFS = _IOW('c', 4, __u32), + BC_ACQUIRE = _IOW('c', 5, __u32), + BC_RELEASE = _IOW('c', 6, __u32), + BC_DECREFS = _IOW('c', 7, __u32), /* * int: descriptor */ -- cgit v1.2.3 From c44aa763f58444937c8320171e08ceffde811ba7 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Thu, 4 Jul 2013 10:54:48 +0100 Subject: staging: android: binder: fix binder interface for 64bit compat layer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The changes in this patch will fix the binder interface for use on 64bit machines and stand as the base of the 64bit compat support. The changes apply to the structures that are passed between the kernel and userspace. Most of the changes applied mirror the change to struct binder_version where there is no need for a 64bit wide protocol_version(on 64bit machines). The change inlines with the existing 32bit userspace(the structure has the same size) and simplifies the compat layer such that the same handler can service the BINDER_VERSION ioctl. Other changes make use of kernel types as well as user-exportable ones and fix format specifier issues. The changes do not affect existing 32bit ABI. Change-Id: Icccc8d47c302930cc61cddc5749b4cc74dc84117 Signed-off-by: Serban Constantinescu Acked-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/binder.c | 20 ++++++++++---------- drivers/staging/android/uapi/binder.h | 12 ++++++------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 6e8b0e74240..b9a7d934778 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1273,7 +1273,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); if (ref == NULL) { - pr_err("transaction release %d bad handle %ld\n", + pr_err("transaction release %d bad handle %d\n", debug_id, fp->handle); break; } @@ -1285,13 +1285,13 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_FD: binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld\n", fp->handle); + " fd %d\n", fp->handle); if (failed_at) task_close_fd(proc, fp->handle); break; default: - pr_err("transaction release %d bad object type %lx\n", + pr_err("transaction release %d bad object type %x\n", debug_id, fp->type); break; } @@ -1557,7 +1557,7 @@ static void binder_transaction(struct binder_proc *proc, case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); if (ref == NULL) { - binder_user_error("%d:%d got transaction with invalid handle, %ld\n", + binder_user_error("%d:%d got transaction with invalid handle, %d\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; @@ -1604,13 +1604,13 @@ static void binder_transaction(struct binder_proc *proc, if (reply) { if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { - binder_user_error("%d:%d got reply with fd, %ld, but target does not allow fds\n", + binder_user_error("%d:%d got reply with fd, %d, but target does not allow fds\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fd_not_allowed; } } else if (!target_node->accept_fds) { - binder_user_error("%d:%d got transaction with fd, %ld, but target does not allow fds\n", + binder_user_error("%d:%d got transaction with fd, %d, but target does not allow fds\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fd_not_allowed; @@ -1618,7 +1618,7 @@ static void binder_transaction(struct binder_proc *proc, file = fget(fp->handle); if (file == NULL) { - binder_user_error("%d:%d got transaction with invalid fd, %ld\n", + binder_user_error("%d:%d got transaction with invalid fd, %d\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fget_failed; @@ -1637,13 +1637,13 @@ static void binder_transaction(struct binder_proc *proc, task_fd_install(target_proc, target_fd, file); trace_binder_transaction_fd(t, fp->handle, target_fd); binder_debug(BINDER_DEBUG_TRANSACTION, - " fd %ld -> %d\n", fp->handle, target_fd); + " fd %d -> %d\n", fp->handle, target_fd); /* TODO: fput? */ fp->handle = target_fd; } break; default: - binder_user_error("%d:%d got transaction with invalid object type, %lx\n", + binder_user_error("%d:%d got transaction with invalid object type, %x\n", proc->pid, thread->pid, fp->type); return_error = BR_FAILED_REPLY; goto err_bad_object_type; @@ -2597,7 +2597,7 @@ 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 %08lx, read %zd at %08lx\n", + "%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); diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index e1f547bb485..e76cfa876da 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -48,13 +48,13 @@ enum { */ struct flat_binder_object { /* 8 bytes for large_flat_header. */ - unsigned long type; - unsigned long flags; + __u32 type; + __u32 flags; /* 8 bytes of data. */ union { void __user *binder; /* local object */ - signed long handle; /* remote object */ + __u32 handle; /* remote object */ }; /* extra data associated with local object */ @@ -78,7 +78,7 @@ struct binder_write_read { /* Use with BINDER_VERSION, driver fills in fields. */ struct binder_version { /* driver protocol version -- increment with incompatible change */ - signed long protocol_version; + __s32 protocol_version; }; /* This is the current protocol version. */ @@ -119,7 +119,7 @@ struct binder_transaction_data { * identifying the target and contents of the transaction. */ union { - size_t handle; /* target descriptor of command transaction */ + __u32 handle; /* target descriptor of command transaction */ void *ptr; /* target descriptor of return transaction */ } target; void *cookie; /* target object cookie */ @@ -154,7 +154,7 @@ struct binder_ptr_cookie { struct binder_pri_desc { __s32 priority; - __s32 desc; + __u32 desc; }; struct binder_pri_ptr_cookie { -- cgit v1.2.3 From e6395fe2411c2dda02c6052c7bbca32b56f10026 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 15 Jan 2014 11:28:36 +0000 Subject: staging: android: binder: fix ABI for 64bit Android This patch fixes the ABI for 64bit Android userspace. BC_REQUEST_DEATH_NOTIFICATION and BC_CLEAR_DEATH_NOTIFICATION claim to be using struct binder_ptr_cookie, but they are using a 32bit handle and a pointer. On 32bit systems the payload size is the same as the size of struct binder_ptr_cookie, however for 64bit systems this will differ. This patch adds struct binder_handle_cookie that fixes this issue for 64bit Android. Since there are no 64bit users of this interface that we know of this change should not affect any existing systems. Change-Id: I8909cbc50aad48ccf371270bad6f69ff242a8c22 Signed-off-by: Serban Constantinescu --- drivers/staging/android/uapi/binder.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index e76cfa876da..008722a249b 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -152,6 +152,11 @@ struct binder_ptr_cookie { void *cookie; }; +struct binder_handle_cookie { + __u32 handle; + void *cookie; +} __attribute__((packed)); + struct binder_pri_desc { __s32 priority; __u32 desc; @@ -308,15 +313,15 @@ enum binder_driver_command_protocol { * of looping threads it has available. */ - BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), + BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_handle_cookie), /* - * void *: ptr to binder + * int: handle * void *: cookie */ - BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), + BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_handle_cookie), /* - * void *: ptr to binder + * int: handle * void *: cookie */ -- cgit v1.2.3 From 9dcd36a520ecc9a56ffb8897e741b6fee59b43c7 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:33 +0000 Subject: staging: android: binder: Move some of the logic into subfunction 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 Signed-off-by: John Stultz --- drivers/staging/android/binder.c | 408 +++++++++++++++++++++------------------ 1 file changed, 223 insertions(+), 185 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index b9a7d934778..1b9ebe6577f 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1718,7 +1718,219 @@ err_no_context_mgr_node: thread->return_error = return_error; } -int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, +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_t target, void __user *cookie) +{ + struct binder_ref *ref; + struct binder_ref_death *death; + + ref = binder_get_ref(proc, target); + if (ref == NULL) { + binder_user_error("%d:%d %s invalid ref %d\n", + proc->pid, thread->pid, + cmd == BC_REQUEST_DEATH_NOTIFICATION ? + "BC_REQUEST_DEATH_NOTIFICATION" : + "BC_CLEAR_DEATH_NOTIFICATION", + target); + return; + } + + 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 ? + "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 (ref->death) { + binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set\n", + proc->pid, thread->pid); + return; + } + death = kzalloc(sizeof(*death), GFP_KERNEL); + if (death == NULL) { + thread->return_error = BR_ERROR; + binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, + "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", + proc->pid, thread->pid); + return; + } + 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; + if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { + list_add_tail(&ref->death->work.entry, &thread->todo); + } else { + list_add_tail(&ref->death->work.entry, &proc->todo); + wake_up_interruptible(&proc->wait); + } + } + } else { + if (ref->death == NULL) { + binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active\n", + proc->pid, thread->pid); + return; + } + death = ref->death; + if (death->cookie != cookie) { + binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %p != %p\n", + proc->pid, thread->pid, + death->cookie, cookie); + return; + } + ref->death = NULL; + if (list_empty(&death->work.entry)) { + death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; + if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { + list_add_tail(&death->work.entry, &thread->todo); + } else { + list_add_tail(&death->work.entry, &proc->todo); + wake_up_interruptible(&proc->wait); + } + } else { + BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); + death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; + } + } + return; +} + +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); + if (tmp_death->cookie == cookie) { + death = tmp_death; + return; + } + } + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "%d:%d BC_DEAD_BINDER_DONE %p found %p\n", + proc->pid, thread->pid, cookie, death); + if (death == NULL) { + binder_user_error("%d:%d BC_DEAD_BINDER_DONE %p not found\n", + proc->pid, thread->pid, cookie); + return; + } + + list_del_init(&death->work.entry); + if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { + death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; + if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { + list_add_tail(&death->work.entry, &thread->todo); + } else { + list_add_tail(&death->work.entry, &proc->todo); + wake_up_interruptible(&proc->wait); + } + } + return; +} + +static int binder_thread_write(struct binder_proc *proc, + struct binder_thread *thread, void __user *buffer, size_t size, size_t *consumed) { uint32_t cmd; @@ -1791,8 +2003,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, case BC_INCREFS_DONE: case BC_ACQUIRE_DONE: { void __user *node_ptr; - void *cookie; - struct binder_node *node; + void __user *cookie; if (get_user(node_ptr, (void * __user *)ptr)) return -EFAULT; @@ -1800,48 +2011,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, if (get_user(cookie, (void * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); - 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); - break; - } - 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); - break; - } - 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); - break; - } - 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); - break; - } - 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); + bc_increfs_done(proc, thread, cmd, node_ptr, cookie); break; } case BC_ATTEMPT_ACQUIRE: @@ -1853,42 +2023,11 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, case BC_FREE_BUFFER: { void __user *data_ptr; - struct binder_buffer *buffer; if (get_user(data_ptr, (void * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); - - 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); - 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); - 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, - 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); + bc_free_buffer(proc, thread, data_ptr); break; } @@ -1943,8 +2082,6 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, case BC_CLEAR_DEATH_NOTIFICATION: { uint32_t target; void __user *cookie; - struct binder_ref *ref; - struct binder_ref_death *death; if (get_user(target, (uint32_t __user *)ptr)) return -EFAULT; @@ -1952,117 +2089,18 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, if (get_user(cookie, (void __user * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); - ref = binder_get_ref(proc, target); - if (ref == NULL) { - binder_user_error("%d:%d %s invalid ref %d\n", - proc->pid, thread->pid, - cmd == BC_REQUEST_DEATH_NOTIFICATION ? - "BC_REQUEST_DEATH_NOTIFICATION" : - "BC_CLEAR_DEATH_NOTIFICATION", - target); - break; - } - - 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 ? - "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 (ref->death) { - binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set\n", - proc->pid, thread->pid); - break; - } - death = kzalloc(sizeof(*death), GFP_KERNEL); - if (death == NULL) { - thread->return_error = BR_ERROR; - binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", - proc->pid, thread->pid); - 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; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&ref->death->work.entry, &thread->todo); - } else { - list_add_tail(&ref->death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } else { - if (ref->death == NULL) { - binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active\n", - proc->pid, thread->pid); - break; - } - death = ref->death; - if (death->cookie != cookie) { - binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %p != %p\n", - proc->pid, thread->pid, - death->cookie, cookie); - break; - } - ref->death = NULL; - if (list_empty(&death->work.entry)) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } else { - BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); - death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; - } - } - } break; + bc_clear_death_notif(proc, thread, cmd, target, cookie); + break; + } case BC_DEAD_BINDER_DONE: { - struct binder_work *w; void __user *cookie; - struct binder_ref_death *death = NULL; + if (get_user(cookie, (void __user * __user *)ptr)) return -EFAULT; - ptr += sizeof(void *); - list_for_each_entry(w, &proc->delivered_death, entry) { - struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work); - if (tmp_death->cookie == cookie) { - death = tmp_death; - break; - } - } - binder_debug(BINDER_DEBUG_DEAD_BINDER, - "%d:%d BC_DEAD_BINDER_DONE %p found %p\n", - proc->pid, thread->pid, cookie, death); - if (death == NULL) { - binder_user_error("%d:%d BC_DEAD_BINDER_DONE %p not found\n", - proc->pid, thread->pid, cookie); - break; - } - - list_del_init(&death->work.entry); - if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { - death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; - if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { - list_add_tail(&death->work.entry, &thread->todo); - } else { - list_add_tail(&death->work.entry, &proc->todo); - wake_up_interruptible(&proc->wait); - } - } - } break; - + bc_dead_binder_done(proc, thread, cookie); + break; + } default: pr_err("%d:%d unknown command %d\n", proc->pid, thread->pid, cmd); -- cgit v1.2.3 From 8b88117ca6327329e7e0880ef854e6ade9d7b605 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:34 +0000 Subject: staging: android: binder: Add binder_copy_to_user() 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 Signed-off-by: John Stultz --- 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 1b9ebe6577f..7d6f0b150e4 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -2135,6 +2135,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, @@ -2281,15 +2293,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, @@ -2324,12 +2333,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", @@ -2391,12 +2398,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); -- cgit v1.2.3 From d1b83dd27f1ec80da678d2db00a54ff07de9a5fd Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:35 +0000 Subject: staging: android: binder: Add cmd == CMD_NAME handling 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 Signed-off-by: John Stultz --- 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 7d6f0b150e4..392283d4b21 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1719,7 +1719,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; @@ -1728,22 +1728,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, @@ -1760,13 +1760,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; @@ -1811,7 +1811,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; @@ -1821,7 +1821,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); @@ -1831,13 +1831,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); @@ -2011,7 +2011,7 @@ static int binder_thread_write(struct binder_proc *proc, if (get_user(cookie, (void * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); - bc_increfs_done(proc, thread, cmd, node_ptr, cookie); + bc_increfs_done(proc, thread, cmd == BC_ACQUIRE_DONE, node_ptr, cookie); break; } case BC_ATTEMPT_ACQUIRE: @@ -2089,7 +2089,8 @@ static int binder_thread_write(struct binder_proc *proc, if (get_user(cookie, (void __user * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); - bc_clear_death_notif(proc, thread, cmd, target, cookie); + bc_clear_death_notif(proc, thread, cmd == BC_REQUEST_DEATH_NOTIFICATION, + target, cookie); break; } case BC_DEAD_BINDER_DONE: { -- cgit v1.2.3 From a4cffaa5e848445430acc0a51e843f6209b8cda2 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:36 +0000 Subject: staging: android: binder: Add align_helper() macro 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 Signed-off-by: John Stultz --- 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 392283d4b21..8a4e252ece9 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -141,6 +141,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, @@ -1240,7 +1242,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 @@ -1477,7 +1479,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", @@ -2396,8 +2398,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; -- cgit v1.2.3 From 98e77a8deabe744d3754f28f54e435d72407b8a9 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:37 +0000 Subject: staging: android: binder: Add deref_helper() macro 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 Signed-off-by: John Stultz --- 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 8a4e252ece9..38d47f1fee3 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, } 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, @@ -1231,7 +1232,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, @@ -1247,16 +1248,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: { @@ -1306,7 +1307,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; @@ -1500,17 +1501,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: { -- cgit v1.2.3 From 63efce4893bc25a6db91bb363f0fa30a2af8d149 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:38 +0000 Subject: staging: android: binder: Add size_helper() macro 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 Signed-off-by: John Stultz --- 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 38d47f1fee3..6dd58a22836 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -143,6 +143,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, @@ -1248,10 +1249,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); @@ -1494,17 +1495,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)); @@ -2247,7 +2248,7 @@ retry: break; } - if (end - ptr < sizeof(tr) + 4) + if (end - ptr < size_helper(tr) + 4) break; switch (w->type) { -- cgit v1.2.3 From 46bd93ed20f4b4f1ae743f46a458b6d8eb10f2b0 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:39 +0000 Subject: staging: android: binder: Add copy_flat_binder_object() 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 Signed-off-by: John Stultz --- 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 6dd58a22836..16ce8f4e5ed 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -145,6 +145,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, @@ -1258,7 +1263,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: { @@ -1512,7 +1517,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: { -- cgit v1.2.3 From 42aea61e29f2c76517be8867b0209fdd9ea2a660 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:40 +0000 Subject: staging: android: binder: Add binder compat handling to binder.h 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 Signed-off-by: John Stultz --- drivers/staging/android/uapi/binder.h | 109 ++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index 008722a249b..384658ac1bb 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -21,6 +21,9 @@ #define _UAPI_LINUX_BINDER_H #include +#ifdef CONFIG_COMPAT +#include +#endif #define B_PACK_CHARS(c1, c2, c3, c4) \ ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) @@ -331,5 +334,111 @@ 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; + __u8 buf[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', 16, compat_uptr_t), +}; +#endif /* CONFIG_COMPAT */ + + #endif /* _UAPI_LINUX_BINDER_H */ -- cgit v1.2.3 From 754af9a1d3f81e8e17dd47be81c673abc681fbe0 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 12 Jun 2013 16:28:04 +0100 Subject: arm64: mm: permit use of tagged pointers at EL0 TCR.TBI0 can be used to cause hardware address translation to ignore the top byte of userspace virtual addresses. Whilst not especially useful in standard C programs, this can be used by JITs to `tag' pointers with various pieces of metadata. This patch enables this bit for AArch64 Linux, and adds a new file to Documentation/arm64/ which describes some potential caveats when using tagged virtual addresses. Change-Id: I4c025d026144c69a2259b6562e46176f95b4e110 Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- Documentation/arm64/tagged-pointers.txt | 34 +++++++++++++++++++++++++++++++++ arch/arm64/include/asm/pgtable-hwdef.h | 1 + arch/arm64/kernel/entry.S | 1 + arch/arm64/mm/proc.S | 2 +- 4 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 Documentation/arm64/tagged-pointers.txt diff --git a/Documentation/arm64/tagged-pointers.txt b/Documentation/arm64/tagged-pointers.txt new file mode 100644 index 00000000000..264e9841563 --- /dev/null +++ b/Documentation/arm64/tagged-pointers.txt @@ -0,0 +1,34 @@ + Tagged virtual addresses in AArch64 Linux + ========================================= + +Author: Will Deacon +Date : 12 June 2013 + +This document briefly describes the provision of tagged virtual +addresses in the AArch64 translation system and their potential uses +in AArch64 Linux. + +The kernel configures the translation tables so that translations made +via TTBR0 (i.e. userspace mappings) have the top byte (bits 63:56) of +the virtual address ignored by the translation hardware. This frees up +this byte for application use, with the following caveats: + + (1) The kernel requires that all user addresses passed to EL1 + are tagged with tag 0x00. This means that any syscall + parameters containing user virtual addresses *must* have + their top byte cleared before trapping to the kernel. + + (2) Tags are not guaranteed to be preserved when delivering + signals. This means that signal handlers in applications + making use of tags cannot rely on the tag information for + user virtual addresses being maintained for fields inside + siginfo_t. One exception to this rule is for signals raised + in response to debug exceptions, where the tag information + will be preserved. + + (3) Special care should be taken when using tagged pointers, + since it is likely that C compilers will not hazard two + addresses differing only in the upper bits. + +The architecture prevents the use of a tagged PC, so the upper byte will +be set to a sign-extension of bit 55 on exception return. diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 75fd13d289b..7eeed1ae2c5 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -92,5 +92,6 @@ #define TCR_TG1_64K (UL(1) << 30) #define TCR_IPS_40BIT (UL(2) << 32) #define TCR_ASID16 (UL(1) << 36) +#define TCR_TBI0 (UL(1) << 37) #endif diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 1d1314280a0..1146e6f40a6 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -423,6 +423,7 @@ el0_da: * Data abort handling */ mrs x0, far_el1 + bic x0, x0, #(0xff << 56) disable_step x1 isb enable_dbg diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index a82ae886807..9428de8a8f3 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -151,7 +151,7 @@ ENTRY(__cpu_setup) * both user and kernel. */ ldr x10, =TCR_TxSZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT | \ - TCR_ASID16 | (1 << 31) + TCR_ASID16 | TCR_TBI0 | (1 << 31) #ifdef CONFIG_ARM64_64K_PAGES orr x10, x10, TCR_TG0_64K orr x10, x10, TCR_TG1_64K -- cgit v1.2.3 From 7a18e70688223a37ba4c8cf5edd313e8d1bb680d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 17 Sep 2013 11:46:23 +0100 Subject: arm64: documentation: tighten up tagged pointer documentation Commit d50240a5f6ce ("arm64: mm: permit use of tagged pointers at EL0") added support for tagged pointers in userspace, but the corresponding update to Documentation/ contained some imprecise statements. This patch fixes up some minor ambiguities in the text, hopefully making it more clear about exactly what the kernel expects from user virtual addresses. Change-Id: I7df342e01d5253ccacb3847449940892768d7e07 Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- Documentation/arm64/tagged-pointers.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/arm64/tagged-pointers.txt b/Documentation/arm64/tagged-pointers.txt index 264e9841563..d9995f1f51b 100644 --- a/Documentation/arm64/tagged-pointers.txt +++ b/Documentation/arm64/tagged-pointers.txt @@ -18,17 +18,17 @@ this byte for application use, with the following caveats: parameters containing user virtual addresses *must* have their top byte cleared before trapping to the kernel. - (2) Tags are not guaranteed to be preserved when delivering - signals. This means that signal handlers in applications - making use of tags cannot rely on the tag information for - user virtual addresses being maintained for fields inside - siginfo_t. One exception to this rule is for signals raised - in response to debug exceptions, where the tag information + (2) Non-zero tags are not preserved when delivering signals. + This means that signal handlers in applications making use + of tags cannot rely on the tag information for user virtual + addresses being maintained for fields inside siginfo_t. + One exception to this rule is for signals raised in response + to watchpoint debug exceptions, where the tag information will be preserved. (3) Special care should be taken when using tagged pointers, since it is likely that C compilers will not hazard two - addresses differing only in the upper bits. + virtual addresses differing only in the upper byte. The architecture prevents the use of a tagged PC, so the upper byte will be set to a sign-extension of bit 55 on exception return. -- cgit v1.2.3 From c10c64d40bf14ce5964300991744d17296d57481 Mon Sep 17 00:00:00 2001 From: Greg Hackmann Date: Mon, 13 Jan 2014 15:24:24 -0800 Subject: video: adf: define constants for device-custom ioctls Device-custom ADF ioctls can use type ADF_IOCTL_TYPE and nr >= ADF_IOCTL_NR_CUSTOM Change-Id: Ia8270973df5100e996ca0e021ede60e54b9af72a Signed-off-by: Greg Hackmann --- include/uapi/video/adf.h | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/include/uapi/video/adf.h b/include/uapi/video/adf.h index 38458f6428b..b703bf9e9a6 100644 --- a/include/uapi/video/adf.h +++ b/include/uapi/video/adf.h @@ -295,17 +295,27 @@ struct adf_overlay_engine_data { }; #define ADF_MAX_SUPPORTED_FORMATS (4096 / sizeof(__u32)) -#define ADF_SET_EVENT _IOW('D', 0, struct adf_set_event) -#define ADF_BLANK _IOW('D', 1, __u8) -#define ADF_POST_CONFIG _IOW('D', 2, struct adf_post_config) -#define ADF_SET_MODE _IOW('D', 3, struct drm_mode_modeinfo) -#define ADF_GET_DEVICE_DATA _IOR('D', 4, struct adf_device_data) -#define ADF_GET_INTERFACE_DATA _IOR('D', 5, struct adf_interface_data) +#define ADF_IOCTL_TYPE 'D' +#define ADF_IOCTL_NR_CUSTOM 128 + +#define ADF_SET_EVENT _IOW(ADF_IOCTL_TYPE, 0, struct adf_set_event) +#define ADF_BLANK _IOW(ADF_IOCTL_TYPE, 1, __u8) +#define ADF_POST_CONFIG _IOW(ADF_IOCTL_TYPE, 2, struct adf_post_config) +#define ADF_SET_MODE _IOW(ADF_IOCTL_TYPE, 3, \ + struct drm_mode_modeinfo) +#define ADF_GET_DEVICE_DATA _IOR(ADF_IOCTL_TYPE, 4, struct adf_device_data) +#define ADF_GET_INTERFACE_DATA _IOR(ADF_IOCTL_TYPE, 5, \ + struct adf_interface_data) #define ADF_GET_OVERLAY_ENGINE_DATA \ - _IOR('D', 6, struct adf_overlay_engine_data) -#define ADF_SIMPLE_POST_CONFIG _IOW('D', 7, struct adf_simple_post_config) -#define ADF_SIMPLE_BUFFER_ALLOC _IOW('D', 8, struct adf_simple_buffer_alloc) -#define ADF_ATTACH _IOW('D', 9, struct adf_attachment_config) -#define ADF_DETACH _IOW('D', 10, struct adf_attachment_config) + _IOR(ADF_IOCTL_TYPE, 6, \ + struct adf_overlay_engine_data) +#define ADF_SIMPLE_POST_CONFIG _IOW(ADF_IOCTL_TYPE, 7, \ + struct adf_simple_post_config) +#define ADF_SIMPLE_BUFFER_ALLOC _IOW(ADF_IOCTL_TYPE, 8, \ + struct adf_simple_buffer_alloc) +#define ADF_ATTACH _IOW(ADF_IOCTL_TYPE, 9, \ + struct adf_attachment_config) +#define ADF_DETACH _IOW(ADF_IOCTL_TYPE, 10, \ + struct adf_attachment_config) #endif /* _UAPI_VIDEO_ADF_H_ */ -- cgit v1.2.3 From 0ac276ebfca1d405153f4a3476aa1f7f66bbbec8 Mon Sep 17 00:00:00 2001 From: Minsung Kim Date: Sun, 19 Jan 2014 14:32:42 +0900 Subject: cpufreq: interactive: fix NULL pointer dereference at sysfs ops sysfs ops for target_loads and above_hispeed_delay can be called before initializing tunables at CPUFREQ_GOV_POLICY_INIT. Create sysfs entries after initialization. Change-Id: I50356198d7629731c0d32a3066d61fe8354e0001 Signed-off-by: Minsung Kim --- drivers/cpufreq/cpufreq_interactive.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c index 9f63bd1e4fe..8297ac69863 100644 --- a/drivers/cpufreq/cpufreq_interactive.c +++ b/drivers/cpufreq/cpufreq_interactive.c @@ -1178,13 +1178,6 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, return -ENOMEM; } - rc = sysfs_create_group(get_governor_parent_kobj(policy), - get_sysfs_attr()); - if (rc) { - kfree(tunables); - return rc; - } - tunables->usage_count = 1; tunables->above_hispeed_delay = default_above_hispeed_delay; tunables->nabove_hispeed_delay = @@ -1200,16 +1193,26 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy, spin_lock_init(&tunables->target_loads_lock); spin_lock_init(&tunables->above_hispeed_delay_lock); + policy->governor_data = tunables; + if (!have_governor_per_policy()) + common_tunables = tunables; + + rc = sysfs_create_group(get_governor_parent_kobj(policy), + get_sysfs_attr()); + if (rc) { + kfree(tunables); + policy->governor_data = NULL; + if (!have_governor_per_policy()) + common_tunables = NULL; + return rc; + } + if (!policy->governor->initialized) { idle_notifier_register(&cpufreq_interactive_idle_nb); cpufreq_register_notifier(&cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); } - policy->governor_data = tunables; - if (!have_governor_per_policy()) - common_tunables = tunables; - break; case CPUFREQ_GOV_POLICY_EXIT: -- cgit v1.2.3 From 46650262c2342eab6ef01b382741df2d89688ab3 Mon Sep 17 00:00:00 2001 From: Serban Constantinescu Date: Wed, 4 Dec 2013 18:09:41 +0000 Subject: staging: android: binder: Add binder compat layer 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 Signed-off-by: John Stultz --- 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 16ce8f4e5ed..65dd819d41a 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "binder.h" #include "binder_trace.h" @@ -141,6 +142,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) @@ -149,6 +221,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, @@ -1255,7 +1328,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))) { @@ -1304,6 +1377,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, debug_id, fp->type); break; } + if (is_compat_task()) + kfree(fp); } } @@ -1322,6 +1397,7 @@ static void binder_transaction(struct binder_proc *proc, struct binder_transaction *in_reply_to = NULL; struct binder_transaction_log_entry *e; uint32_t return_error; + struct flat_binder_object *fp = NULL; e = binder_transaction_log_add(&binder_transaction_log); e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); @@ -1508,7 +1584,6 @@ static void binder_transaction(struct binder_proc *proc, } off_end = (void *)offp + tr->offsets_size; for (; offp < off_end; offp += size_helper(size_t)) { - struct flat_binder_object *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))) { @@ -1657,6 +1732,12 @@ static void binder_transaction(struct binder_proc *proc, return_error = BR_FAILED_REPLY; goto err_bad_object_type; } +#ifdef CONFIG_COMPAT + if (is_compat_task()) { + writeback_flat_binder_object(fp, t->buffer->data + deref_helper(offp)); + kfree(fp); + } +#endif } if (reply) { BUG_ON(t->buffer->async_transaction != 0); @@ -1692,6 +1773,8 @@ err_binder_new_node_failed: err_bad_object_type: err_bad_offset: err_copy_data_failed: + if (is_compat_task()) + kfree(fp); trace_binder_transaction_failed_buffer_release(t->buffer); binder_transaction_buffer_release(target_proc, t->buffer, offp); t->buffer->transaction = NULL; @@ -1938,6 +2021,95 @@ static void bc_dead_binder_done(struct binder_proc *proc, return; } +#ifdef CONFIG_COMPAT +static int compat_binder_thread_write(struct binder_proc *proc, + struct binder_thread *thread, uint32_t cmd, + void __user **ptr) +{ + BUG_ON(!is_compat_task()); + switch (cmd) { + 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; + } + + case COMPAT_BC_FREE_BUFFER: { + compat_uptr_t data_ptr; + + if (get_user(data_ptr, (compat_uptr_t __user *)*ptr)) + return -EFAULT; + *ptr += sizeof(compat_uptr_t); + bc_free_buffer(proc, thread, compat_ptr(data_ptr)); + break; + } + + case COMPAT_BC_TRANSACTION: + case COMPAT_BC_REPLY: { + struct binder_transaction_data tr; + struct compat_binder_transaction_data tmp_tr; + + if (copy_from_user(&tmp_tr, *ptr, sizeof(tmp_tr))) + return -EFAULT; + *ptr += sizeof(tmp_tr); + + memset(&tr, 0, sizeof(tr)); + /* copy from compat struct */ + tr.target.ptr = compat_ptr(tmp_tr.target.ptr); + tr.cookie = compat_ptr(tmp_tr.cookie); + tr.code = tmp_tr.code; + tr.flags = tmp_tr.flags; + tr.sender_pid = tmp_tr.sender_pid; + tr.sender_euid = tmp_tr.sender_euid; + tr.data_size = (size_t) tmp_tr.data_size; + tr.offsets_size = (size_t) tmp_tr.offsets_size; + tr.data.ptr.buffer = compat_ptr(tmp_tr.data.ptr.buffer); + tr.data.ptr.offsets = compat_ptr(tmp_tr.data.ptr.offsets); + + binder_transaction(proc, thread, &tr, cmd == COMPAT_BC_REPLY); + break; + } + case COMPAT_BC_REQUEST_DEATH_NOTIFICATION: + case COMPAT_BC_CLEAR_DEATH_NOTIFICATION: { + uint32_t target; + compat_uptr_t cookie; + + if (get_user(target, (uint32_t __user *)*ptr)) + return -EFAULT; + *ptr += sizeof(uint32_t); + if (get_user(cookie, (compat_uptr_t __user *)*ptr)) + return -EFAULT; + *ptr += sizeof(compat_uptr_t); + bc_clear_death_notif(proc, thread, cmd == COMPAT_BC_REQUEST_DEATH_NOTIFICATION, + target, compat_ptr(cookie)); + break; + } + case COMPAT_BC_DEAD_BINDER_DONE: { + compat_uptr_t cookie; + + if (get_user(cookie, (compat_uptr_t __user *)*ptr)) + return -EFAULT; + *ptr += sizeof(compat_uptr_t); + bc_dead_binder_done(proc, thread, compat_ptr(cookie)); + break; + } + default: + return -EINVAL; + } + return 0; +} +#endif + static int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, void __user *buffer, size_t size, size_t *consumed) @@ -2112,6 +2284,10 @@ static int binder_thread_write(struct binder_proc *proc, break; } default: +#ifdef CONFIG_COMPAT + if (is_compat_task() && (!compat_binder_thread_write(proc, thread, cmd, &ptr))) + break; +#endif pr_err("%d:%d unknown command %d\n", proc->pid, thread->pid, cmd); return -EINVAL; @@ -2145,6 +2321,103 @@ static int binder_has_thread_work(struct binder_thread *thread) (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); } +#ifdef CONFIG_COMPAT +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)); + 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); + + break; + } + case BR_DEAD_BINDER: + case BR_CLEAR_DEATH_NOTIFICATION_DONE: { + compat_uptr_t tmp; + + cmd = compat_change_size(cmd, sizeof(tmp)); + BUG_ON((cmd != COMPAT_BR_DEAD_BINDER) && + (cmd != COMPAT_BR_CLEAR_DEATH_NOTIFICATION_DONE)); + + tmp = ptr_to_compat((void *)*(uintptr_t *) parcel); + 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); + + break; + } + case BR_REPLY: + case BR_TRANSACTION: { + struct binder_transaction_data *fp; + struct compat_binder_transaction_data tmp; + + memset(&tmp, 0, sizeof(tmp)); + cmd = compat_change_size(cmd, sizeof(tmp)); + BUG_ON((cmd != COMPAT_BR_REPLY) && + (cmd != COMPAT_BR_TRANSACTION)); + + fp = (struct binder_transaction_data *) parcel; + /* copy to compat struct */ + tmp.target.ptr = ptr_to_compat(fp->target.ptr); + tmp.cookie = ptr_to_compat(fp->cookie); + tmp.code = fp->code; + tmp.flags = fp->flags; + tmp.sender_pid = fp->sender_pid; + tmp.sender_euid = fp->sender_euid; + tmp.data_size = (compat_size_t) fp->data_size; + tmp.offsets_size = (compat_size_t) fp->offsets_size; + tmp.data.ptr.buffer = ptr_to_compat((void *)fp->data.ptr.buffer); + tmp.data.ptr.offsets = ptr_to_compat((void *)fp->data.ptr.offsets); + + 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); + + break; + } + default: + pr_err("unexpected user copy, cmd %d, ptr %p\n", + cmd, (void *)*(uintptr_t *)ptr); + return -EFAULT; + } + return 0; +} +#else static int binder_copy_to_user(uint32_t cmd, void *parcel, void __user **ptr, size_t size) { @@ -2156,6 +2429,7 @@ static int binder_copy_to_user(uint32_t cmd, void *parcel, *ptr += size; return 0; } +#endif static int binder_thread_read(struct binder_proc *proc, struct binder_thread *thread, @@ -2750,6 +3024,80 @@ err_unlocked: return ret; } +/* TODO: add tracepoint */ +#ifdef CONFIG_COMPAT +static long compat_binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int ret = 0; + struct binder_thread *thread; + struct compat_binder_write_read bwr; + struct binder_proc *proc = filp->private_data; + void __user *ubuf = compat_ptr(arg); + + /* pr_info("compat_binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg); */ + + if (cmd != COMPAT_BINDER_WRITE_READ) + return binder_ioctl(filp, cmd, arg); + + BUG_ON(!is_compat_task()); + binder_lock(__func__); + thread = binder_get_thread(proc); + if (thread == NULL) { + ret = -ENOMEM; + goto err; + } + + /* COMPAT_BINDER_WRITE_READ */ + if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { + ret = -EFAULT; + goto err; + } + binder_debug(BINDER_DEBUG_READ_WRITE, + "compat: %d:%d write %d at %016x, read %d at %016x\n", + proc->pid, thread->pid, bwr.write_size, + bwr.write_buffer, bwr.read_size, bwr.read_buffer); + + if (bwr.write_size > 0) { + size_t tmp_write_consumed = (size_t)bwr.write_consumed; + ret = binder_thread_write(proc, thread, compat_ptr(bwr.write_buffer), (size_t)bwr.write_size, &tmp_write_consumed); + bwr.write_consumed = (compat_size_t)tmp_write_consumed; + if (ret < 0) { + bwr.read_consumed = 0; + if (copy_to_user(ubuf, &bwr, sizeof(bwr))) + ret = -EFAULT; + goto err; + } + } + + if (bwr.read_size > 0) { + size_t tmp_read_consumed = (size_t)bwr.read_consumed; + ret = binder_thread_read(proc, thread, compat_ptr(bwr.read_buffer), (size_t)bwr.read_size, &tmp_read_consumed, filp->f_flags & O_NONBLOCK); + bwr.read_consumed = (compat_size_t)tmp_read_consumed; + if (!list_empty(&proc->todo)) + wake_up_interruptible(&proc->wait); + if (ret < 0) { + if (copy_to_user(ubuf, &bwr, sizeof(bwr))) + ret = -EFAULT; + goto err; + } + } + binder_debug(BINDER_DEBUG_READ_WRITE, + "compat: %d:%d wrote %d of %d, read return %d of %d\n", + proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, + bwr.read_consumed, bwr.read_size); + if (copy_to_user(ubuf, &bwr, sizeof(bwr))) + ret = -EFAULT; + +err: + if (thread) + thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; + binder_unlock(__func__); + if (ret && ret != -ERESTARTSYS) + pr_info("%d:%d compat ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); + return ret; +} +#endif + static void binder_vma_open(struct vm_area_struct *vma) { struct binder_proc *proc = vma->vm_private_data; @@ -3567,6 +3915,9 @@ static const struct file_operations binder_fops = { .owner = THIS_MODULE, .poll = binder_poll, .unlocked_ioctl = binder_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = compat_binder_ioctl, +#endif .mmap = binder_mmap, .open = binder_open, .flush = binder_flush, -- cgit v1.2.3 From f024263397cfaca5e2e97a27d9db424a42432eaf Mon Sep 17 00:00:00 2001 From: Ashish Sharma Date: Wed, 15 Jan 2014 16:47:16 -0800 Subject: android: configs: Add CONFIG_NETFILTER_XT_TARGET_IDLETIMER Signed-off-by: Ashish Sharma (cherry picked from commit 5621df1091c7e103bca6cdd1dbecf4333efad4e7) Change-Id: I3104266fa648fc024fee45f1ce9800142898baf7 --- android/configs/android-base.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index 1fb9bb5b1ac..6b67601b7f1 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -83,6 +83,7 @@ CONFIG_NETFILTER_XT_MATCH_TIME=y CONFIG_NETFILTER_XT_MATCH_U32=y CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y CONFIG_NETFILTER_XT_TARGET_MARK=y CONFIG_NETFILTER_XT_TARGET_NFLOG=y CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -- cgit v1.2.3 From da8a3700249608e24c3910549a5045cf1908a86d Mon Sep 17 00:00:00 2001 From: Rom Lemarchand Date: Tue, 28 Jan 2014 10:23:19 -0800 Subject: android: configs: update 3.10 options Change-Id: Ifbda55e570a22ace98d7d74b057ba21a597e0826 --- android/configs/android-base.cfg | 1 - android/configs/android-recommended.cfg | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/android/configs/android-base.cfg b/android/configs/android-base.cfg index 6b67601b7f1..00c99e1f3b1 100644 --- a/android/configs/android-base.cfg +++ b/android/configs/android-base.cfg @@ -17,7 +17,6 @@ CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_SCHED=y CONFIG_DM_CRYPT=y CONFIG_EMBEDDED=y -CONFIG_EXPERIMENTAL=y CONFIG_FB=y CONFIG_HIGH_RES_TIMERS=y CONFIG_INET6_AH=y diff --git a/android/configs/android-recommended.cfg b/android/configs/android-recommended.cfg index 9caa089c5d1..aceee62a3e0 100644 --- a/android/configs/android-recommended.cfg +++ b/android/configs/android-recommended.cfg @@ -5,7 +5,6 @@ # CONFIG_NF_CONNTRACK_SIP is not set # CONFIG_PM_WAKELOCKS_GC is not set # CONFIG_VT is not set -CONFIG_ANDROID_RAM_CONSOLE=y CONFIG_ANDROID_TIMED_GPIO=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BLK_DEV_LOOP=y @@ -95,6 +94,9 @@ CONFIG_PM_DEBUG=y CONFIG_PM_RUNTIME=y CONFIG_PM_WAKELOCKS_LIMIT=0 CONFIG_POWER_SUPPLY=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y CONFIG_SCHEDSTATS=y CONFIG_SMARTJOYPLUS_FF=y CONFIG_SND=y -- cgit v1.2.3 From 233fd81496ca2cb483f3987b5753b71d7071531a Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Tue, 28 Jan 2014 15:39:48 -0800 Subject: ion: Fix ION_IOC_FREE compat ioctl The compat ioctl for ION_IOC_FREE currently passes allocation data instead of the free data. Correct this. Change-Id: I5108a1937104b8368426f7695b4a2df416036a87 Signed-off-by: Laura Abbott --- drivers/staging/android/ion/compat_ion.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index e9a8132cd56..fb0ebddbba2 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -35,9 +35,14 @@ struct compat_ion_custom_data { compat_ulong_t arg; }; +struct compat_ion_handle_data { + compat_int_t handle; +}; + #define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ struct compat_ion_allocation_data) -#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, \ + struct compat_ion_handle_data) #define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ struct compat_ion_custom_data) @@ -64,6 +69,18 @@ static int compat_get_ion_allocation_data( return err; } +static int compat_get_ion_handle_data( + struct compat_ion_handle_data __user *data32, + struct ion_handle_data __user *data) +{ + compat_int_t i; + + err = get_user(i, &data32->handle); + err |= put_user(i, &data->handle); + + return err; +} + static int compat_put_ion_allocation_data( struct compat_ion_allocation_data __user *data32, struct ion_allocation_data __user *data) @@ -132,8 +149,8 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } case COMPAT_ION_IOC_FREE: { - struct compat_ion_allocation_data __user *data32; - struct ion_allocation_data __user *data; + struct compat_ion_handle_data __user *data32; + struct ion_handle_data __user *data; int err; data32 = compat_ptr(arg); @@ -141,7 +158,7 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (data == NULL) return -EFAULT; - err = compat_get_ion_allocation_data(data32, data); + err = compat_get_ion_handle_data(data32, data); if (err) return err; -- cgit v1.2.3 From d4e564429cb89a90b9d5482af884b0b6a85aa284 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 29 Jan 2014 13:00:51 -0800 Subject: staging: ion: Build fix for compat_ion.c compat_get_ion_handle_data is missing a declaration for the return value. This patch simply adds it, so things build. Change-Id: I1a72a3c56975dc614322a63852f2a6554f2be107 Signed-off-by: John Stultz --- drivers/staging/android/ion/compat_ion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c index fb0ebddbba2..a5e8c408fd7 100644 --- a/drivers/staging/android/ion/compat_ion.c +++ b/drivers/staging/android/ion/compat_ion.c @@ -74,6 +74,7 @@ static int compat_get_ion_handle_data( struct ion_handle_data __user *data) { compat_int_t i; + int err; err = get_user(i, &data32->handle); err |= put_user(i, &data->handle); -- cgit v1.2.3 From 6e23832c042e05fcc25f9d26e7e3f7959cce7c54 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 31 Jan 2014 11:22:18 -0800 Subject: Fix aarch64 build issue with ION In trying to build ION for aarch64, I came across the following build error: In file included from /home/jstultz/projects/linux/linaro.android/arch/arm64/include/asm/page.h:39:0, from drivers/staging/android/ion/ion_system_heap.c:17: /home/jstultz/projects/linux/linaro.android/arch/arm64/include/asm/pgtable-3level-types.h:19:1: error: unknown type name u64 typedef u64 pteval_t; ^ /home/jstultz/projects/linux/linaro.android/arch/arm64/include/asm/pgtable-3level-types.h:20:1: error: unknown type name u64 typedef u64 pmdval_t; ^ ... The problem is asm/page.h doesn't include anything that defines u64, so add an asm/types.h include to the pgtable-3level-types.h to match upstream and avoid the issue. Change-Id: I23f6d2e909cb4de1f9b4f21eb20f9200367faddd Signed-off-by: John Stultz --- arch/arm64/include/asm/pgtable-3level-types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/include/asm/pgtable-3level-types.h b/arch/arm64/include/asm/pgtable-3level-types.h index 4489615f14a..4e94424938a 100644 --- a/arch/arm64/include/asm/pgtable-3level-types.h +++ b/arch/arm64/include/asm/pgtable-3level-types.h @@ -16,6 +16,8 @@ #ifndef __ASM_PGTABLE_3LEVEL_TYPES_H #define __ASM_PGTABLE_3LEVEL_TYPES_H +#include + typedef u64 pteval_t; typedef u64 pmdval_t; typedef u64 pgdval_t; -- cgit v1.2.3