From de5cc248096f1b2b0c2adc56e5f8972de138d6cc Mon Sep 17 00:00:00 2001 From: Patrick Tjin Date: Mon, 22 Aug 2016 09:01:25 -0700 Subject: Branch kernel for NDR Factory ROM Change-Id: I7f71f70489b2d5c7b9a96ca1cb20bbcc86d96b3a --- build.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.config b/build.config index 9e0c69fe0c4f..230bfd14cafd 100644 --- a/build.config +++ b/build.config @@ -1,5 +1,5 @@ ARCH=arm64 -BRANCH=android-msm-marlin-3.18 +BRANCH=android-msm-marlin-3.18-ndr-factoryrom CROSS_COMPILE=aarch64-linux-android- DEFCONFIG=marlin_defconfig EXTRA_CMDS='' -- cgit v1.2.3 From 502298e0050705dd3f3d65f58dbd00a998f27a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 2 Aug 2016 15:40:39 -0700 Subject: ANDROID: binder: Add strong ref checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent using a binder_ref with only weak references where a strong reference is required. BUG: 30445380 Change-Id: I66c15b066808f28bd27bfe50fd0e03ff45a09fca Signed-off-by: Arve Hjønnevåg --- drivers/staging/android/binder.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index f7fb2b3ad3bd..d08a7fcb1b82 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1069,7 +1069,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal) static struct binder_ref *binder_get_ref(struct binder_proc *proc, - uint32_t desc) + uint32_t desc, bool need_strong_ref) { struct rb_node *n = proc->refs_by_desc.rb_node; struct binder_ref *ref; @@ -1077,12 +1077,16 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc, while (n) { ref = rb_entry(n, struct binder_ref, rb_node_desc); - if (desc < ref->desc) + if (desc < ref->desc) { n = n->rb_left; - else if (desc > ref->desc) + } else if (desc > ref->desc) { n = n->rb_right; - else + } else if (need_strong_ref && !ref->strong) { + binder_user_error("tried to use weak ref as strong ref\n"); + return NULL; + } else { return ref; + } } return NULL; } @@ -1352,7 +1356,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, } break; case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); + struct binder_ref *ref = binder_get_ref(proc, fp->handle, + fp->type == BINDER_TYPE_HANDLE); if (ref == NULL) { pr_err("transaction release %d bad handle %d\n", @@ -1447,7 +1452,7 @@ static void binder_transaction(struct binder_proc *proc, if (tr->target.handle) { struct binder_ref *ref; - ref = binder_get_ref(proc, tr->target.handle); + ref = binder_get_ref(proc, tr->target.handle, true); if (ref == NULL) { binder_user_error("%d:%d got transaction to invalid handle\n", proc->pid, thread->pid); @@ -1654,7 +1659,8 @@ static void binder_transaction(struct binder_proc *proc, } break; case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { - struct binder_ref *ref = binder_get_ref(proc, fp->handle); + struct binder_ref *ref = binder_get_ref(proc, fp->handle, + fp->type == BINDER_TYPE_HANDLE); if (ref == NULL) { binder_user_error("%d:%d got transaction with invalid handle, %d\n", @@ -1868,7 +1874,9 @@ static int binder_thread_write(struct binder_proc *proc, ref->desc); } } else - ref = binder_get_ref(proc, target); + ref = binder_get_ref(proc, target, + cmd == BC_ACQUIRE || + cmd == BC_RELEASE); if (ref == NULL) { binder_user_error("%d:%d refcount change on invalid ref %d\n", proc->pid, thread->pid, target); @@ -2064,7 +2072,7 @@ static int binder_thread_write(struct binder_proc *proc, if (get_user_preempt_disabled(cookie, (binder_uintptr_t __user *)ptr)) return -EFAULT; ptr += sizeof(binder_uintptr_t); - ref = binder_get_ref(proc, target); + ref = binder_get_ref(proc, target, false); if (ref == NULL) { binder_user_error("%d:%d %s invalid ref %d\n", proc->pid, thread->pid, -- cgit v1.2.3 From 0e703cfaa8d16e93c1732be1abfb05df5db41704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Fri, 12 Aug 2016 16:04:28 -0700 Subject: ANDROID: binder: Clear binder and cookie when setting handle in flat binder struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevents leaking pointers between processes BUG: 30768347 Change-Id: Id898076926f658a1b8b27a3ccb848756b36de4ca Signed-off-by: Arve Hjønnevåg --- drivers/staging/android/binder.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index d08a7fcb1b82..192032638f75 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -1647,7 +1647,9 @@ static void binder_transaction(struct binder_proc *proc, fp->type = BINDER_TYPE_HANDLE; else fp->type = BINDER_TYPE_WEAK_HANDLE; + fp->binder = 0; fp->handle = ref->desc; + fp->cookie = 0; binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, &thread->todo); @@ -1694,7 +1696,9 @@ static void binder_transaction(struct binder_proc *proc, return_error = BR_FAILED_REPLY; goto err_binder_get_ref_for_node_failed; } + fp->binder = 0; fp->handle = new_ref->desc; + fp->cookie = 0; binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); trace_binder_transaction_ref_to_ref(t, ref, new_ref); @@ -1746,6 +1750,7 @@ static void binder_transaction(struct binder_proc *proc, binder_debug(BINDER_DEBUG_TRANSACTION, " fd %d -> %d\n", fp->handle, target_fd); /* TODO: fput? */ + fp->binder = 0; fp->handle = target_fd; } break; -- cgit v1.2.3 From 35de94b5b694e857fd0c6df8295992465741bfee Mon Sep 17 00:00:00 2001 From: Dennis Cagle Date: Fri, 19 Aug 2016 12:11:42 -0700 Subject: msm: ipa: fix potential race condition ioctls There are potential race condition ioctls in the IPA driver when it copies the actual arguments from the user-space memory to the IPA-driver. The fix is to add check on the 2nd copy to make sure the same payload size is copied to the pre-allocated kernel memory as in during the 1st copy. Change-Id: I5a440f89153518507acdf5dad42625503732e59a Signed-off-by: Skylar Chang Signed-off-by: Dennis Cagle --- drivers/platform/msm/ipa/ipa_v2/ipa.c | 226 +++++++++++++++++++++++++----- drivers/platform/msm/ipa/ipa_v3/ipa.c | 257 +++++++++++++++++++++++++++++----- 2 files changed, 411 insertions(+), 72 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c index 6bd7218e63c8..f21c30ec2cdc 100644 --- a/drivers/platform/msm/ipa/ipa_v2/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c @@ -571,6 +571,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_v4_nat_del nat_del; struct ipa_ioc_rm_dependency rm_depend; size_t sz; + int pre_entry; IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd)); @@ -619,11 +620,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + pre_entry = + ((struct ipa_ioc_nat_dma_cmd *)header)->entries; pyld_sz = sizeof(struct ipa_ioc_nat_dma_cmd) + - ((struct ipa_ioc_nat_dma_cmd *)header)->entries * - sizeof(struct ipa_ioc_nat_dma_one); + pre_entry * sizeof(struct ipa_ioc_nat_dma_one); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -634,7 +635,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_nat_dma_cmd *)param)->entries + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_nat_dma_cmd *)param)->entries, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_nat_dma_cmd((struct ipa_ioc_nat_dma_cmd *)param)) { retval = -EFAULT; break; @@ -659,10 +668,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr *)header)->num_hdrs; pyld_sz = sizeof(struct ipa_ioc_add_hdr) + - ((struct ipa_ioc_add_hdr *)header)->num_hdrs * - sizeof(struct ipa_hdr_add); + pre_entry * sizeof(struct ipa_hdr_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -672,6 +682,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr *)param)->num_hdrs + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_hdr *)param)->num_hdrs, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_add_hdr((struct ipa_ioc_add_hdr *)param)) { retval = -EFAULT; break; @@ -688,10 +707,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr) + - ((struct ipa_ioc_del_hdr *)header)->num_hdls * - sizeof(struct ipa_hdr_del); + pre_entry * sizeof(struct ipa_hdr_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -701,6 +721,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr *)param)->num_hdls + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_hdr *)param)->num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_del_hdr((struct ipa_ioc_del_hdr *)param)) { retval = -EFAULT; break; @@ -717,10 +746,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_rt_rule) + - ((struct ipa_ioc_add_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_add); + pre_entry * sizeof(struct ipa_rt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -730,6 +760,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) { retval = -EFAULT; break; @@ -746,10 +786,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + - ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_mdfy); + pre_entry * sizeof(struct ipa_rt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -759,6 +800,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_mdfy_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_mdfy_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; @@ -775,10 +826,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_rt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_rt_rule) + - ((struct ipa_ioc_del_rt_rule *)header)->num_hdls * - sizeof(struct ipa_rt_rule_del); + pre_entry * sizeof(struct ipa_rt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -788,6 +840,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_rt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_rt_rule *)param)->num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_del_rt_rule((struct ipa_ioc_del_rt_rule *)param)) { retval = -EFAULT; break; @@ -804,10 +865,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_flt_rule) + - ((struct ipa_ioc_add_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_add); + pre_entry * sizeof(struct ipa_flt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -817,6 +879,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) { retval = -EFAULT; break; @@ -833,10 +905,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_flt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_flt_rule) + - ((struct ipa_ioc_del_flt_rule *)header)->num_hdls * - sizeof(struct ipa_flt_rule_del); + pre_entry * sizeof(struct ipa_flt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -846,6 +919,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_flt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_flt_rule *)param)-> + num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_del_flt_rule((struct ipa_ioc_del_flt_rule *)param)) { retval = -EFAULT; break; @@ -862,10 +945,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + - ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_mdfy); + pre_entry * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -875,6 +959,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_mdfy_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; @@ -988,9 +1082,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_tx_props *) - header)->num_tx_props * + pre_entry = + ((struct ipa_ioc_query_intf_tx_props *) + header)->num_tx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_tx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -1001,6 +1096,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props, pre_entry); + retval = -EINVAL; + break; + } if (ipa_query_intf_tx_props( (struct ipa_ioc_query_intf_tx_props *)param)) { retval = -1; @@ -1023,9 +1128,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_rx_props *) - header)->num_rx_props * + pre_entry = + ((struct ipa_ioc_query_intf_rx_props *) + header)->num_rx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_rx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -1036,6 +1142,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props, pre_entry); + retval = -EINVAL; + break; + } if (ipa_query_intf_rx_props( (struct ipa_ioc_query_intf_rx_props *)param)) { retval = -1; @@ -1058,9 +1173,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_ext_props *) - header)->num_ext_props * + pre_entry = + ((struct ipa_ioc_query_intf_ext_props *) + header)->num_ext_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_ext_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -1071,6 +1187,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props, pre_entry); + retval = -EINVAL; + break; + } if (ipa_query_intf_ext_props( (struct ipa_ioc_query_intf_ext_props *)param)) { retval = -1; @@ -1087,8 +1212,10 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - pyld_sz = sizeof(struct ipa_msg_meta) + + pre_entry = ((struct ipa_msg_meta *)header)->msg_len; + pyld_sz = sizeof(struct ipa_msg_meta) + + pre_entry; param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1098,6 +1225,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_msg_meta *)param)->msg_len + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_msg_meta *)param)->msg_len, + pre_entry); + retval = -EINVAL; + break; + } if (ipa_pull_msg((struct ipa_msg_meta *)param, (char *)param + sizeof(struct ipa_msg_meta), ((struct ipa_msg_meta *)param)->msg_len) != @@ -1214,10 +1350,12 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr_proc_ctx *) + header)->num_proc_ctxs; pyld_sz = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + - ((struct ipa_ioc_add_hdr_proc_ctx *)header)->num_proc_ctxs * - sizeof(struct ipa_hdr_proc_ctx_add); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1227,6 +1365,15 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs, pre_entry); + retval = -EINVAL; + break; + } if (ipa2_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { retval = -EFAULT; @@ -1243,10 +1390,11 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + - ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls * - sizeof(struct ipa_hdr_proc_ctx_del); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1256,6 +1404,16 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr_proc_ctx *) + param)->num_hdls != pre_entry)) { + IPAERR(" prevent memory corruption( %d not match %d)\n", + ((struct ipa_ioc_del_hdr_proc_ctx *)param)-> + num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa2_del_hdr_proc_ctx( (struct ipa_ioc_del_hdr_proc_ctx *)param)) { retval = -EFAULT; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index d5563eb023c1..7887395a0468 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -583,6 +583,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_v4_nat_del nat_del; struct ipa_ioc_rm_dependency rm_depend; size_t sz; + int pre_entry; IPADBG("cmd=%x nr=%d\n", cmd, _IOC_NR(cmd)); @@ -636,11 +637,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + pre_entry = + ((struct ipa_ioc_nat_dma_cmd *)header)->entries; pyld_sz = sizeof(struct ipa_ioc_nat_dma_cmd) + - ((struct ipa_ioc_nat_dma_cmd *)header)->entries * - sizeof(struct ipa_ioc_nat_dma_one); + pre_entry * sizeof(struct ipa_ioc_nat_dma_one); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -651,7 +652,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_nat_dma_cmd *)param)->entries + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_nat_dma_cmd *)param)->entries, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_nat_dma_cmd((struct ipa_ioc_nat_dma_cmd *)param)) { retval = -EFAULT; break; @@ -676,10 +685,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr *)header)->num_hdrs; pyld_sz = sizeof(struct ipa_ioc_add_hdr) + - ((struct ipa_ioc_add_hdr *)header)->num_hdrs * - sizeof(struct ipa_hdr_add); + pre_entry * sizeof(struct ipa_hdr_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -689,6 +699,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr *)param)->num_hdrs + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_hdr *)param)->num_hdrs, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_add_hdr((struct ipa_ioc_add_hdr *)param)) { retval = -EFAULT; break; @@ -705,10 +724,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr) + - ((struct ipa_ioc_del_hdr *)header)->num_hdls * - sizeof(struct ipa_hdr_del); + pre_entry * sizeof(struct ipa_hdr_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -718,6 +738,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr *)param)->num_hdls + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_hdr *)param)->num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_del_hdr((struct ipa_ioc_del_hdr *)param)) { retval = -EFAULT; break; @@ -734,10 +763,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_rt_rule) + - ((struct ipa_ioc_add_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_add); + pre_entry * sizeof(struct ipa_rt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -747,6 +777,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_add_rt_rule((struct ipa_ioc_add_rt_rule *)param)) { retval = -EFAULT; break; @@ -763,10 +803,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_rt_rule_after *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_rt_rule_after) + - ((struct ipa_ioc_add_rt_rule_after *)header)->num_rules * - sizeof(struct ipa_rt_rule_add); + pre_entry * sizeof(struct ipa_rt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -776,6 +817,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_rt_rule_after *)param)-> + num_rules != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_rt_rule_after *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_add_rt_rule_after( (struct ipa_ioc_add_rt_rule_after *)param)) { @@ -794,10 +845,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_rt_rule) + - ((struct ipa_ioc_mdfy_rt_rule *)header)->num_rules * - sizeof(struct ipa_rt_rule_mdfy); + pre_entry * sizeof(struct ipa_rt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -807,6 +859,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_rt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_mdfy_rt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_mdfy_rt_rule((struct ipa_ioc_mdfy_rt_rule *)param)) { retval = -EFAULT; break; @@ -823,10 +885,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_rt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_rt_rule) + - ((struct ipa_ioc_del_rt_rule *)header)->num_hdls * - sizeof(struct ipa_rt_rule_del); + pre_entry * sizeof(struct ipa_rt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -836,6 +899,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_rt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_rt_rule *)param)->num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_del_rt_rule((struct ipa_ioc_del_rt_rule *)param)) { retval = -EFAULT; break; @@ -852,10 +924,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_add_flt_rule) + - ((struct ipa_ioc_add_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_add); + pre_entry * sizeof(struct ipa_flt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -865,6 +938,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_add_flt_rule((struct ipa_ioc_add_flt_rule *)param)) { retval = -EFAULT; break; @@ -882,10 +965,12 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_flt_rule_after *)header)-> + num_rules; pyld_sz = sizeof(struct ipa_ioc_add_flt_rule_after) + - ((struct ipa_ioc_add_flt_rule_after *)header)->num_rules * - sizeof(struct ipa_flt_rule_add); + pre_entry * sizeof(struct ipa_flt_rule_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -895,6 +980,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_flt_rule_after *)param)-> + num_rules != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_flt_rule_after *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_add_flt_rule_after( (struct ipa_ioc_add_flt_rule_after *)param)) { retval = -EFAULT; @@ -912,10 +1007,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_flt_rule *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_flt_rule) + - ((struct ipa_ioc_del_flt_rule *)header)->num_hdls * - sizeof(struct ipa_flt_rule_del); + pre_entry * sizeof(struct ipa_flt_rule_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -925,6 +1021,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_flt_rule *)param)->num_hdls + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_flt_rule *)param)-> + num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_del_flt_rule((struct ipa_ioc_del_flt_rule *)param)) { retval = -EFAULT; break; @@ -941,10 +1047,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules; pyld_sz = sizeof(struct ipa_ioc_mdfy_flt_rule) + - ((struct ipa_ioc_mdfy_flt_rule *)header)->num_rules * - sizeof(struct ipa_flt_rule_mdfy); + pre_entry * sizeof(struct ipa_flt_rule_mdfy); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -954,6 +1061,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_mdfy_flt_rule *)param)->num_rules + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_mdfy_flt_rule *)param)-> + num_rules, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_mdfy_flt_rule((struct ipa_ioc_mdfy_flt_rule *)param)) { retval = -EFAULT; break; @@ -1067,9 +1184,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_tx_props *) - header)->num_tx_props * + pre_entry = + ((struct ipa_ioc_query_intf_tx_props *) + header)->num_tx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_tx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -1080,6 +1198,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_query_intf_tx_props *) + param)->num_tx_props, pre_entry); + retval = -EINVAL; + break; + } if (ipa3_query_intf_tx_props( (struct ipa_ioc_query_intf_tx_props *)param)) { retval = -1; @@ -1102,9 +1230,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_rx_props *) - header)->num_rx_props * + pre_entry = + ((struct ipa_ioc_query_intf_rx_props *) + header)->num_rx_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_rx_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -1115,6 +1244,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_query_intf_rx_props *) + param)->num_rx_props, pre_entry); + retval = -EINVAL; + break; + } if (ipa3_query_intf_rx_props( (struct ipa_ioc_query_intf_rx_props *)param)) { retval = -1; @@ -1137,9 +1275,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - - pyld_sz = sz + ((struct ipa_ioc_query_intf_ext_props *) - header)->num_ext_props * + pre_entry = + ((struct ipa_ioc_query_intf_ext_props *) + header)->num_ext_props; + pyld_sz = sz + pre_entry * sizeof(struct ipa_ioc_ext_intf_prop); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { @@ -1150,6 +1289,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_query_intf_ext_props *) + param)->num_ext_props, pre_entry); + retval = -EINVAL; + break; + } if (ipa3_query_intf_ext_props( (struct ipa_ioc_query_intf_ext_props *)param)) { retval = -1; @@ -1166,8 +1314,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } - pyld_sz = sizeof(struct ipa_msg_meta) + + pre_entry = ((struct ipa_msg_meta *)header)->msg_len; + pyld_sz = sizeof(struct ipa_msg_meta) + + pre_entry; param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1177,6 +1327,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_msg_meta *)param)->msg_len + != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_msg_meta *)param)->msg_len, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_pull_msg((struct ipa_msg_meta *)param, (char *)param + sizeof(struct ipa_msg_meta), ((struct ipa_msg_meta *)param)->msg_len) != @@ -1293,10 +1452,12 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_add_hdr_proc_ctx *) + header)->num_proc_ctxs; pyld_sz = sizeof(struct ipa_ioc_add_hdr_proc_ctx) + - ((struct ipa_ioc_add_hdr_proc_ctx *)header)->num_proc_ctxs * - sizeof(struct ipa_hdr_proc_ctx_add); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_add); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1306,6 +1467,15 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_add_hdr_proc_ctx *) + param)->num_proc_ctxs, pre_entry); + retval = -EINVAL; + break; + } if (ipa3_add_hdr_proc_ctx( (struct ipa_ioc_add_hdr_proc_ctx *)param)) { retval = -EFAULT; @@ -1322,10 +1492,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + pre_entry = + ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls; pyld_sz = sizeof(struct ipa_ioc_del_hdr_proc_ctx) + - ((struct ipa_ioc_del_hdr_proc_ctx *)header)->num_hdls * - sizeof(struct ipa_hdr_proc_ctx_del); + pre_entry * sizeof(struct ipa_hdr_proc_ctx_del); param = kzalloc(pyld_sz, GFP_KERNEL); if (!param) { retval = -ENOMEM; @@ -1335,6 +1506,16 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = -EFAULT; break; } + /* add check in case user-space module compromised */ + if (unlikely(((struct ipa_ioc_del_hdr_proc_ctx *) + param)->num_hdls != pre_entry)) { + IPAERR(" prevent memory corruption(%d not match %d)\n", + ((struct ipa_ioc_del_hdr_proc_ctx *)param)-> + num_hdls, + pre_entry); + retval = -EINVAL; + break; + } if (ipa3_del_hdr_proc_ctx( (struct ipa_ioc_del_hdr_proc_ctx *)param)) { retval = -EFAULT; -- cgit v1.2.3 From 75abb6903a74fc20420b5c932a8c664644fac9e9 Mon Sep 17 00:00:00 2001 From: bradley_chen Date: Mon, 25 Jul 2016 16:41:00 +0800 Subject: platform:: qpnp-haptic: Correct logs printed condition 1. Correct VIB_ERR_LOG define form pr_error to pr_err. 2. Correct the log printed condition after writing QPNP_HAP_EN_CTL_REG in qpnp_hap_mod_enable. 3. Change the log level to ERR if qpnp_hap_vmax_config failed 4. Change the log level to ERR and print only when sc_irq_count is not 0 in suspend adn resume function. Bug: 30961838 Change-Id: I3266099a923722b3cd85c6a36fd3ec9410dc0824 Signed-off-by: bradley_chen --- drivers/platform/msm/qpnp-haptic.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) mode change 100644 => 100755 drivers/platform/msm/qpnp-haptic.c diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c old mode 100644 new mode 100755 index f132849dece7..5c3da0f46a49 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -32,7 +32,7 @@ #define VIB_INFO_LOG(fmt, ...) \ pr_info("[VIB] " fmt, ##__VA_ARGS__) #define VIB_ERR_LOG(fmt, ...) \ - pr_error("[VIB][ERR] " fmt, ##__VA_ARGS__) + pr_err("[VIB][ERR] " fmt, ##__VA_ARGS__) #define QPNP_IRQ_FLAGS (IRQF_TRIGGER_RISING | \ IRQF_TRIGGER_FALLING | \ @@ -443,14 +443,14 @@ static int qpnp_hap_mod_enable(struct qpnp_hap *hap, int on) rc = qpnp_hap_write_reg(hap, &val, QPNP_HAP_EN_CTL_REG(hap->base)); + if (!on && val) + VIB_DBG_LOG("reg=0x%x, rc=%d.\n", val, rc); if (rc < 0) - if (!on) - VIB_DBG_LOG("reg=0x%x, rc=%d.\n", val, rc); - if (rc < 0) - { - if(on) VIB_DBG_LOG("reg=0x%x, err=%d.\n", val, rc); - return rc; - } + { + if (on) + VIB_ERR_LOG("reg=0x%x, err=%d.\n", val, rc); + return rc; + } hap->reg_en_ctl = val; @@ -472,7 +472,7 @@ static int qpnp_hap_play(struct qpnp_hap *hap, int on) QPNP_HAP_PLAY_REG(hap->base)); if (on) VIB_DBG_LOG("on, reg=0x%x, rc=%d.\n", hap->reg_en_ctl, rc); - else + else if (hap->reg_play & QPNP_HAP_PLAY_EN) VIB_DBG_LOG("off, rc=%d.\n", rc); if (rc < 0) return rc; @@ -1246,8 +1246,8 @@ static ssize_t qpnp_hap_voltage_level_store(struct device *dev, hap->vmax_mv = input; rc = qpnp_hap_vmax_config(hap); - if(rc<0) - VIB_DBG_LOG("qpnp_hap_vmax_config set failed(%d)", rc); + if (rc < 0) + VIB_ERR_LOG("qpnp_hap_vmax_config set failed(%d)", rc); return count; } @@ -1784,7 +1784,8 @@ static int qpnp_haptic_suspend(struct device *dev) if (hap->use_sc_irq && (hap->sc_irq > 0)) { disable_irq(hap->sc_irq); - VIB_DBG_LOG("%s: sc_irq = %d\n", __func__, sc_irq_count); + if (sc_irq_count > 0) + VIB_ERR_LOG("%s: sc_irq = %d\n", __func__, sc_irq_count); } hrtimer_cancel(&hap->hap_timer); @@ -1800,7 +1801,8 @@ static int qpnp_haptic_resume(struct device *dev) struct qpnp_hap *hap = dev_get_drvdata(dev); if (hap->use_sc_irq && (hap->sc_irq > 0)) { - VIB_DBG_LOG("%s: sc_irq = %d\n", __func__, sc_irq_count); + if (sc_irq_count > 0) + VIB_ERR_LOG("%s: sc_irq = %d\n", __func__, sc_irq_count); enable_irq(hap->sc_irq); } @@ -2311,7 +2313,7 @@ static int qpnp_haptic_probe(struct spmi_device *spmi) struct regulator *vcc_pon; int rc, i; - VIB_DBG_LOG("%s, ++++++++++++++++++++++\n", __func__); + VIB_DBG_LOG("%s: ++\n", __func__); hap = devm_kzalloc(&spmi->dev, sizeof(*hap), GFP_KERNEL); if (!hap) return -ENOMEM; @@ -2377,9 +2379,6 @@ static int qpnp_haptic_probe(struct spmi_device *spmi) } } - VIB_DBG_LOG("play_mode=%d\n", hap->play_mode); - VIB_DBG_LOG("%s, ----------------------\n", __func__); - if (hap->manage_pon_supply) { vcc_pon = regulator_get(&spmi->dev, "vcc_pon"); if (IS_ERR(vcc_pon)) { @@ -2391,6 +2390,7 @@ static int qpnp_haptic_probe(struct spmi_device *spmi) hap->vcc_pon = vcc_pon; } + VIB_DBG_LOG("%s: --, play_mode=%d\n", __func__, hap->play_mode); ghap = hap; return 0; -- cgit v1.2.3 From 2768e8234dc65722b707fbb71f065bb183e8204f Mon Sep 17 00:00:00 2001 From: Ranjith Kagathi Ananda Date: Mon, 2 May 2016 12:42:56 -0700 Subject: msm: camera: isp: Fix the preview split issue This change fixes the preview split issue when overflow recovery procedure is triggered in daul vfe case.The current procedure will cause the vfe pipeline violation after the recovery. This causes the WM between two VFE out of sync. The new procedure will eliminate the pipeline violation so the split will never happen. BUG=30866777 CRs-Fixed: 1018298 Change-Id: Ie30c5c3224a654a49af8b62bc17f94cc7a790430 Signed-off-by: Jing Zhou Signed-off-by: Ranjith Kagathi Ananda --- drivers/media/platform/msm/camera_v2/isp/msm_isp.h | 1 + .../media/platform/msm/camera_v2/isp/msm_isp40.c | 28 ++-- .../media/platform/msm/camera_v2/isp/msm_isp44.c | 28 ++-- .../media/platform/msm/camera_v2/isp/msm_isp46.c | 32 +++-- .../media/platform/msm/camera_v2/isp/msm_isp47.c | 52 ++++--- .../platform/msm/camera_v2/isp/msm_isp_axi_util.c | 39 +++--- .../platform/msm/camera_v2/isp/msm_isp_util.c | 32 ++++- .../media/platform/msm/camera_v2/ispif/msm_ispif.c | 151 +++------------------ 8 files changed, 149 insertions(+), 214 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index f3fac0a0f0b0..4f3285cc782e 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -242,6 +242,7 @@ struct msm_vfe_core_ops { void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev, uint32_t *rdi_wm_mask); bool (*is_module_cfg_lock_needed)(uint32_t reg_offset); + void (*set_halt_restart_mask)(struct vfe_device *vfe_dev); }; struct msm_vfe_stats_ops { int (*get_stats_idx)(enum msm_isp_stats_type stats_type); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index b6e30d941746..5aa72e251220 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -1385,6 +1385,7 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev, msm_camera_io_w_mb(0xFFFFFFFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); vfe_dev->irq0_mask |= 0xF7; + vfe_dev->irq1_mask |= 0x81; msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); @@ -1408,8 +1409,9 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev, vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1; } else if (update_state == DISABLE_CAMIF || DISABLE_CAMIF_IMMEDIATELY == update_state) { - msm_vfe40_config_irq(vfe_dev, 0, 0, - MSM_ISP_IRQ_SET); + vfe_dev->irq1_mask &= ~0x81; + msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); val = msm_camera_io_r(vfe_dev->vfe_base + 0x464); /* disable danger signal */ msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0x464); @@ -1419,12 +1421,6 @@ static void msm_vfe40_update_camif_state(struct vfe_device *vfe_dev, /* testgen OFF*/ if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0x93C); - msm_camera_io_w(0, vfe_dev->vfe_base + 0x30); - msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x34); - msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24); - msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, - vfe_dev->irq1_mask, - MSM_ISP_IRQ_SET); } } @@ -1722,6 +1718,11 @@ static void msm_vfe40_update_ping_pong_addr( VFE40_PING_PONG_BASE(wm_idx, pingpong_bit)); } +static void msm_vfe40_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe40_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1729,8 +1730,8 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, enum msm_vfe_input_src i; /* Keep only halt and restart mask */ - msm_vfe40_config_irq(vfe_dev, (1 << 31), (1 << 8), - MSM_ISP_IRQ_SET); + msm_vfe40_set_halt_restart_mask(vfe_dev); + /*Clear IRQ Status */ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); @@ -1780,8 +1781,6 @@ static int msm_vfe40_axi_halt(struct vfe_device *vfe_dev, static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif) { - msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, - MSM_ISP_IRQ_SET); /* Clear IRQ Status */ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); @@ -1791,6 +1790,9 @@ static int msm_vfe40_axi_restart(struct vfe_device *vfe_dev, /* Start AXI */ msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0); + msm_vfe40_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); @@ -2251,6 +2253,8 @@ struct msm_vfe_hardware_info vfe40_hw_info = { .process_error_status = msm_vfe40_process_error_status, .is_module_cfg_lock_needed = msm_vfe40_is_module_cfg_lock_needed, + .set_halt_restart_mask = + msm_vfe40_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe40_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c index 800eace50fc9..b1e515c81801 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp44.c @@ -1049,8 +1049,9 @@ static void msm_vfe44_update_camif_state(struct vfe_device *vfe_dev, msm_camera_io_w_mb(0x1, vfe_dev->vfe_base + 0x24); vfe_dev->irq0_mask |= 0xF7; + vfe_dev->irq1_mask |= 0x81; msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, - vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); msm_camera_io_w_mb(0x140000, vfe_dev->vfe_base + 0x318); bus_en = @@ -1069,19 +1070,15 @@ static void msm_vfe44_update_camif_state(struct vfe_device *vfe_dev, vfe_dev->axi_data.src_info[VFE_PIX_0].active = 1; } else if (update_state == DISABLE_CAMIF || DISABLE_CAMIF_IMMEDIATELY == update_state) { - msm_vfe44_config_irq(vfe_dev, 0, - 0, MSM_ISP_IRQ_SET); + vfe_dev->irq1_mask &= ~0x81; + msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); val = msm_camera_io_r(vfe_dev->vfe_base + 0xC18); /* disable danger signal */ msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0xC18); msm_camera_io_w_mb((update_state == DISABLE_CAMIF ? 0x0 : 0x6), vfe_dev->vfe_base + 0x2F4); vfe_dev->axi_data.src_info[VFE_PIX_0].active = 0; - msm_camera_io_w(0, vfe_dev->vfe_base + 0x30); - msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x34); - msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x24); - msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, - vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); } } @@ -1322,6 +1319,11 @@ static void msm_vfe44_update_ping_pong_addr( VFE44_PING_PONG_BASE(wm_idx, pingpong_bit)); } +static void msm_vfe44_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe44_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1329,8 +1331,7 @@ static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev, enum msm_vfe_input_src i; /* Keep only halt and restart mask */ - msm_vfe44_config_irq(vfe_dev, (1 << 31), (1 << 8), - MSM_ISP_IRQ_SET); + msm_vfe44_set_halt_restart_mask(vfe_dev); /*Clear IRQ Status0, only leave reset irq mask*/ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); @@ -1390,8 +1391,6 @@ static int msm_vfe44_axi_halt(struct vfe_device *vfe_dev, static int msm_vfe44_axi_restart(struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif) { - msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, - MSM_ISP_IRQ_SET); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x30); msm_camera_io_w(0xFEFFFEFF, vfe_dev->vfe_base + 0x34); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x24); @@ -1400,6 +1399,9 @@ static int msm_vfe44_axi_restart(struct vfe_device *vfe_dev, /* Start AXI */ msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x2C0); + msm_vfe44_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, + MSM_ISP_IRQ_SET); + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); @@ -1898,6 +1900,8 @@ struct msm_vfe_hardware_info vfe44_hw_info = { .process_error_status = msm_vfe44_process_error_status, .is_module_cfg_lock_needed = msm_vfe44_is_module_cfg_lock_needed, + .set_halt_restart_mask = + msm_vfe44_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe44_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c index f7b0402a4b51..32ffd5906627 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp46.c @@ -1119,7 +1119,11 @@ static void msm_vfe46_update_camif_state(struct vfe_device *vfe_dev, return; if (update_state == ENABLE_CAMIF) { + msm_camera_io_w(0, vfe_dev->vfe_base + 0x64); + msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x68); + msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58); vfe_dev->irq0_mask |= 0xF5; + vfe_dev->irq1_mask |= 0x81; msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); @@ -1143,7 +1147,9 @@ static void msm_vfe46_update_camif_state(struct vfe_device *vfe_dev, msm_camera_io_w(1, vfe_dev->vfe_base + 0xAF4); } else if (update_state == DISABLE_CAMIF || DISABLE_CAMIF_IMMEDIATELY == update_state) { - msm_vfe46_config_irq(vfe_dev, 0, 0, MSM_ISP_IRQ_SET); + vfe_dev->irq1_mask &= ~0x81; + msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); /* disable danger signal */ val = msm_camera_io_r(vfe_dev->vfe_base + 0xC18); val &= ~(1 << 8); @@ -1154,11 +1160,6 @@ static void msm_vfe46_update_camif_state(struct vfe_device *vfe_dev, /* testgen OFF*/ if (vfe_dev->axi_data.src_info[VFE_PIX_0].input_mux == TESTGEN) msm_camera_io_w(1 << 1, vfe_dev->vfe_base + 0xAF4); - msm_camera_io_w(0, vfe_dev->vfe_base + 0x64); - msm_camera_io_w((1 << 0), vfe_dev->vfe_base + 0x68); - msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58); - msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, - vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); } } @@ -1407,6 +1408,11 @@ static void msm_vfe46_update_ping_pong_addr( VFE46_PING_PONG_BASE(wm_idx, pingpong_bit)); } +static void msm_vfe46_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe46_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1414,8 +1420,7 @@ static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev, enum msm_vfe_input_src i; /* Keep only halt and restart mask */ - msm_vfe46_config_irq(vfe_dev, (1 << 31), (1 << 8), - MSM_ISP_IRQ_SET); + msm_vfe46_set_halt_restart_mask(vfe_dev); /*Clear IRQ Status0, only leave reset irq mask*/ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); @@ -1475,8 +1480,6 @@ static int msm_vfe46_axi_halt(struct vfe_device *vfe_dev, static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif) { - msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, - MSM_ISP_IRQ_SET); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58); @@ -1485,10 +1488,14 @@ static int msm_vfe46_axi_restart(struct vfe_device *vfe_dev, /* Start AXI */ msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x374); - vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); + msm_vfe46_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); + + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); + if (enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, ENABLE_CAMIF); @@ -1904,6 +1911,7 @@ static void msm_vfe46_get_halt_restart_mask(uint32_t *irq0_mask, *irq0_mask = BIT(31); *irq1_mask = BIT(8); } + static struct msm_vfe_axi_hardware_info msm_vfe46_axi_hw_info = { .num_wm = 7, .num_comp_mask = 3, @@ -1993,6 +2001,8 @@ struct msm_vfe_hardware_info vfe46_hw_info = { .process_error_status = msm_vfe46_process_error_status, .is_module_cfg_lock_needed = msm_vfe46_is_module_cfg_lock_needed, + .set_halt_restart_mask = + msm_vfe46_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe46_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c index 3a3af6f60db6..06effe701203 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp47.c @@ -361,7 +361,7 @@ void msm_vfe47_init_hardware_reg(struct vfe_device *vfe_dev) /* BUS_CFG */ msm_camera_io_w(0x00000101, vfe_dev->vfe_base + 0x84); /* IRQ_MASK/CLEAR */ - vfe_dev->irq0_mask = 0xE00000F3; + vfe_dev->irq0_mask = 0xE00000F5; vfe_dev->irq1_mask = 0xFFFFFFFF; msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); @@ -412,7 +412,9 @@ void msm_vfe47_process_input_irq(struct vfe_device *vfe_dev, return; if (irq_status0 & (1 << 0)) { - ISP_DBG("%s: SOF IRQ\n", __func__); + ISP_DBG("vfe %d: SOF IRQ, frame id %d\n", + vfe_dev->pdev->id, + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id); msm_isp_increment_frame_id(vfe_dev, VFE_PIX_0, ts); } @@ -670,8 +672,8 @@ void msm_vfe47_reg_update(struct vfe_device *vfe_dev, if ((vfe_dev->is_split && vfe_dev->pdev->id == ISP_VFE1) && ((frame_src == VFE_PIX_0) || (frame_src == VFE_SRC_MAX))) { msm_camera_io_w_mb(update_mask, - vfe_dev->common_data->dual_vfe_res->vfe_base[ISP_VFE0] - + 0x4AC); + vfe_dev->common_data->dual_vfe_res-> + vfe_base[ISP_VFE0] + 0x4AC); msm_camera_io_w_mb(update_mask, vfe_dev->vfe_base + 0x4AC); } else if (!vfe_dev->is_split || @@ -1374,9 +1376,14 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev, val = msm_camera_io_r(vfe_dev->vfe_base + 0x47C); if (update_state == ENABLE_CAMIF) { + msm_camera_io_w(0, vfe_dev->vfe_base + 0x64); + msm_camera_io_w(1 << 0, vfe_dev->vfe_base + 0x68); + msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58); vfe_dev->irq0_mask |= 0xF5; + vfe_dev->irq1_mask |= 0x81; + msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, - vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); if ((vfe_dev->hvx_cmd > HVX_DISABLE) && (vfe_dev->hvx_cmd <= HVX_ROUND_TRIP)) @@ -1404,8 +1411,10 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev, msm_camera_io_w(1, vfe_dev->vfe_base + 0xC58); } else if (update_state == DISABLE_CAMIF || update_state == DISABLE_CAMIF_IMMEDIATELY) { - /* turn off all irq before camif disable */ - msm_vfe47_config_irq(vfe_dev, 0, 0, MSM_ISP_IRQ_SET); + /* turn off camif violation and error irqs */ + vfe_dev->irq1_mask &= ~0x81; + msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); val = msm_camera_io_r(vfe_dev->vfe_base + 0x464); /* disable danger signal */ msm_camera_io_w_mb(val & ~(1 << 8), vfe_dev->vfe_base + 0x464); @@ -1419,16 +1428,6 @@ void msm_vfe47_update_camif_state(struct vfe_device *vfe_dev, if ((vfe_dev->hvx_cmd > HVX_DISABLE) && (vfe_dev->hvx_cmd <= HVX_ROUND_TRIP)) msm_vfe47_configure_hvx(vfe_dev, 0); - /* - * restore the irq that were disabled for camif stop and clear - * the camif error interrupts if generated during that period - */ - msm_camera_io_w(0, vfe_dev->vfe_base + 0x64); - msm_camera_io_w(1 << 0, vfe_dev->vfe_base + 0x68); - msm_camera_io_w_mb(1, vfe_dev->vfe_base + 0x58); - msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, - vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); - } } @@ -1685,6 +1684,11 @@ void msm_vfe47_update_ping_pong_addr( } +static void msm_vfe47_set_halt_restart_mask(struct vfe_device *vfe_dev) +{ + msm_vfe47_config_irq(vfe_dev, BIT(31), BIT(8), MSM_ISP_IRQ_SET); +} + int msm_vfe47_axi_halt(struct vfe_device *vfe_dev, uint32_t blocking) { @@ -1697,8 +1701,7 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev, msm_camera_io_w(val, vfe_dev->vfe_vbif_base + VFE47_VBIF_CLK_OFFSET); /* Keep only halt and reset mask */ - msm_vfe47_config_irq(vfe_dev, (1 << 31), (1 << 8), - MSM_ISP_IRQ_SET); + msm_vfe47_set_halt_restart_mask(vfe_dev); /*Clear IRQ Status0, only leave reset irq mask*/ msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); @@ -1760,8 +1763,6 @@ int msm_vfe47_axi_halt(struct vfe_device *vfe_dev, int msm_vfe47_axi_restart(struct vfe_device *vfe_dev, uint32_t blocking, uint32_t enable_camif) { - msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, vfe_dev->irq1_mask, - MSM_ISP_IRQ_SET); msm_camera_io_w(0x7FFFFFFF, vfe_dev->vfe_base + 0x64); msm_camera_io_w(0xFFFFFEFF, vfe_dev->vfe_base + 0x68); msm_camera_io_w(0x1, vfe_dev->vfe_base + 0x58); @@ -1769,10 +1770,15 @@ int msm_vfe47_axi_restart(struct vfe_device *vfe_dev, /* Start AXI */ msm_camera_io_w(0x0, vfe_dev->vfe_base + 0x400); - vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); memset(&vfe_dev->error_info, 0, sizeof(vfe_dev->error_info)); atomic_set(&vfe_dev->error_info.overflow_state, NO_OVERFLOW); + /* reset the irq masks without camif violation and errors */ + msm_vfe47_config_irq(vfe_dev, vfe_dev->irq0_mask, + vfe_dev->irq1_mask, MSM_ISP_IRQ_SET); + + vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev, VFE_SRC_MAX); + if (enable_camif) { vfe_dev->hw_info->vfe_ops.core_ops. update_camif_state(vfe_dev, ENABLE_CAMIF); @@ -2652,6 +2658,8 @@ struct msm_vfe_hardware_info vfe47_hw_info = { .process_error_status = msm_vfe47_process_error_status, .is_module_cfg_lock_needed = msm_vfe47_is_module_cfg_lock_needed, + .set_halt_restart_mask = + msm_vfe47_set_halt_restart_mask, }, .stats_ops = { .get_stats_idx = msm_vfe47_get_stats_idx, diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index 083a82cab4fd..adc26996593f 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -2193,24 +2193,11 @@ int msm_isp_axi_halt(struct vfe_device *vfe_dev, { int rc = 0; - if (atomic_read(&vfe_dev->error_info.overflow_state) == - OVERFLOW_DETECTED) { - ISP_DBG("%s: VFE%d already halted, direct return\n", - __func__, vfe_dev->pdev->id); - return rc; - } - - if (halt_cmd->overflow_detected) { - atomic_cmpxchg(&vfe_dev->error_info.overflow_state, - NO_OVERFLOW, OVERFLOW_DETECTED); - pr_err("%s: VFE%d Bus overflow detected: start recovery!\n", - __func__, vfe_dev->pdev->id); - } - if (halt_cmd->stop_camif) { vfe_dev->hw_info->vfe_ops.core_ops. - update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY); + update_camif_state(vfe_dev, DISABLE_CAMIF_IMMEDIATELY); } + rc = vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, halt_cmd->blocking_halt); @@ -2233,6 +2220,9 @@ int msm_isp_axi_reset(struct vfe_device *vfe_dev, return rc; } + /* flush the tasklet queue */ + msm_isp_flush_tasklet(vfe_dev); + rc = vfe_dev->hw_info->vfe_ops.core_ops.reset_hw(vfe_dev, 0, reset_cmd->blocking); @@ -2296,7 +2286,16 @@ int msm_isp_axi_restart(struct vfe_device *vfe_dev, uint32_t wm_reload_mask = 0x0; unsigned long flags; + /* reset sync mask */ + spin_lock_irqsave( + &vfe_dev->common_data->common_dev_data_lock, flags); + vfe_dev->common_data->dual_vfe_res->epoch_sync_mask = 0; + spin_unlock_irqrestore( + &vfe_dev->common_data->common_dev_data_lock, flags); + vfe_dev->buf_mgr->frameId_mismatch_recovery = 0; + + for (i = 0, j = 0; j < axi_data->num_active_stream && i < VFE_AXI_SRC_MAX; i++, j++) { stream_info = &axi_data->stream_info[i]; @@ -2315,7 +2314,8 @@ int msm_isp_axi_restart(struct vfe_device *vfe_dev, rc = vfe_dev->hw_info->vfe_ops.axi_ops.restart(vfe_dev, 0, restart_cmd->enable_camif); if (rc < 0) - pr_err("%s Error restarting HW\n", __func__); + pr_err("%s Error restarting vfe %d HW\n", + __func__, vfe_dev->pdev->id); return rc; } @@ -3558,6 +3558,13 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, if (done_buf) buf_index = done_buf->buf_idx; + ISP_DBG("%s: vfe %d: stream 0x%x, frame id %d, pingpong bit %d\n", + __func__, + vfe_dev->pdev->id, + stream_info->stream_id, + frame_id, + pingpong_bit); + rc = vfe_dev->buf_mgr->ops->update_put_buf_cnt(vfe_dev->buf_mgr, vfe_dev->pdev->id, done_buf ? done_buf->bufq_handle : diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index e3352644b26f..5d246b252229 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -1699,7 +1699,6 @@ static void msm_isp_process_overflow_irq( if (overflow_mask) { struct msm_isp_event_data error_event; - struct msm_vfe_axi_halt_cmd halt_cmd; if (vfe_dev->reset_pending == 1) { pr_err("%s:%d failed: overflow %x during reset\n", @@ -1709,16 +1708,37 @@ static void msm_isp_process_overflow_irq( return; } - halt_cmd.overflow_detected = 1; - halt_cmd.stop_camif = 1; - halt_cmd.blocking_halt = 0; + ISP_DBG("%s: VFE%d Bus overflow detected: start recovery!\n", + __func__, vfe_dev->pdev->id); + + /* maks off irq for current vfe */ + atomic_cmpxchg(&vfe_dev->error_info.overflow_state, + NO_OVERFLOW, OVERFLOW_DETECTED); + vfe_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(vfe_dev); + + /* mask off other vfe if dual vfe is used */ + if (vfe_dev->is_split) { + uint32_t other_vfe_id; - msm_isp_axi_halt(vfe_dev, &halt_cmd); + other_vfe_id = (vfe_dev->pdev->id == ISP_VFE0) ? + ISP_VFE1 : ISP_VFE0; + + atomic_cmpxchg(&(vfe_dev->common_data->dual_vfe_res-> + vfe_dev[other_vfe_id]-> + error_info.overflow_state), + NO_OVERFLOW, OVERFLOW_DETECTED); + + vfe_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(vfe_dev->common_data-> + dual_vfe_res->vfe_dev[other_vfe_id]); + } - /*Update overflow state*/ + /* reset irq status so skip further process */ *irq_status0 = 0; *irq_status1 = 0; + /* send overflow event as needed */ if (atomic_read(&vfe_dev->error_info.overflow_state) != HALT_ENFORCED) { memset(&error_event, 0, sizeof(error_event)); diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 5fed9314f045..67beb9d803f7 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -855,6 +855,7 @@ static int msm_ispif_stop_immediately(struct ispif_device *ispif, cid_mask, params->entries[i].vfe_intf, 0); } + rc = msm_ispif_reset_hw(ispif); return rc; } @@ -883,142 +884,21 @@ static int msm_ispif_start_frame_boundary(struct ispif_device *ispif, static int msm_ispif_restart_frame_boundary(struct ispif_device *ispif, struct msm_ispif_param_data *params) { - int rc = 0, i; - long timeout = 0; - uint16_t cid_mask; - enum msm_ispif_intftype intftype; - enum msm_ispif_vfe_intf vfe_intf; - uint32_t vfe_mask = 0; - uint32_t intf_addr; - - if (ispif->ispif_state != ISPIF_POWER_UP) { - pr_err("%s: ispif invalid state %d\n", __func__, - ispif->ispif_state); - rc = -EPERM; - return rc; - } - if (params->num > MAX_PARAM_ENTRIES) { - pr_err("%s: invalid param entries %d\n", __func__, - params->num); - rc = -EINVAL; - return rc; - } - - for (i = 0; i < params->num; i++) { - vfe_intf = params->entries[i].vfe_intf; - if (vfe_intf >= VFE_MAX) { - pr_err("%s: %d invalid i %d vfe_intf %d\n", __func__, - __LINE__, i, vfe_intf); - return -EINVAL; - } - vfe_mask |= (1 << vfe_intf); - } - - /* Turn ON regulators before enabling the clocks*/ - rc = msm_ispif_set_regulators(ispif->vfe_vdd, - ispif->vfe_vdd_count, 1); - if (rc < 0) - return -EFAULT; - - rc = msm_camera_clk_enable(&ispif->pdev->dev, - ispif->clk_info, ispif->clks, - ispif->num_clk, 1); - if (rc < 0) - goto disable_regulator; - - if (vfe_mask & (1 << VFE0)) { - atomic_set(&ispif->reset_trig[VFE0], 1); - /* initiate reset of ISPIF */ - msm_camera_io_w(ISPIF_RST_CMD_MASK_RESTART, - ispif->base + ISPIF_RST_CMD_ADDR); - timeout = wait_for_completion_timeout( - &ispif->reset_complete[VFE0], msecs_to_jiffies(500)); - if (timeout <= 0) { - pr_err("%s: VFE0 reset wait timeout\n", __func__); - rc = -ETIMEDOUT; - goto disable_clk; - } - } - - if (ispif->hw_num_isps > 1 && (vfe_mask & (1 << VFE1))) { - atomic_set(&ispif->reset_trig[VFE1], 1); - msm_camera_io_w(ISPIF_RST_CMD_1_MASK_RESTART, - ispif->base + ISPIF_RST_CMD_1_ADDR); - timeout = wait_for_completion_timeout( - &ispif->reset_complete[VFE1], - msecs_to_jiffies(500)); - if (timeout <= 0) { - pr_err("%s: VFE1 reset wait timeout\n", __func__); - rc = -ETIMEDOUT; - goto disable_clk; - } - } - - pr_info("%s: ISPIF reset hw done, Restarting", __func__); - rc = msm_camera_clk_enable(&ispif->pdev->dev, - ispif->clk_info, ispif->clks, - ispif->num_clk, 0); - if (rc < 0) - goto disable_regulator; - - /* Turn OFF regulators after disabling clocks */ - rc = msm_ispif_set_regulators(ispif->vfe_vdd, ispif->vfe_vdd_count, 0); - if (rc < 0) - goto end; - - for (i = 0; i < params->num; i++) { - intftype = params->entries[i].intftype; - vfe_intf = params->entries[i].vfe_intf; - - switch (params->entries[0].intftype) { - case PIX0: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 0); - break; - case RDI0: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 0); - break; - case PIX1: - intf_addr = ISPIF_VFE_m_PIX_INTF_n_STATUS(vfe_intf, 1); - break; - case RDI1: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 1); - break; - case RDI2: - intf_addr = ISPIF_VFE_m_RDI_INTF_n_STATUS(vfe_intf, 2); - break; - default: - pr_err("%s: invalid intftype=%d\n", __func__, - params->entries[i].intftype); - rc = -EPERM; - goto end; - } - - msm_ispif_intf_cmd(ispif, - ISPIF_INTF_CMD_ENABLE_FRAME_BOUNDARY, params); - } - - for (i = 0; i < params->num; i++) { - intftype = params->entries[i].intftype; - - vfe_intf = params->entries[i].vfe_intf; - - - cid_mask = msm_ispif_get_cids_mask_from_cfg( - ¶ms->entries[i]); + int rc = 0; - msm_ispif_enable_intf_cids(ispif, intftype, - cid_mask, vfe_intf, 1); - } - return rc; + rc = msm_ispif_reset_hw(ispif); + if (!rc) + rc = msm_ispif_reset(ispif); + if (!rc) + rc = msm_ispif_config(ispif, params); + if (!rc) + rc = msm_ispif_start_frame_boundary(ispif, params); + + if (!rc) + pr_info("ISPIF restart Successful\n"); + else + pr_info("ISPIF restart Failed\n"); -disable_clk: - msm_camera_clk_enable(&ispif->pdev->dev, - ispif->clk_info, ispif->clks, - ispif->num_clk, 0); -disable_regulator: - /* Turn OFF regulators */ - msm_ispif_set_regulators(ispif->vfe_vdd, ispif->vfe_vdd_count, 0); -end: return rc; } @@ -1094,7 +974,7 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, ISPIF_TIMEOUT_SLEEP_US, ISPIF_TIMEOUT_ALL_US); if (rc < 0) - goto end; + pr_err("ISPIF stop frame boundary timeout\n"); /* disable CIDs in CID_MASK register */ msm_ispif_enable_intf_cids(ispif, params->entries[i].intftype, @@ -1102,6 +982,7 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, } end: + rc = msm_ispif_reset_hw(ispif); return rc; } -- cgit v1.2.3 From 8d7d5ab45fc3003befd6b6f992f5c7818996c5c1 Mon Sep 17 00:00:00 2001 From: Ranjith Kagathi Ananda Date: Fri, 22 Jul 2016 13:09:44 -0700 Subject: msm: camera: isp: Fix an issue in ispif The ispif hardware reset in the stramoff() is not correct. The ispif hardware reset can only be done at the open/close ispif node. This change is to remove the hardware reset during the streamoff which causes the issue in the PIP use case. BUG=30866777 Change-Id: I5a7428b7ac76c6b360d0a97c07473886170d8e65 Signed-off-by: Jing Zhou Signed-off-by: Ranjith Kagathi Ananda --- drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c index 67beb9d803f7..d0e308e23050 100644 --- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c +++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c @@ -855,7 +855,6 @@ static int msm_ispif_stop_immediately(struct ispif_device *ispif, cid_mask, params->entries[i].vfe_intf, 0); } - rc = msm_ispif_reset_hw(ispif); return rc; } @@ -982,7 +981,6 @@ static int msm_ispif_stop_frame_boundary(struct ispif_device *ispif, } end: - rc = msm_ispif_reset_hw(ispif); return rc; } -- cgit v1.2.3 From d59da5ebb5cefbad89a7fc33bd514d858cb4bbae Mon Sep 17 00:00:00 2001 From: Ranjith Kagathi Ananda Date: Fri, 29 Jul 2016 20:07:47 +0530 Subject: msm:isp: add recovery method in case of pingpong mismatch. restart the VFE in case of pingpong mismatch. BUG=30866777 Change-Id: I38482aeb8d03c81a1ebe91ba895916fc5064e8aa Signed-off-by: Alok Kediya Signed-off-by: Ranjith Kagathi Ananda --- drivers/media/platform/msm/camera_v2/isp/msm_isp.h | 2 + .../platform/msm/camera_v2/isp/msm_isp_axi_util.c | 14 +++++- .../msm/camera_v2/isp/msm_isp_stats_util.c | 2 +- .../platform/msm/camera_v2/isp/msm_isp_util.c | 50 ++++++++++++++++++++++ .../platform/msm/camera_v2/isp/msm_isp_util.h | 1 + 5 files changed, 66 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h index 4f3285cc782e..f525c71f5da2 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h @@ -63,6 +63,7 @@ #define MAX_BUFFERS_IN_HW 2 #define MAX_VFE 2 +#define MAX_RECOVERY_THRESHOLD 5 struct vfe_device; struct msm_vfe_axi_stream; @@ -511,6 +512,7 @@ struct msm_vfe_axi_shared_data { uint32_t event_mask; uint8_t enable_frameid_recovery; enum msm_vfe_camif_state camif_state; + uint32_t recovery_count; }; struct msm_vfe_stats_hardware_info { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index adc26996593f..3c7a82858bbf 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1509,13 +1509,23 @@ void msm_isp_halt_send_error(struct vfe_device *vfe_dev, uint32_t event) struct msm_isp_event_data error_event; struct msm_vfe_axi_halt_cmd halt_cmd; + if (ISP_EVENT_PING_PONG_MISMATCH == event && + vfe_dev->axi_data.recovery_count < MAX_RECOVERY_THRESHOLD) { + pr_err("%s:pingpong mismatch from vfe%d, core%d,recovery_count %d\n", + __func__, vfe_dev->pdev->id, smp_processor_id(), + vfe_dev->axi_data.recovery_count); + vfe_dev->axi_data.recovery_count++; + msm_isp_start_error_recovery(vfe_dev); + return; + } + memset(&halt_cmd, 0, sizeof(struct msm_vfe_axi_halt_cmd)); memset(&error_event, 0, sizeof(struct msm_isp_event_data)); halt_cmd.stop_camif = 1; halt_cmd.overflow_detected = 0; halt_cmd.blocking_halt = 0; - pr_err("%s: vfe%d fatal error!\n", __func__, vfe_dev->pdev->id); + pr_err("%s: vfe%d exiting camera!\n", __func__, vfe_dev->pdev->id); atomic_set(&vfe_dev->error_info.overflow_state, HALT_ENFORCED); @@ -3574,7 +3584,7 @@ void msm_isp_process_axi_irq_stream(struct vfe_device *vfe_dev, if (rc < 0) { spin_unlock_irqrestore(&stream_info->lock, flags); /* this usually means a serious scheduling error */ - msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR); + msm_isp_halt_send_error(vfe_dev, ISP_EVENT_PING_PONG_MISMATCH); return; } /* diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c index e59dd679220d..1332a3e4cce3 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c @@ -203,7 +203,7 @@ static int32_t msm_isp_stats_buf_divert(struct vfe_device *vfe_dev, if (rc < 0) { if (rc == -EFAULT) msm_isp_halt_send_error(vfe_dev, - ISP_EVENT_BUF_FATAL_ERROR); + ISP_EVENT_PING_PONG_MISMATCH); pr_err("stats_buf_divert: update put buf cnt fail\n"); return rc; } diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c index 5d246b252229..d2b3629202b2 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c @@ -2140,3 +2140,53 @@ void msm_isp_save_framedrop_values(struct vfe_device *vfe_dev, spin_unlock_irqrestore(&stream_info->lock, flags); } } + +void msm_isp_start_error_recovery(struct vfe_device *vfe_dev) +{ + struct msm_isp_event_data error_event; + + /*Mask out all other irqs if recovery is started*/ + if (atomic_read(&vfe_dev->error_info.overflow_state) != NO_OVERFLOW) { + pr_err("%s: Error Recovery in processing !!!\n", + __func__); + return; + } + + if (vfe_dev->reset_pending == 1) { + pr_err("%s:%d failed: recovery during reset\n", + __func__, __LINE__); + return; + } + + /* maks off irq for current vfe */ + atomic_cmpxchg(&vfe_dev->error_info.overflow_state, + NO_OVERFLOW, OVERFLOW_DETECTED); + vfe_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(vfe_dev); + + /* mask off other vfe if dual vfe is used */ + if (vfe_dev->is_split) { + uint32_t other_vfe_id; + + other_vfe_id = (vfe_dev->pdev->id == ISP_VFE0) ? + ISP_VFE1 : ISP_VFE0; + atomic_cmpxchg(&(vfe_dev->common_data->dual_vfe_res-> + vfe_dev[other_vfe_id]-> + error_info.overflow_state), + NO_OVERFLOW, OVERFLOW_DETECTED); + vfe_dev->hw_info->vfe_ops.core_ops. + set_halt_restart_mask(vfe_dev->common_data-> + dual_vfe_res->vfe_dev[other_vfe_id]); + } + + if (atomic_read(&vfe_dev->error_info.overflow_state) + != HALT_ENFORCED) { + memset(&error_event, 0, sizeof(error_event)); + error_event.frame_id = + vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id; + error_event.u.error_info.err_type = + ISP_ERROR_BUS_OVERFLOW; + msm_isp_send_event(vfe_dev, + ISP_EVENT_ERROR, &error_event); + } +} diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h index 498c63c91c92..a8a7ea05f68e 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h @@ -73,4 +73,5 @@ void msm_isp_flush_tasklet(struct vfe_device *vfe_dev); void msm_isp_save_framedrop_values(struct vfe_device *vfe_dev, enum msm_vfe_input_src frame_src); void msm_isp_get_timestamp(struct msm_isp_timestamp *time_stamp, struct vfe_device *vfe_dev); +void msm_isp_start_error_recovery(struct vfe_device *vfe_dev); #endif /* __MSM_ISP_UTIL_H__ */ -- cgit v1.2.3 From d6a8196911be4aee3f726dc7835e38ffe92e5797 Mon Sep 17 00:00:00 2001 From: Praveen Chavan Date: Tue, 23 Aug 2016 13:14:22 -0700 Subject: msm: vidc: Compare ion_handles rather than fds fd(s) cannot uniquely identify buffers queued by cross-process clients. Use ion handles to compare and match already-mapped- buffers irrespective of data or extradata planes. Bug: 30969795 Change-Id: I591f18aa225cc6690bf423f2ae5bc7dafd4dad78 Signed-off-by: Praveen Chavan --- drivers/media/platform/msm/vidc/msm_vidc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 42beacf8c0f4..724ab779571e 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -241,8 +241,7 @@ err_invalid_input: return ret; } -static struct msm_smem *get_same_fd_buffer(struct msm_vidc_list *buf_list, - int fd) +static struct msm_smem *get_same_fd_buffer(struct msm_vidc_inst *inst, int fd) { struct buffer_info *temp; struct msm_smem *same_fd_handle = NULL; @@ -252,16 +251,18 @@ static struct msm_smem *get_same_fd_buffer(struct msm_vidc_list *buf_list, if (!fd) return NULL; - if (!buf_list || fd < 0) { - dprintk(VIDC_ERR, "Invalid input\n"); + if (!inst || fd < 0) { + dprintk(VIDC_ERR, "%s: Invalid input\n", __func__); goto err_invalid_input; } - mutex_lock(&buf_list->lock); - list_for_each_entry(temp, &buf_list->list, list) { + mutex_lock(&inst->registeredbufs.lock); + list_for_each_entry(temp, &inst->registeredbufs.list, list) { for (i = 0; i < min(temp->num_planes, VIDEO_MAX_PLANES); i++) { - if (temp->fd[i] == fd && - temp->handle[i] && temp->mapped[i]) { + bool ion_hndl_matches = temp->handle[i] ? + msm_smem_compare_buffers(inst->mem_client, fd, + temp->handle[i]->smem_priv) : false; + if (ion_hndl_matches && temp->mapped[i]) { temp->same_fd_ref[i]++; dprintk(VIDC_INFO, "Found same fd buffer\n"); @@ -272,7 +273,7 @@ static struct msm_smem *get_same_fd_buffer(struct msm_vidc_list *buf_list, if (same_fd_handle) break; } - mutex_unlock(&buf_list->lock); + mutex_unlock(&inst->registeredbufs.lock); err_invalid_input: return same_fd_handle; @@ -493,8 +494,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) } same_fd_handle = get_same_fd_buffer( - &inst->registeredbufs, - b->m.planes[i].reserved[0]); + inst, b->m.planes[i].reserved[0]); populate_buf_info(binfo, b, i); if (same_fd_handle) { -- cgit v1.2.3 From e2699e56af139595b31473b4bc91403283f5b2f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 13 Jan 2016 17:48:01 +0100 Subject: UPSTREAM: ALSA: timer: Fix race among timer ioctls (cherry picked from commit af368027a49a751d6ff4ee9e3f9961f35bb4fede) ALSA timer ioctls have an open race and this may lead to a use-after-free of timer instance object. A simplistic fix is to make each ioctl exclusive. We have already tread_sem for controlling the tread, and extend this as a global mutex to be applied to each ioctl. The downside is, of course, the worse concurrency. But these ioctls aren't to be parallel accessible, in anyway, so it should be fine to serialize there. Reported-by: Dmitry Vyukov Tested-by: Dmitry Vyukov Cc: Signed-off-by: Takashi Iwai Change-Id: I1ac52f1cba5e7408fd88c8fc1c30ca2e83967ebb Bug: 28694392 --- sound/core/timer.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 4927a3c88340..442e27968925 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -74,7 +74,7 @@ struct snd_timer_user { struct timespec tstamp; /* trigger tstamp */ wait_queue_head_t qchange_sleep; struct fasync_struct *fasync; - struct mutex tread_sem; + struct mutex ioctl_lock; }; /* list of timers */ @@ -1333,7 +1333,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) return -ENOMEM; spin_lock_init(&tu->qlock); init_waitqueue_head(&tu->qchange_sleep); - mutex_init(&tu->tread_sem); + mutex_init(&tu->ioctl_lock); tu->ticks = 1; tu->queue_size = 128; tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), @@ -1353,8 +1353,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) if (file->private_data) { tu = file->private_data; file->private_data = NULL; + mutex_lock(&tu->ioctl_lock); if (tu->timeri) snd_timer_close(tu->timeri); + mutex_unlock(&tu->ioctl_lock); kfree(tu->queue); kfree(tu->tqueue); kfree(tu); @@ -1592,7 +1594,6 @@ static int snd_timer_user_tselect(struct file *file, int err = 0; tu = file->private_data; - mutex_lock(&tu->tread_sem); if (tu->timeri) { snd_timer_close(tu->timeri); tu->timeri = NULL; @@ -1636,7 +1637,6 @@ static int snd_timer_user_tselect(struct file *file, } __err: - mutex_unlock(&tu->tread_sem); return err; } @@ -1849,7 +1849,7 @@ enum { SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), }; -static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, +static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct snd_timer_user *tu; @@ -1866,17 +1866,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, { int xarg; - mutex_lock(&tu->tread_sem); - if (tu->timeri) { /* too late */ - mutex_unlock(&tu->tread_sem); + if (tu->timeri) /* too late */ return -EBUSY; - } - if (get_user(xarg, p)) { - mutex_unlock(&tu->tread_sem); + if (get_user(xarg, p)) return -EFAULT; - } tu->tread = xarg ? 1 : 0; - mutex_unlock(&tu->tread_sem); return 0; } case SNDRV_TIMER_IOCTL_GINFO: @@ -1909,6 +1903,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, return -ENOTTY; } +static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct snd_timer_user *tu = file->private_data; + long ret; + + mutex_lock(&tu->ioctl_lock); + ret = __snd_timer_user_ioctl(file, cmd, arg); + mutex_unlock(&tu->ioctl_lock); + return ret; +} + static int snd_timer_user_fasync(int fd, struct file * file, int on) { struct snd_timer_user *tu; -- cgit v1.2.3 From f893bc842a4bd2431ed355db86514f7e8e59b311 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:20 -0400 Subject: UPSTREAM: ALSA: timer: Fix leak in events via snd_timer_user_ccallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry pick from commit 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6) The stack object “r1” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Bug: 28980217 Change-Id: I0ba03af4d0620bcbc7a808d083295b7c97aba56d --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index 442e27968925..ac15b4e3410c 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1251,6 +1251,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, tu->tstamp = *tstamp; if ((tu->filter & (1 << event)) == 0 || !tu->tread) return; + memset(&r1, 0, sizeof(r1)); r1.event = event; r1.tstamp = *tstamp; r1.val = resolution; -- cgit v1.2.3 From 449ae3ff25d5bd229ccf1f63a94437c7c2813f97 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:32 -0400 Subject: UPSTREAM: ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry pick from commit e4ec8cc8039a7063e24204299b462bd1383184a5) The stack object “r1” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Bug: 28980217 Change-Id: I756d05a328a133c1c67132301434c6817be0a2a6 --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index ac15b4e3410c..f5e600292819 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1286,6 +1286,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, } if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { + memset(&r1, 0, sizeof(r1)); r1.event = SNDRV_TIMER_EVENT_RESOLUTION; r1.tstamp = tstamp; r1.val = resolution; -- cgit v1.2.3 From 5fd212257c4f4f636c919817db9c2efaf900c4f8 Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:44:07 -0400 Subject: UPSTREAM: ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry pick from commit cec8f96e49d9be372fdb0c3836dcf31ec71e457e) The stack object “tread” has a total size of 32 bytes. Its field “event” and “val” both contain 4 bytes padding. These 8 bytes padding bytes are sent to user without being initialized. Signed-off-by: Kangjie Lu Signed-off-by: Takashi Iwai Bug: 28980557 Change-Id: I963a8f5f7ae828787c655c9b89121d3844474513 --- sound/core/timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/core/timer.c b/sound/core/timer.c index f5e600292819..9d543fab2055 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1752,6 +1752,7 @@ static int snd_timer_user_params(struct file *file, if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { if (tu->tread) { struct snd_timer_tread tread; + memset(&tread, 0, sizeof(tread)); tread.event = SNDRV_TIMER_EVENT_EARLY; tread.tstamp.tv_sec = 0; tread.tstamp.tv_nsec = 0; -- cgit v1.2.3 From cd5b1e372ed3f4017bd555707d3271d208d0680a Mon Sep 17 00:00:00 2001 From: Kangjie Lu Date: Tue, 3 May 2016 16:32:16 -0400 Subject: UPSTREAM: USB: usbfs: fix potential infoleak in devio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry pick from commit 681fef8380eb818c0b845fca5d2ab1dcbab114ee) The stack object “ci” has a total size of 8 bytes. Its last 3 bytes are padding bytes which are not initialized and leaked to userland via “copy_to_user”. Signed-off-by: Kangjie Lu Signed-off-by: Greg Kroah-Hartman Bug: 28619695 Change-Id: I170754d659d0891c075f85211b5e3970b114f097 --- drivers/usb/core/devio.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index a85eadff6bea..dfcb5f8b8f18 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1202,10 +1202,11 @@ static int proc_getdriver(struct usb_dev_state *ps, void __user *arg) static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + + memset(&ci, 0, sizeof(ci)); + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; -- cgit v1.2.3 From 287d37e2e63549398bc248043572c4fda86e9733 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 20 Mar 2015 17:41:43 +0000 Subject: UPSTREAM: net: validate the range we feed to iov_iter_init() in sys_sendto/sys_recvfrom (cherry pick from commit 4de930efc23b92ddf88ce91c405ee645fe6e27ea) Cc: stable@vger.kernel.org # v3.19 Signed-off-by: Al Viro Signed-off-by: David S. Miller Bug: 28759139 Change-Id: I556eab62bc545f4382f93d0c721df342bbe76787 --- net/socket.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/socket.c b/net/socket.c index 5c6ba2bb1385..6f886c4857da 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1824,6 +1824,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, if (len > INT_MAX) len = INT_MAX; + if (unlikely(!access_ok(VERIFY_READ, buff, len))) + return -EFAULT; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; @@ -1883,6 +1885,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, if (size > INT_MAX) size = INT_MAX; + if (unlikely(!access_ok(VERIFY_WRITE, ubuf, size))) + return -EFAULT; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) goto out; -- cgit v1.2.3 From 149b99add8e08c1dc943e1ef945ce837325d431a Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Wed, 15 Jun 2016 17:28:49 -0600 Subject: msm: kgsl: Read HLSQ SP/TP registers through debug aperture Use crash dumper to read HLSQ SP/TP registers through debug ahb aperture during device snapshot. Bug: 30907663 CRs-Fixed: 1019957 Change-Id: I3b18fd0d1eab28b6b3e5d314539cfbc15210f675 Signed-off-by: Harshdeep Dhatt Signed-off-by: Siqi Lin --- drivers/gpu/msm/adreno_a5xx_snapshot.c | 158 ++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/msm/adreno_a5xx_snapshot.c b/drivers/gpu/msm/adreno_a5xx_snapshot.c index 970fd12858ad..6e69c2192ebd 100644 --- a/drivers/gpu/msm/adreno_a5xx_snapshot.c +++ b/drivers/gpu/msm/adreno_a5xx_snapshot.c @@ -419,49 +419,49 @@ static const unsigned int a5xx_registers[] = { 0xB000, 0xB97F, 0xB9A0, 0xB9BF, }; -/* - * The HLSQ registers can only be read via the crash dumper (not AHB) so they - * need to be in their own array because the array above does double duty for - * the fallback path too - */ -static const unsigned int a5xx_hlsq_registers[] = { +struct a5xx_hlsq_sp_tp_regs { + unsigned int statetype; + unsigned int ahbaddr; + unsigned int size; + uint64_t offset; +}; + +static struct a5xx_hlsq_sp_tp_regs a5xx_hlsq_sp_tp_registers[] = { + /* HSLQ non context. 0xe32 - 0xe3f are holes so don't include them */ + { 0x35, 0xE00, 0x32 }, + /* HLSQ CTX 0 2D */ + { 0x31, 0x2080, 0x1 }, + /* HLSQ CTX 1 2D */ + { 0x33, 0x2480, 0x1 }, + /* HLSQ CTX 0 3D. 0xe7e2 - 0xe7ff are holes so don't inculde them */ + { 0x32, 0xE780, 0x62 }, + /* HLSQ CTX 1 3D. 0xefe2 - 0xefff are holes so don't include them */ + { 0x34, 0xEF80, 0x62 }, + /* SP non context */ - 0x0EC0, 0xEC2, 0xED0, 0xEE0, 0xEF0, 0xEF2, 0xEFA, 0xEFF, + { 0x3f, 0x0EC0, 0x40 }, /* SP CTX 0 2D */ - 0x2040, 0x2040, + { 0x3d, 0x2040, 0x1 }, /* SP CTX 1 2D */ - 0x2440, 0x2440, - /* SP CTXT 0 3D */ - 0xE580, 0xE580, 0xE584, 0xE58B, 0xE590, 0xE5B1, 0xE5C0, 0xE5DF, - 0xE5F0, 0xE5F9, 0xE600, 0xE608, 0xE610, 0xE631, 0xE640, 0xE661, - 0xE670, 0xE673, 0xE6F0, 0xE6F0, - /* SP CTXT 1 3D */ - 0xED80, 0xED80, 0xED84, 0xED8B, 0xED90, 0xEDB1, 0xEDC0, 0xEDDF, - 0xEDF0, 0xEDF9, 0xEE00, 0xEE08, 0xEE10, 0xEE31, 0xEE40, 0xEE61, - 0xEE70, 0xEE73, 0xEEF0, 0xEEF0, - /* TP non context */ - 0xF00, 0xF03, 0xF08, 0xF08, 0xF10, 0xF1B, - /* TP CTX 0 2D */ - 0x2000, 0x2009, - /* TP CTX 1 2D */ - 0x2400, 0x2409, + { 0x3b, 0x2440, 0x1 }, + /* SP CTX 0 3D */ + { 0x3e, 0xE580, 0x180 }, + /* SP CTX 1 3D */ + { 0x3c, 0xED80, 0x180 }, + + /* TP non context. 0x0f1c - 0x0f3f are holes so don't include them */ + { 0x3a, 0x0F00, 0x1c }, + /* TP CTX 0 2D. 0x200a - 0x200f are holes so don't include them */ + { 0x38, 0x2000, 0xa }, + /* TP CTX 1 2D. 0x240a - 0x240f are holes so don't include them */ + { 0x36, 0x2400, 0xa }, /* TP CTX 0 3D */ - 0xE700, 0xE707, 0xE70E, 0xE731, - 0xE750, 0xE751, 0xE75A, 0xE764, 0xE76C, 0xE77F, + { 0x39, 0xE700, 0x80 }, /* TP CTX 1 3D */ - 0xEF00, 0xEF07, 0xEF0E, 0xEF31, - 0xEF50, 0xEF51, 0xEF5A, 0xEF64, 0xEF6C, 0xEF7F, - /* HLSQ non context */ - 0xE00, 0xE01, 0xE04, 0xE06, 0xE08, 0xE09, 0xE10, 0xE17, - 0xE20, 0xE25, - /* HLSQ CTXT 0 3D */ - 0xE784, 0xE789, 0xE78B, 0xE796, 0xE7A0, 0xE7A2, 0xE7B0, 0xE7BB, - 0xE7C0, 0xE7DD, 0xE7E0, 0xE7E1, - /* HLSQ CTXT 1 3D */ - 0xEF84, 0xEF89, 0xEF8B, 0xEF96, 0xEFA0, 0xEFA2, 0xEFB0, 0xEFBB, - 0xEFC0, 0xEFDD, 0xEFE0, 0xEFE1, + { 0x37, 0xEF00, 0x80 }, }; + #define A5XX_NUM_SHADER_BANKS 4 #define A5XX_SHADER_STATETYPE_SHIFT 8 @@ -657,7 +657,6 @@ static struct cdregs { unsigned int size; } _a5xx_cd_registers[] = { { a5xx_registers, ARRAY_SIZE(a5xx_registers) }, - { a5xx_hlsq_registers, ARRAY_SIZE(a5xx_hlsq_registers) }, }; #define REG_PAIR_COUNT(_a, _i) \ @@ -781,6 +780,46 @@ static void _a5xx_do_crashdump(struct kgsl_device *device) crash_dump_valid = true; } +static int get_hlsq_registers(struct kgsl_device *device, + const struct a5xx_hlsq_sp_tp_regs *regs, unsigned int *data) +{ + unsigned int i; + unsigned int *src = registers.hostptr + regs->offset; + + for (i = 0; i < regs->size; i++) { + *data++ = regs->ahbaddr + i; + *data++ = *(src + i); + } + + return (2 * regs->size); +} + +static size_t a5xx_snapshot_dump_hlsq_sp_tp_regs(struct kgsl_device *device, + u8 *buf, size_t remain, void *priv) +{ + struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf; + unsigned int *data = (unsigned int *)(buf + sizeof(*header)); + int count = 0, i; + + /* Figure out how many registers we are going to dump */ + for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++) + count += a5xx_hlsq_sp_tp_registers[i].size; + + if (remain < (count * 8) + sizeof(*header)) { + SNAPSHOT_ERR_NOMEM(device, "REGISTERS"); + return 0; + } + + for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++) + data += get_hlsq_registers(device, + &a5xx_hlsq_sp_tp_registers[i], data); + + header->count = count; + + /* Return the size of the section */ + return (count * 8) + sizeof(*header); +} + /* * a5xx_snapshot() - A5XX GPU snapshot function * @adreno_dev: Device being snapshotted @@ -811,6 +850,10 @@ void a5xx_snapshot(struct adreno_device *adreno_dev, a5xx_vbif_snapshot_registers, ARRAY_SIZE(a5xx_vbif_snapshot_registers)); + /* Dump SP TP HLSQ registers */ + kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot, + a5xx_snapshot_dump_hlsq_sp_tp_regs, NULL); + /* CP_PFP indexed registers */ kgsl_snapshot_indexed_registers(device, snapshot, A5XX_CP_PFP_STAT_ADDR, A5XX_CP_PFP_STAT_DATA, @@ -883,8 +926,8 @@ void a5xx_snapshot(struct adreno_device *adreno_dev, } -static int _a5xx_crashdump_init(struct a5xx_shader_block *block, uint64_t *ptr, - uint64_t *offset) +static int _a5xx_crashdump_init_shader(struct a5xx_shader_block *block, + uint64_t *ptr, uint64_t *offset) { int qwords = 0; unsigned int j; @@ -913,6 +956,31 @@ static int _a5xx_crashdump_init(struct a5xx_shader_block *block, uint64_t *ptr, return qwords; } +static int _a5xx_crashdump_init_hlsq(struct a5xx_hlsq_sp_tp_regs *regs, + uint64_t *ptr, uint64_t *offset) +{ + int qwords = 0; + + /* Program the aperture */ + ptr[qwords++] = + (regs->statetype << A5XX_SHADER_STATETYPE_SHIFT); + ptr[qwords++] = (((uint64_t) A5XX_HLSQ_DBG_READ_SEL << 44)) | + (1 << 21) | 1; + + /* Read all the data in one chunk */ + ptr[qwords++] = registers.gpuaddr + *offset; + ptr[qwords++] = + (((uint64_t) A5XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) | + regs->size; + + /* Remember the offset of the first bank for easy access */ + regs->offset = *offset; + + *offset += regs->size * sizeof(unsigned int); + + return qwords; +} + void a5xx_crashdump_init(struct adreno_device *adreno_dev) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); @@ -959,6 +1027,11 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev) data_size += a5xx_shader_blocks[i].sz * sizeof(unsigned int) * A5XX_NUM_SHADER_BANKS; } + for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++) { + script_size += 32; + data_size += + a5xx_hlsq_sp_tp_registers[i].size * sizeof(unsigned int); + } /* Now allocate the script and data buffers */ @@ -973,7 +1046,6 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev) kgsl_free_global(KGSL_DEVICE(adreno_dev), &capturescript); return; } - /* Build the crash script */ ptr = (uint64_t *) capturescript.hostptr; @@ -992,9 +1064,13 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev) /* Program each shader block */ for (i = 0; i < ARRAY_SIZE(a5xx_shader_blocks); i++) { - ptr += _a5xx_crashdump_init(&a5xx_shader_blocks[i], ptr, + ptr += _a5xx_crashdump_init_shader(&a5xx_shader_blocks[i], ptr, &offset); } + /* Program the hlsq sp tp register sets */ + for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++) + ptr += _a5xx_crashdump_init_hlsq(&a5xx_hlsq_sp_tp_registers[i], + ptr, &offset); *ptr++ = 0; *ptr++ = 0; -- cgit v1.2.3 From 53dc26e43577b3ee67648c27ce5ea6193052f27a Mon Sep 17 00:00:00 2001 From: Naseer Ahmed Date: Fri, 26 Aug 2016 18:00:43 -0400 Subject: mdss: protect sysfs panel settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VR low persistence mode sends DSI commands out-of-band through a sysfs node instead of through HWC ಠ_ಠ. Do not allow sysfs panel settings such as low persistence mode from sending DSI commands when the panel is blank and do not blank the device when a configuration update from sysfs is in progress. Bug: 31036253 Change-Id: I5fb26a8b01ae144a87209a5d212b4ab6c1685565 Signed-off-by: Dhaval Patel Signed-off-by: Aravind Venkateswaran Signed-off-by: Naseer Ahmed --- drivers/video/msm/mdss/mdss_fb.c | 21 +++++++++++++++++++-- drivers/video/msm/mdss/mdss_fb.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index fa5f64cd7767..6e28ec73f564 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -1191,6 +1191,7 @@ static int mdss_fb_probe(struct platform_device *pdev) INIT_LIST_HEAD(&mfd->file_list); mutex_init(&mfd->bl_lock); + mutex_init(&mfd->sysfs_settings_lock); mutex_init(&mfd->switch_lock); fbi_list[fbi_list_index++] = fbi; @@ -1958,6 +1959,8 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info) return ret; } + mutex_lock(&mfd->sysfs_settings_lock); + if (mfd->op_enable == 0) { if (blank_mode == FB_BLANK_UNBLANK) mfd->suspend.panel_power_state = MDSS_PANEL_POWER_ON; @@ -1967,7 +1970,8 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info) mfd->suspend.panel_power_state = MDSS_PANEL_POWER_LP1; else mfd->suspend.panel_power_state = MDSS_PANEL_POWER_OFF; - return 0; + ret = 0; + goto end; } pr_debug("mode: %d\n", blank_mode); @@ -1981,7 +1985,11 @@ static int mdss_fb_blank(int blank_mode, struct fb_info *info) pdata->panel_info.is_lpm_mode = false; } - return mdss_fb_blank_sub(blank_mode, info, mfd->op_enable); + ret = mdss_fb_blank_sub(blank_mode, info, mfd->op_enable); +end: + mutex_unlock(&mfd->sysfs_settings_lock); + + return ret; } static inline int mdss_fb_create_ion_client(struct msm_fb_data_type *mfd) @@ -4587,6 +4595,12 @@ static int mdss_fb_set_display_setting(struct msm_fb_data_type *mfd, if (!mfd || !mfd->panel_info) return -EINVAL; + mutex_lock(&mfd->sysfs_settings_lock); + if (mdss_panel_is_power_off(mfd->panel_power_state)) { + ret = -EINVAL; + goto end; + } + pinfo = mfd->panel_info; mutex_lock(&mfd->bl_lock); @@ -4595,6 +4609,9 @@ static int mdss_fb_set_display_setting(struct msm_fb_data_type *mfd, ret = pdata->apply_display_setting(pdata, setting, mode); mutex_unlock(&mfd->bl_lock); +end: + mutex_unlock(&mfd->sysfs_settings_lock); + return ret; } diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h index 56997e40d244..bc6194499b7d 100644 --- a/drivers/video/msm/mdss/mdss_fb.h +++ b/drivers/video/msm/mdss/mdss_fb.h @@ -304,6 +304,7 @@ struct msm_fb_data_type { bool allow_bl_update; u32 bl_level_scaled; struct mutex bl_lock; + struct mutex sysfs_settings_lock; bool ipc_resume; struct platform_device *pdev; -- cgit v1.2.3 From 96e033488266512fedc88cfbdb346b7d61a579fe Mon Sep 17 00:00:00 2001 From: vivek mehta Date: Tue, 30 Aug 2016 19:42:30 -0700 Subject: ASoC: wcd9335: Fix race during codec master clock (mclk) enablement It is possible that codec master clock enablement could race from two different execution contexts, causing the mclk to be not enabled at all. This will result in failure of use cases that expect the clock to be present. Fix this issue by making sure the race condition does not occur during mclk enablement. Bug: 30983442 Change-Id: Ie254b8876524956b816267eaaed205f65641c000 Signed-off-by: Bhalchandra Gajare Signed-off-by: vivek mehta --- sound/soc/codecs/wcd9335.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 46125b73fc9d..926ae130e92d 100755 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -825,6 +825,9 @@ struct tasha_priv { int rx_8_count; bool clk_mode; bool clk_internal; + + /* Lock to protect mclk enablement */ + struct mutex mclk_lock; }; static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec, @@ -965,13 +968,14 @@ static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha, { int ret = 0; + mutex_lock(&tasha->mclk_lock); if (enable) { tasha_cdc_sido_ccl_enable(tasha, true); ret = clk_prepare_enable(tasha->wcd_ext_clk); if (ret) { dev_err(tasha->dev, "%s: ext clk enable failed\n", __func__); - goto err; + goto unlock_mutex; } /* get BG */ wcd_resmgr_enable_master_bias(tasha->resmgr); @@ -985,7 +989,8 @@ static int tasha_cdc_req_mclk_enable(struct tasha_priv *tasha, clk_disable_unprepare(tasha->wcd_ext_clk); tasha_cdc_sido_ccl_enable(tasha, false); } -err: +unlock_mutex: + mutex_unlock(&tasha->mclk_lock); return ret; } @@ -13684,6 +13689,7 @@ static int tasha_probe(struct platform_device *pdev) mutex_init(&tasha->swr_read_lock); mutex_init(&tasha->swr_write_lock); mutex_init(&tasha->swr_clk_lock); + mutex_init(&tasha->mclk_lock); cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region), GFP_KERNEL); @@ -13781,6 +13787,7 @@ static int tasha_remove(struct platform_device *pdev) clk_put(tasha->wcd_ext_clk); if (tasha->wcd_native_clk) clk_put(tasha->wcd_native_clk); + mutex_destroy(&tasha->mclk_lock); devm_kfree(&pdev->dev, tasha); snd_soc_unregister_codec(&pdev->dev); return 0; -- cgit v1.2.3 From ad62b26e4592fe77243bf9daf5af6de11ffadbbe Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Fri, 2 Sep 2016 16:04:41 -0700 Subject: lowmemorykiller: account for unevictable pages lowmemorykiller was not taking into account unevictable pages when deciding what level to kill. If significant amounts of memory were pinned, this caused lowmemorykiller to effectively stop at a much higher level than it should. bug 31255977 Change-Id: I763ecbfef8c56d65bb8f6147ae810692bd81b6e2 --- drivers/staging/android/lowmemorykiller.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 7e41ccf0c10e..6fe48eb9bda4 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -92,6 +92,7 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages; int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM) - + global_page_state(NR_UNEVICTABLE) - total_swapcache_pages(); if (lowmem_adj_size < array_size) -- cgit v1.2.3 -- cgit v1.2.3 From b976b264087c32b713445d3804c713c3795d5e10 Mon Sep 17 00:00:00 2001 From: Howard Yen Date: Mon, 5 Sep 2016 20:38:25 +0800 Subject: arm64: dts: marlin: modify USB2.0 phy settings USB HS Reg 0x90=Val 0x03 Bug: 31206266 Change-Id: Ie07898c71ce5c9008ea423fb6f22f1ac6f9b9b56 Signed-off-by: Howard Yen --- arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi | 1 + arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi b/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi index 394012b14b15..de5b191f0d57 100644 --- a/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi +++ b/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi @@ -124,6 +124,7 @@ 0x51 0x84 0x81 0x88 0xC0 0x8C + 0x03 0x90 0x30 0x08 0x79 0x0C 0x21 0x10 diff --git a/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi b/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi index ecc5fa3fbd85..039d74b3c040 100644 --- a/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi +++ b/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi @@ -19,6 +19,7 @@ 0x23 0x84 0x81 0x88 0xC0 0x8C + 0x03 0x90 0x30 0x08 0x79 0x0C 0x21 0x10 -- cgit v1.2.3 From 3158ee49960462ca4f302c8f8409ad443cdf508e Mon Sep 17 00:00:00 2001 From: "Yueyao (Nathan) Zhu" Date: Fri, 9 Sep 2016 20:16:17 +0000 Subject: Revert "arm64: dts: marlin: modify USB2.0 phy settings" This reverts commit b976b264087c32b713445d3804c713c3795d5e10. Change-Id: I78a67c861daa881a90e98abf94a35da5582d4f4b --- arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi | 1 - arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi b/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi index de5b191f0d57..394012b14b15 100644 --- a/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi +++ b/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi @@ -124,7 +124,6 @@ 0x51 0x84 0x81 0x88 0xC0 0x8C - 0x03 0x90 0x30 0x08 0x79 0x0C 0x21 0x10 diff --git a/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi b/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi index 039d74b3c040..ecc5fa3fbd85 100644 --- a/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi +++ b/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi @@ -19,7 +19,6 @@ 0x23 0x84 0x81 0x88 0xC0 0x8C - 0x03 0x90 0x30 0x08 0x79 0x0C 0x21 0x10 -- cgit v1.2.3 From e62667b4a5ba40e93ff0926531a8ddef4bfedb35 Mon Sep 17 00:00:00 2001 From: Steve Pfetsch Date: Sun, 11 Sep 2016 01:51:21 -0700 Subject: arm64: dts: marlin/sailfish: add default values for haptics Add default values for vmax-strong-mv, vmax-light-mv, and timeout-strong-threshold, which control the intensity of haptic feedback and the length of pulse necessary to trigger strong vibration. Bug: 31407746 Change-Id: Ie0e22fea2591343b3006d5f2171ea0a6936e6233 --- arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi | 3 +++ arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi b/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi index 394012b14b15..2d7842a7bdcc 100644 --- a/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi +++ b/arch/arm64/boot/dts/htc/msm8996-htc_marlin.dtsi @@ -268,6 +268,9 @@ qcom,actuator-type = "lra"; qcom,wave-shape = "sine"; qcom,vmax-mv = <3596>; + qcom,vmax-strong-mv = <3596>; + qcom,vmax-light-mv = <1600>; + qcom,timeout-strong-threshold = <330>; qcom,brake-pattern = [03 03 03 03]; }; diff --git a/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi b/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi index ecc5fa3fbd85..242a050f65b1 100644 --- a/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi +++ b/arch/arm64/boot/dts/htc/msm8996-htc_sailfish.dtsi @@ -135,4 +135,7 @@ &pmi8994_haptics { qcom,vmax-mv = <3132>; + qcom,vmax-strong-mv = <3132>; + qcom,vmax-light-mv = <2200>; + qcom,timeout-strong-threshold = <330>; }; -- cgit v1.2.3 From 895c4a66de92219859cf5939fefb0e4d6fbb1391 Mon Sep 17 00:00:00 2001 From: Steve Pfetsch Date: Sat, 10 Sep 2016 18:19:19 -0700 Subject: msm: haptic: reduce haptic intensity except for calls and messages Introduce a haptic duration threshold below which vibration intensity is automatically reduced. The intensity of brief vibration is reduced so that keyboard, touch, and fingerprint haptics are less audible. Add sysfs nodes for accessing the threshold and the strong/light intensity settings. Bug: 31407746 Change-Id: Ib4704a38255f3171bb13fc2ecc0201940ffa8767 --- drivers/platform/msm/qpnp-haptic.c | 151 +++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/drivers/platform/msm/qpnp-haptic.c b/drivers/platform/msm/qpnp-haptic.c index 5c3da0f46a49..e9ea721f39ba 100755 --- a/drivers/platform/msm/qpnp-haptic.c +++ b/drivers/platform/msm/qpnp-haptic.c @@ -81,6 +81,9 @@ #define QPNP_HAP_VMAX_SHIFT 1 #define QPNP_HAP_VMAX_MIN_MV 116 #define QPNP_HAP_VMAX_MAX_MV 3596 +#define QPNP_HAP_VMAX_STRONG_MV 3596 +#define QPNP_HAP_VMAX_LIGHT_MV 500 +#define QPNP_HAP_STRONG_THRESHOLD 330 #define QPNP_HAP_ILIM_MASK 0xFE #define QPNP_HAP_ILIM_MIN_MV 400 #define QPNP_HAP_ILIM_MAX_MV 800 @@ -259,6 +262,9 @@ struct qpnp_pwm_info { * @ time_required_to_generate_back_emf_us - the time required for sufficient back-emf to be generated for auto resonance to be successful * @ vmax_mv - max voltage in mv + * @ timeout_strong_threshold - minimum duration of a strong pulse in ms + * @ vmax_strong_mv - voltage used for a strong pulse in mv + * @ vmax_light_mv - voltage used for a light pulse in mv * @ ilim_ma - limiting current in ma * @ sc_deb_cycles - short circuit debounce cycles * @ int_pwm_freq_khz - internal pwm frequency in khz @@ -310,6 +316,9 @@ struct qpnp_hap { u32 timeout_ms; u32 time_required_to_generate_back_emf_us; u32 vmax_mv; + u32 timeout_strong_threshold; + u32 vmax_strong_mv; + u32 vmax_light_mv; u32 ilim_ma; u32 sc_deb_cycles; u32 int_pwm_freq_khz; @@ -1012,6 +1021,108 @@ static ssize_t qpnp_hap_wf_s7_store(struct device *dev, return qpnp_hap_wf_samp_store(dev, buf, count, 7); } +/* sysfs show for timeout_strong_threshold update */ +static ssize_t qpnp_hap_timeout_strong_threshold_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->timeout_strong_threshold); +} + +/* sysfs store for timeout_strong_threshold */ +static ssize_t qpnp_hap_timeout_strong_threshold_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + u32 val; + ssize_t ret; + + ret = kstrtou32(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&hap->wf_lock); + hap->timeout_strong_threshold = val; + mutex_unlock(&hap->wf_lock); + + return count; +} + +/* sysfs show for vmax_strong_mv update */ +static ssize_t qpnp_hap_vmax_strong_mv_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vmax_strong_mv); +} + +/* sysfs store for vmax_strong_mv */ +static ssize_t qpnp_hap_vmax_strong_mv_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + u32 val; + ssize_t ret; + + ret = kstrtou32(buf, 10, &val); + if (ret) + return ret; + + if ((val < QPNP_HAP_VMAX_MIN_MV) || (val > QPNP_HAP_VMAX_MAX_MV)) + return -EINVAL; + + mutex_lock(&hap->wf_lock); + hap->vmax_strong_mv = val; + mutex_unlock(&hap->wf_lock); + + return count; +} + +/* sysfs show for vmax_light_mv update */ +static ssize_t qpnp_hap_vmax_light_mv_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", hap->vmax_light_mv); +} + +/* sysfs store for vmax_light_mv */ +static ssize_t qpnp_hap_vmax_light_mv_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct timed_output_dev *timed_dev = dev_get_drvdata(dev); + struct qpnp_hap *hap = container_of(timed_dev, struct qpnp_hap, + timed_dev); + u32 val; + ssize_t ret; + + ret = kstrtou32(buf, 10, &val); + if (ret) + return ret; + + if ((val < QPNP_HAP_VMAX_MIN_MV) || (val > QPNP_HAP_VMAX_MAX_MV)) + return -EINVAL; + + mutex_lock(&hap->wf_lock); + hap->vmax_light_mv = val; + mutex_unlock(&hap->wf_lock); + + return count; +} + /* sysfs show for wave form update */ static ssize_t qpnp_hap_wf_update_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1394,6 +1505,15 @@ static struct device_attribute qpnp_hap_attrs[] = { __ATTR(min_max_test, (S_IRUGO | S_IWUSR | S_IWGRP), qpnp_hap_min_max_test_data_show, qpnp_hap_min_max_test_data_store), + __ATTR(timeout_strong_threshold, (S_IRUGO | S_IWUSR | S_IWGRP), + qpnp_hap_timeout_strong_threshold_show, + qpnp_hap_timeout_strong_threshold_store), + __ATTR(vmax_strong_mv, (S_IRUGO | S_IWUSR | S_IWGRP), + qpnp_hap_vmax_strong_mv_show, + qpnp_hap_vmax_strong_mv_store), + __ATTR(vmax_light_mv, (S_IRUGO | S_IWUSR | S_IWGRP), + qpnp_hap_vmax_light_mv_show, + qpnp_hap_vmax_light_mv_store), }; static void calculate_lra_code(struct qpnp_hap *hap) @@ -1635,7 +1755,17 @@ static void qpnp_hap_td_enable(struct timed_output_dev *dev, int value) } hap->state = 0; } else { + u32 new_vmax_mv; VIB_DBG_LOG("enable=%d.\n", value); + + /* Reduce intensity if outside call/message duration */ + new_vmax_mv = (value >= hap->timeout_strong_threshold) ? + hap->vmax_strong_mv : hap->vmax_light_mv; + if (new_vmax_mv != hap->vmax_mv) { + hap->vmax_mv = new_vmax_mv; + qpnp_hap_vmax_config(hap); + } + value = (value > hap->timeout_ms ? hap->timeout_ms : value); hap->state = 1; @@ -2205,6 +2335,27 @@ static int qpnp_hap_parse_dt(struct qpnp_hap *hap) return rc; } + hap->timeout_strong_threshold = QPNP_HAP_STRONG_THRESHOLD; + rc = of_property_read_u32(spmi->dev.of_node, + "qcom,timeout-strong-threshold", &temp); + if (!rc) { + hap->timeout_strong_threshold = temp; + } + + hap->vmax_strong_mv = QPNP_HAP_VMAX_STRONG_MV; + rc = of_property_read_u32(spmi->dev.of_node, + "qcom,vmax-strong-mv", &temp); + if (!rc) { + hap->vmax_strong_mv = temp; + } + + hap->vmax_light_mv = QPNP_HAP_VMAX_LIGHT_MV; + rc = of_property_read_u32(spmi->dev.of_node, + "qcom,vmax-light-mv", &temp); + if (!rc) { + hap->vmax_light_mv = temp; + } + hap->ilim_ma = QPNP_HAP_ILIM_MIN_MV; rc = of_property_read_u32(spmi->dev.of_node, "qcom,ilim-ma", &temp); -- cgit v1.2.3 From a41329dce2fef8359fdf4e94a736fd7b8f53d663 Mon Sep 17 00:00:00 2001 From: Omar Sandoval Date: Fri, 1 Jul 2016 00:39:35 -0700 Subject: UPSTREAM: block: fix use-after-free in sys_ioprio_get() get_task_ioprio() accesses the task->io_context without holding the task lock and thus can race with exit_io_context(), leading to a use-after-free. The reproducer below hits this within a few seconds on my 4-core QEMU VM: int main(int argc, char **argv) { pid_t pid, child; long nproc, i; /* ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)); */ syscall(SYS_ioprio_set, 1, 0, 0x6000); nproc = sysconf(_SC_NPROCESSORS_ONLN); for (i = 0; i < nproc; i++) { pid = fork(); assert(pid != -1); if (pid == 0) { for (;;) { pid = fork(); assert(pid != -1); if (pid == 0) { _exit(0); } else { child = wait(NULL); assert(child == pid); } } } pid = fork(); assert(pid != -1); if (pid == 0) { for (;;) { /* ioprio_get(IOPRIO_WHO_PGRP, 0); */ syscall(SYS_ioprio_get, 2, 0); } } } for (;;) { /* ioprio_get(IOPRIO_WHO_PGRP, 0); */ syscall(SYS_ioprio_get, 2, 0); } return 0; } This gets us KASAN dumps like this: [ 35.526914] ================================================================== [ 35.530009] BUG: KASAN: out-of-bounds in get_task_ioprio+0x7b/0x90 at addr ffff880066f34e6c [ 35.530009] Read of size 2 by task ioprio-gpf/363 [ 35.530009] ============================================================================= [ 35.530009] BUG blkdev_ioc (Not tainted): kasan: bad access detected [ 35.530009] ----------------------------------------------------------------------------- [ 35.530009] Disabling lock debugging due to kernel taint [ 35.530009] INFO: Allocated in create_task_io_context+0x2b/0x370 age=0 cpu=0 pid=360 [ 35.530009] ___slab_alloc+0x55d/0x5a0 [ 35.530009] __slab_alloc.isra.20+0x2b/0x40 [ 35.530009] kmem_cache_alloc_node+0x84/0x200 [ 35.530009] create_task_io_context+0x2b/0x370 [ 35.530009] get_task_io_context+0x92/0xb0 [ 35.530009] copy_process.part.8+0x5029/0x5660 [ 35.530009] _do_fork+0x155/0x7e0 [ 35.530009] SyS_clone+0x19/0x20 [ 35.530009] do_syscall_64+0x195/0x3a0 [ 35.530009] return_from_SYSCALL_64+0x0/0x6a [ 35.530009] INFO: Freed in put_io_context+0xe7/0x120 age=0 cpu=0 pid=1060 [ 35.530009] __slab_free+0x27b/0x3d0 [ 35.530009] kmem_cache_free+0x1fb/0x220 [ 35.530009] put_io_context+0xe7/0x120 [ 35.530009] put_io_context_active+0x238/0x380 [ 35.530009] exit_io_context+0x66/0x80 [ 35.530009] do_exit+0x158e/0x2b90 [ 35.530009] do_group_exit+0xe5/0x2b0 [ 35.530009] SyS_exit_group+0x1d/0x20 [ 35.530009] entry_SYSCALL_64_fastpath+0x1a/0xa4 [ 35.530009] INFO: Slab 0xffffea00019bcd00 objects=20 used=4 fp=0xffff880066f34ff0 flags=0x1fffe0000004080 [ 35.530009] INFO: Object 0xffff880066f34e58 @offset=3672 fp=0x0000000000000001 [ 35.530009] ================================================================== Fix it by grabbing the task lock while we poke at the io_context. Cc: stable@vger.kernel.org Reported-by: Dmitry Vyukov Signed-off-by: Omar Sandoval Signed-off-by: Jens Axboe (cherry picked from commit 8ba8682107ee2ca3347354e018865d8e1967c5f4) Bug: 30946378 Change-Id: Ib387abc9c64bcf45c6a5b9ea7439347f2b4a7f7f --- block/ioprio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/ioprio.c b/block/ioprio.c index 31666c92b46a..563435684c3c 100644 --- a/block/ioprio.c +++ b/block/ioprio.c @@ -149,8 +149,10 @@ static int get_task_ioprio(struct task_struct *p) if (ret) goto out; ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM); + task_lock(p); if (p->io_context) ret = p->io_context->ioprio; + task_unlock(p); out: return ret; } -- cgit v1.2.3 From bc912ddcff771d0d7f6feeb64f3b65e785c1d1e0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 17 Aug 2016 05:56:26 -0700 Subject: UPSTREAM: tcp: fix use after free in tcp_xmit_retransmit_queue() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit bb1fceca22492109be12640d49f5ea5a544c6bb4) When tcp_sendmsg() allocates a fresh and empty skb, it puts it at the tail of the write queue using tcp_add_write_queue_tail() Then it attempts to copy user data into this fresh skb. If the copy fails, we undo the work and remove the fresh skb. Unfortunately, this undo lacks the change done to tp->highest_sack and we can leave a dangling pointer (to a freed skb) Later, tcp_xmit_retransmit_queue() can dereference this pointer and access freed memory. For regular kernels where memory is not unmapped, this might cause SACK bugs because tcp_highest_sack_seq() is buggy, returning garbage instead of tp->snd_nxt, but with various debug features like CONFIG_DEBUG_PAGEALLOC, this can crash the kernel. This bug was found by Marco Grassi thanks to syzkaller. Fixes: 6859d49475d4 ("[TCP]: Abstract tp->highest_sack accessing & point to next skb") Reported-by: Marco Grassi Signed-off-by: Eric Dumazet Cc: Ilpo Järvinen Cc: Yuchung Cheng Cc: Neal Cardwell Acked-by: Neal Cardwell Reviewed-by: Cong Wang Signed-off-by: David S. Miller Change-Id: I58bb02d6e4e399612e8580b9e02d11e661df82f5 Bug: 31183296 --- include/net/tcp.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/tcp.h b/include/net/tcp.h index b35a773acf29..638d2fe5393d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1448,6 +1448,8 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli { if (sk->sk_send_head == skb_unlinked) sk->sk_send_head = NULL; + if (tcp_sk(sk)->highest_sack == skb_unlinked) + tcp_sk(sk)->highest_sack = NULL; } static inline void tcp_init_send_head(struct sock *sk) -- cgit v1.2.3 From 2fd70548d5cf62237610f1100f0e926d0b109916 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 28 Jan 2016 09:22:44 -0200 Subject: UPSTREAM: [media] xc2028: avoid use after free If struct xc2028_config is passed without a firmware name, the following trouble may happen: [11009.907205] xc2028 5-0061: type set to XCeive xc2028/xc3028 tuner [11009.907491] ================================================================== [11009.907750] BUG: KASAN: use-after-free in strcmp+0x96/0xb0 at addr ffff8803bd78ab40 [11009.907992] Read of size 1 by task modprobe/28992 [11009.907994] ============================================================================= [11009.907997] BUG kmalloc-16 (Tainted: G W ): kasan: bad access detected [11009.907999] ----------------------------------------------------------------------------- [11009.908008] INFO: Allocated in xhci_urb_enqueue+0x214/0x14c0 [xhci_hcd] age=0 cpu=3 pid=28992 [11009.908012] ___slab_alloc+0x581/0x5b0 [11009.908014] __slab_alloc+0x51/0x90 [11009.908017] __kmalloc+0x27b/0x350 [11009.908022] xhci_urb_enqueue+0x214/0x14c0 [xhci_hcd] [11009.908026] usb_hcd_submit_urb+0x1e8/0x1c60 [11009.908029] usb_submit_urb+0xb0e/0x1200 [11009.908032] usb_serial_generic_write_start+0xb6/0x4c0 [11009.908035] usb_serial_generic_write+0x92/0xc0 [11009.908039] usb_console_write+0x38a/0x560 [11009.908045] call_console_drivers.constprop.14+0x1ee/0x2c0 [11009.908051] console_unlock+0x40d/0x900 [11009.908056] vprintk_emit+0x4b4/0x830 [11009.908061] vprintk_default+0x1f/0x30 [11009.908064] printk+0x99/0xb5 [11009.908067] kasan_report_error+0x10a/0x550 [11009.908070] __asan_report_load1_noabort+0x43/0x50 [11009.908074] INFO: Freed in xc2028_set_config+0x90/0x630 [tuner_xc2028] age=1 cpu=3 pid=28992 [11009.908077] __slab_free+0x2ec/0x460 [11009.908080] kfree+0x266/0x280 [11009.908083] xc2028_set_config+0x90/0x630 [tuner_xc2028] [11009.908086] xc2028_attach+0x310/0x8a0 [tuner_xc2028] [11009.908090] em28xx_attach_xc3028.constprop.7+0x1f9/0x30d [em28xx_dvb] [11009.908094] em28xx_dvb_init.part.3+0x8e4/0x5cf4 [em28xx_dvb] [11009.908098] em28xx_dvb_init+0x81/0x8a [em28xx_dvb] [11009.908101] em28xx_register_extension+0xd9/0x190 [em28xx] [11009.908105] em28xx_dvb_register+0x10/0x1000 [em28xx_dvb] [11009.908108] do_one_initcall+0x141/0x300 [11009.908111] do_init_module+0x1d0/0x5ad [11009.908114] load_module+0x6666/0x9ba0 [11009.908117] SyS_finit_module+0x108/0x130 [11009.908120] entry_SYSCALL_64_fastpath+0x16/0x76 [11009.908123] INFO: Slab 0xffffea000ef5e280 objects=25 used=25 fp=0x (null) flags=0x2ffff8000004080 [11009.908126] INFO: Object 0xffff8803bd78ab40 @offset=2880 fp=0x0000000000000001 [11009.908130] Bytes b4 ffff8803bd78ab30: 01 00 00 00 2a 07 00 00 9d 28 00 00 01 00 00 00 ....*....(...... [11009.908133] Object ffff8803bd78ab40: 01 00 00 00 00 00 00 00 b0 1d c3 6a 00 88 ff ff ...........j.... [11009.908137] CPU: 3 PID: 28992 Comm: modprobe Tainted: G B W 4.5.0-rc1+ #43 [11009.908140] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015 [11009.908142] ffff8803bd78a000 ffff8802c273f1b8 ffffffff81932007 ffff8803c6407a80 [11009.908148] ffff8802c273f1e8 ffffffff81556759 ffff8803c6407a80 ffffea000ef5e280 [11009.908153] ffff8803bd78ab40 dffffc0000000000 ffff8802c273f210 ffffffff8155ccb4 [11009.908158] Call Trace: [11009.908162] [] dump_stack+0x4b/0x64 [11009.908165] [] print_trailer+0xf9/0x150 [11009.908168] [] object_err+0x34/0x40 [11009.908171] [] kasan_report_error+0x230/0x550 [11009.908175] [] ? trace_hardirqs_off_caller+0x21/0x290 [11009.908179] [] ? kasan_unpoison_shadow+0x36/0x50 [11009.908182] [] __asan_report_load1_noabort+0x43/0x50 [11009.908185] [] ? __asan_register_globals+0x50/0xa0 [11009.908189] [] ? strcmp+0x96/0xb0 [11009.908192] [] strcmp+0x96/0xb0 [11009.908196] [] xc2028_set_config+0x15c/0x630 [tuner_xc2028] [11009.908200] [] xc2028_attach+0x310/0x8a0 [tuner_xc2028] [11009.908203] [] ? memset+0x28/0x30 [11009.908206] [] ? xc2028_set_config+0x630/0x630 [tuner_xc2028] [11009.908211] [] em28xx_attach_xc3028.constprop.7+0x1f9/0x30d [em28xx_dvb] [11009.908215] [] ? em28xx_dvb_init.part.3+0x37c/0x5cf4 [em28xx_dvb] [11009.908219] [] ? hauppauge_hvr930c_init+0x487/0x487 [em28xx_dvb] [11009.908222] [] ? lgdt330x_attach+0x1cc/0x370 [lgdt330x] [11009.908226] [] ? i2c_read_demod_bytes.isra.2+0x210/0x210 [lgdt330x] [11009.908230] [] ? ref_module.part.15+0x10/0x10 [11009.908233] [] ? module_assert_mutex_or_preempt+0x80/0x80 [11009.908238] [] em28xx_dvb_init.part.3+0x8e4/0x5cf4 [em28xx_dvb] [11009.908242] [] ? em28xx_attach_xc3028.constprop.7+0x30d/0x30d [em28xx_dvb] [11009.908245] [] ? string+0x14d/0x1f0 [11009.908249] [] ? symbol_string+0xff/0x1a0 [11009.908253] [] ? uuid_string+0x6f0/0x6f0 [11009.908257] [] ? __kernel_text_address+0x7e/0xa0 [11009.908260] [] ? print_context_stack+0x7f/0xf0 [11009.908264] [] ? __module_address+0xb6/0x360 [11009.908268] [] ? is_ftrace_trampoline+0x99/0xe0 [11009.908271] [] ? __kernel_text_address+0x7e/0xa0 [11009.908275] [] ? debug_check_no_locks_freed+0x290/0x290 [11009.908278] [] ? dump_trace+0x11b/0x300 [11009.908282] [] ? em28xx_register_extension+0x23/0x190 [em28xx] [11009.908285] [] ? trace_hardirqs_off_caller+0x21/0x290 [11009.908289] [] ? trace_hardirqs_on_caller+0x16/0x590 [11009.908292] [] ? trace_hardirqs_on+0xd/0x10 [11009.908296] [] ? em28xx_register_extension+0x23/0x190 [em28xx] [11009.908299] [] ? mutex_trylock+0x400/0x400 [11009.908302] [] ? do_one_initcall+0x131/0x300 [11009.908306] [] ? call_rcu_sched+0x17/0x20 [11009.908309] [] ? put_object+0x48/0x70 [11009.908314] [] em28xx_dvb_init+0x81/0x8a [em28xx_dvb] [11009.908317] [] em28xx_register_extension+0xd9/0x190 [em28xx] [11009.908320] [] ? 0xffffffffa0150000 [11009.908324] [] em28xx_dvb_register+0x10/0x1000 [em28xx_dvb] [11009.908327] [] do_one_initcall+0x141/0x300 [11009.908330] [] ? try_to_run_init_process+0x40/0x40 [11009.908333] [] ? trace_hardirqs_on_caller+0x16/0x590 [11009.908337] [] ? kasan_unpoison_shadow+0x36/0x50 [11009.908340] [] ? kasan_unpoison_shadow+0x36/0x50 [11009.908343] [] ? kasan_unpoison_shadow+0x36/0x50 [11009.908346] [] ? __asan_register_globals+0x87/0xa0 [11009.908350] [] do_init_module+0x1d0/0x5ad [11009.908353] [] load_module+0x6666/0x9ba0 [11009.908356] [] ? symbol_put_addr+0x50/0x50 [11009.908361] [] ? em28xx_dvb_init.part.3+0x5989/0x5cf4 [em28xx_dvb] [11009.908366] [] ? module_frob_arch_sections+0x20/0x20 [11009.908369] [] ? open_exec+0x50/0x50 [11009.908374] [] ? ns_capable+0x5b/0xd0 [11009.908377] [] SyS_finit_module+0x108/0x130 [11009.908379] [] ? SyS_init_module+0x1f0/0x1f0 [11009.908383] [] ? lockdep_sys_exit_thunk+0x12/0x14 [11009.908394] [] entry_SYSCALL_64_fastpath+0x16/0x76 [11009.908396] Memory state around the buggy address: [11009.908398] ffff8803bd78aa00: 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc [11009.908401] ffff8803bd78aa80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [11009.908403] >ffff8803bd78ab00: fc fc fc fc fc fc fc fc 00 00 fc fc fc fc fc fc [11009.908405] ^ [11009.908407] ffff8803bd78ab80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [11009.908409] ffff8803bd78ac00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [11009.908411] ================================================================== In order to avoid it, let's set the cached value of the firmware name to NULL after freeing it. While here, return an error if the memory allocation fails. Signed-off-by: Mauro Carvalho Chehab (cherry picked from commit 8dfbcc4351a0b6d2f2d77f367552f48ffefafe18) Bug: 30946097 Change-Id: I95d962c55c8c9b39d747cb326de263972331e8cd --- drivers/media/tuners/tuner-xc2028.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index d12f5e4ad8bf..36c7f2a077b4 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -1403,11 +1403,12 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) * in order to avoid troubles during device release. */ kfree(priv->ctrl.fname); + priv->ctrl.fname = NULL; memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); if (p->fname) { priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); if (priv->ctrl.fname == NULL) - rc = -ENOMEM; + return -ENOMEM; } /* -- cgit v1.2.3 From 3ed9ac8b81d38f77b5e1adfaf04d89d8992f89d4 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 14:30:21 -0500 Subject: UPSTREAM: tty: Prevent ldisc drivers from re-using stale tty fields (cherry picked from commit dd42bf1197144ede075a9d4793123f7689e164bc) Line discipline drivers may mistakenly misuse ldisc-related fields when initializing. For example, a failure to initialize tty->receive_room in the N_GIGASET_M101 line discipline was recently found and fixed [1]. Now, the N_X25 line discipline has been discovered accessing the previous line discipline's already-freed private data [2]. Harden the ldisc interface against misuse by initializing revelant tty fields before instancing the new line discipline. [1] commit fd98e9419d8d622a4de91f76b306af6aa627aa9c Author: Tilman Schmidt Date: Tue Jul 14 00:37:13 2015 +0200 isdn/gigaset: reset tty->receive_room when attaching ser_gigaset [2] Report from Sasha Levin [ 634.336761] ================================================================== [ 634.338226] BUG: KASAN: use-after-free in x25_asy_open_tty+0x13d/0x490 at addr ffff8800a743efd0 [ 634.339558] Read of size 4 by task syzkaller_execu/8981 [ 634.340359] ============================================================================= [ 634.341598] BUG kmalloc-512 (Not tainted): kasan: bad access detected ... [ 634.405018] Call Trace: [ 634.405277] dump_stack (lib/dump_stack.c:52) [ 634.405775] print_trailer (mm/slub.c:655) [ 634.406361] object_err (mm/slub.c:662) [ 634.406824] kasan_report_error (mm/kasan/report.c:138 mm/kasan/report.c:236) [ 634.409581] __asan_report_load4_noabort (mm/kasan/report.c:279) [ 634.411355] x25_asy_open_tty (drivers/net/wan/x25_asy.c:559 (discriminator 1)) [ 634.413997] tty_ldisc_open.isra.2 (drivers/tty/tty_ldisc.c:447) [ 634.414549] tty_set_ldisc (drivers/tty/tty_ldisc.c:567) [ 634.415057] tty_ioctl (drivers/tty/tty_io.c:2646 drivers/tty/tty_io.c:2879) [ 634.423524] do_vfs_ioctl (fs/ioctl.c:43 fs/ioctl.c:607) [ 634.427491] SyS_ioctl (fs/ioctl.c:622 fs/ioctl.c:613) [ 634.427945] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:188) Cc: Tilman Schmidt Cc: Sasha Levin Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman Change-Id: Ibed6feadfb9706d478f93feec3b240aecfc64af3 Bug: 30951112 --- drivers/tty/tty_ldisc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 2d822aa259b2..2bf08366cd5b 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -414,6 +414,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); * they are not on hot paths so a little discipline won't do * any harm. * + * The line discipline-related tty_struct fields are reset to + * prevent the ldisc driver from re-using stale information for + * the new ldisc instance. + * * Locking: takes termios_rwsem */ @@ -422,6 +426,9 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) down_write(&tty->termios_rwsem); tty->termios.c_line = num; up_write(&tty->termios_rwsem); + + tty->disc_data = NULL; + tty->receive_room = 0; } /** -- cgit v1.2.3 From ee8791a6c51a69a05cb39911cf1f75757d20e40e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 15 Mar 2016 12:14:49 +0100 Subject: BACKPORT: ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk() (cherry picked from commit 902eb7fd1e4af3ac69b9b30f8373f118c92b9729) Just a minor code cleanup: unify the error paths. Signed-off-by: Takashi Iwai Change-Id: I8253a86235df2ac1258153c9e128fa158527567f Bug: 30952477 --- sound/usb/quirks.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 7da345b0cdaf..6d64e29c9775 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -155,16 +155,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, stream = (fp->endpoint & USB_DIR_IN) ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; err = snd_usb_add_audio_stream(chip, stream, fp); - if (err < 0) { - kfree(fp); - kfree(rate_table); - return err; - } + if (err < 0) + goto error; if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber || fp->altset_idx >= iface->num_altsetting) { - kfree(fp); - kfree(rate_table); - return -EINVAL; + err = -EINVAL; + goto error; } alts = &iface->altsetting[fp->altset_idx]; altsd = get_iface_desc(alts); @@ -184,6 +180,11 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, snd_usb_init_pitch(chip, fp->iface, alts, fp); snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max); return 0; + + error: + kfree(fp); + kfree(rate_table); + return err; } static int create_auto_pcm_quirk(struct snd_usb_audio *chip, -- cgit v1.2.3 From 7f350daadf5a87bb86a2f6a59cb32e11f95df82f Mon Sep 17 00:00:00 2001 From: Vladis Dronov Date: Thu, 31 Mar 2016 12:05:43 -0400 Subject: UPSTREAM: ALSA: usb-audio: Fix double-free in error paths after snd_usb_add_audio_stream() call (cherry picked from commit 836b34a935abc91e13e63053d0a83b24dfb5ea78) create_fixed_stream_quirk(), snd_usb_parse_audio_interface() and create_uaxx_quirk() functions allocate the audioformat object by themselves and free it upon error before returning. However, once the object is linked to a stream, it's freed again in snd_usb_audio_pcm_free(), thus it'll be double-freed, eventually resulting in a memory corruption. This patch fixes these failures in the error paths by unlinking the audioformat object before freeing it. Based on a patch by Takashi Iwai [Note for stable backports: this patch requires the commit 902eb7fd1e4a ('ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk()')] Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1283358 Reported-by: Ralf Spenneberg Cc: # see the note above Signed-off-by: Vladis Dronov Signed-off-by: Takashi Iwai Change-Id: I7073a17d8c99886d2f6ed7981892712ba7dd5873 Bug: 30952477 --- sound/usb/quirks.c | 4 ++++ sound/usb/stream.c | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 6d64e29c9775..64789dd1cc02 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -138,6 +138,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, usb_audio_err(chip, "cannot memdup\n"); return -ENOMEM; } + INIT_LIST_HEAD(&fp->list); if (fp->nr_rates > MAX_NR_RATES) { kfree(fp); return -EINVAL; @@ -182,6 +183,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, return 0; error: + list_del(&fp->list); /* unlink for avoiding double-free */ kfree(fp); kfree(rate_table); return err; @@ -457,6 +459,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; fp->datainterval = 0; fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); + INIT_LIST_HEAD(&fp->list); switch (fp->maxpacksize) { case 0x120: @@ -480,6 +483,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; err = snd_usb_add_audio_stream(chip, stream, fp); if (err < 0) { + list_del(&fp->list); /* unlink for avoiding double-free */ kfree(fp); return err; } diff --git a/sound/usb/stream.c b/sound/usb/stream.c index 310a3822d2b7..25e8075f9ea3 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -315,7 +315,9 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, /* * add this endpoint to the chip instance. * if a stream with the same endpoint already exists, append to it. - * if not, create a new pcm stream. + * if not, create a new pcm stream. note, fp is added to the substream + * fmt_list and will be freed on the chip instance release. do not free + * fp or do remove it from the substream fmt_list to avoid double-free. */ int snd_usb_add_audio_stream(struct snd_usb_audio *chip, int stream, @@ -668,6 +670,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) * (fp->maxpacksize & 0x7ff); fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); fp->clock = clock; + INIT_LIST_HEAD(&fp->list); /* some quirks for attributes here */ @@ -716,6 +719,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); err = snd_usb_add_audio_stream(chip, stream, fp); if (err < 0) { + list_del(&fp->list); /* unlink for avoiding double-free */ kfree(fp->rate_table); kfree(fp->chmap); kfree(fp); -- cgit v1.2.3 From f26bc352514b341149b6856531ed95fcca483fa0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 19 Jan 2016 12:34:58 +0100 Subject: UPSTREAM: HID: core: prevent out-of-bound readings (cherry picked from commit 50220dead1650609206efe91f0cc116132d59b3f) Plugging a Logitech DJ receiver with KASAN activated raises a bunch of out-of-bound readings. The fields are allocated up to MAX_USAGE, meaning that potentially, we do not have enough fields to fit the incoming values. Add checks and silence KASAN. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina Change-Id: Iaf25e882a6696884439d7091b5fbb0b350d893d3 Bug: 30951261 --- drivers/hid/hid-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index cb4bc0dadba5..94fdaeb85612 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1213,6 +1213,7 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, /* Ignore report if ErrorRollOver */ if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && value[n] >= min && value[n] <= max && + value[n] - min < field->maxusage && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) goto exit; } @@ -1225,11 +1226,13 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, } if (field->value[n] >= min && field->value[n] <= max + && field->value[n] - min < field->maxusage && field->usage[field->value[n] - min].hid && search(value, field->value[n], count)) hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); if (value[n] >= min && value[n] <= max + && value[n] - min < field->maxusage && field->usage[value[n] - min].hid && search(field->value, value[n], count)) hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); -- cgit v1.2.3 From 8b364d1de97580364b7220a54a3fb700901a6b06 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Wed, 6 Apr 2016 14:06:48 +0100 Subject: UPSTREAM: assoc_array: don't call compare_object() on a node (cherry picked from commit 8d4a2ec1e0b41b0cf9a0c5cd4511da7f8e4f3de2) Changes since V1: fixed the description and added KASan warning. In assoc_array_insert_into_terminal_node(), we call the compare_object() method on all non-empty slots, even when they're not leaves, passing a pointer to an unexpected structure to compare_object(). Currently it causes an out-of-bound read access in keyring_compare_object detected by KASan (see below). The issue is easily reproduced with keyutils testsuite. Only call compare_object() when the slot is a leave. KASan warning: ================================================================== BUG: KASAN: slab-out-of-bounds in keyring_compare_object+0x213/0x240 at addr ffff880060a6f838 Read of size 8 by task keyctl/1655 ============================================================================= BUG kmalloc-192 (Not tainted): kasan: bad access detected ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in assoc_array_insert+0xfd0/0x3a60 age=69 cpu=1 pid=1647 ___slab_alloc+0x563/0x5c0 __slab_alloc+0x51/0x90 kmem_cache_alloc_trace+0x263/0x300 assoc_array_insert+0xfd0/0x3a60 __key_link_begin+0xfc/0x270 key_create_or_update+0x459/0xaf0 SyS_add_key+0x1ba/0x350 entry_SYSCALL_64_fastpath+0x12/0x76 INFO: Slab 0xffffea0001829b80 objects=16 used=8 fp=0xffff880060a6f550 flags=0x3fff8000004080 INFO: Object 0xffff880060a6f740 @offset=5952 fp=0xffff880060a6e5d1 Bytes b4 ffff880060a6f730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f740: d1 e5 a6 60 00 88 ff ff 0e 00 00 00 00 00 00 00 ...`............ Object ffff880060a6f750: 02 cf 8e 60 00 88 ff ff 02 c0 8e 60 00 88 ff ff ...`.......`.... Object ffff880060a6f760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7d0: 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ Object ffff880060a6f7f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CPU: 0 PID: 1655 Comm: keyctl Tainted: G B 4.5.0-rc4-kasan+ #291 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 0000000000000000 000000001b2800b4 ffff880060a179e0 ffffffff81b60491 ffff88006c802900 ffff880060a6f740 ffff880060a17a10 ffffffff815e2969 ffff88006c802900 ffffea0001829b80 ffff880060a6f740 ffff880060a6e650 Call Trace: [] dump_stack+0x85/0xc4 [] print_trailer+0xf9/0x150 [] object_err+0x34/0x40 [] kasan_report_error+0x230/0x550 [] ? keyring_get_key_chunk+0x13e/0x210 [] __asan_report_load_n_noabort+0x5d/0x70 [] ? keyring_compare_object+0x213/0x240 [] keyring_compare_object+0x213/0x240 [] assoc_array_insert+0x86c/0x3a60 [] ? assoc_array_cancel_edit+0x70/0x70 [] ? __key_link_begin+0x20d/0x270 [] __key_link_begin+0xfc/0x270 [] key_create_or_update+0x459/0xaf0 [] ? trace_hardirqs_on+0xd/0x10 [] ? key_type_lookup+0xc0/0xc0 [] ? lookup_user_key+0x13d/0xcd0 [] ? memdup_user+0x53/0x80 [] SyS_add_key+0x1ba/0x350 [] ? key_get_type_from_user.constprop.6+0xa0/0xa0 [] ? retint_user+0x18/0x23 [] ? trace_hardirqs_on_caller+0x3fe/0x580 [] ? trace_hardirqs_on_thunk+0x17/0x19 [] entry_SYSCALL_64_fastpath+0x12/0x76 Memory state around the buggy address: ffff880060a6f700: fc fc fc fc fc fc fc fc 00 00 00 00 00 00 00 00 ffff880060a6f780: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc >ffff880060a6f800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ^ ffff880060a6f880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff880060a6f900: fc fc fc fc fc fc 00 00 00 00 00 00 00 00 00 00 ================================================================== Signed-off-by: Jerome Marchand Signed-off-by: David Howells cc: stable@vger.kernel.org Change-Id: I903935a221a5b9fb14cec14ef64bd2b6fa8eb222 Bug: 30513364 --- lib/assoc_array.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/assoc_array.c b/lib/assoc_array.c index 2404d03e251a..03a77f4740c1 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c @@ -523,7 +523,9 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit, free_slot = i; continue; } - if (ops->compare_object(assoc_array_ptr_to_leaf(ptr), index_key)) { + if (assoc_array_ptr_is_leaf(ptr) && + ops->compare_object(assoc_array_ptr_to_leaf(ptr), + index_key)) { pr_devel("replace in slot %d\n", i); edit->leaf_p = &node->slots[i]; edit->dead_leaf = node->slots[i]; -- cgit v1.2.3 From 5f675641a3a5f0ff0e639476ea73d1a86672f2d9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 3 Feb 2016 13:34:00 -0200 Subject: UPSTREAM: [media] xc2028: unlock on error in xc2028_set_config() We have to unlock before returning -ENOMEM. Fixes: 8dfbcc4351a0 ('[media] xc2028: avoid use after free') Signed-off-by: Dan Carpenter Signed-off-by: Mauro Carvalho Chehab (cherry picked from commit 210bd104c6acd31c3c6b8b075b3f12d4a9f6b60d) Bug: 30946097 Change-Id: I2d0bab35824d204a05de36e265c443938033eb81 --- drivers/media/tuners/tuner-xc2028.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 36c7f2a077b4..0b54ec2d6eed 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -1407,8 +1407,10 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); if (p->fname) { priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); - if (priv->ctrl.fname == NULL) - return -ENOMEM; + if (priv->ctrl.fname == NULL) { + rc = -ENOMEM; + goto unlock; + } } /* @@ -1440,6 +1442,7 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg) } else priv->state = XC2028_WAITING_FIRMWARE; } +unlock: mutex_unlock(&priv->lock); return rc; -- cgit v1.2.3 From d28dfeeca261ca4c0b74bf013ba43c2506d2ff67 Mon Sep 17 00:00:00 2001 From: Patrick Tjin Date: Fri, 16 Sep 2016 11:34:06 -0700 Subject: arm64/configs: marlin: remove tuner support Bug: 30946097 Change-Id: I2572d3e147ee75185155ec665f9925323dae73b5 --- arch/arm64/configs/marlin_defconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/configs/marlin_defconfig b/arch/arm64/configs/marlin_defconfig index 37414fd5b976..a87144fcc012 100644 --- a/arch/arm64/configs/marlin_defconfig +++ b/arch/arm64/configs/marlin_defconfig @@ -353,7 +353,6 @@ CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_KRYO=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_RADIO_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_V4L_PLATFORM_DRIVERS=y @@ -381,7 +380,6 @@ CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y CONFIG_MSMB_JPEG=y CONFIG_MSM_FD=y CONFIG_MSM_JPEGDMA=y -CONFIG_RADIO_SILABS=y CONFIG_MSM_KGSL=y CONFIG_FB=y CONFIG_FB_MSM=y -- cgit v1.2.3 From b1e90ba0a333e58fada69a883c4e432351c34ee0 Mon Sep 17 00:00:00 2001 From: vivek mehta Date: Mon, 12 Sep 2016 17:22:18 -0700 Subject: ASoC: msm: initialize the params array before using it The params array is used without initialization, which may cause security issues. Initialize it as all zero after the definition. bug: 30902162 Change-Id: If462fe3d82f139d72547f82dc7eb564f83cb35bf Signed-off-by: vivek mehta --- sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c index b5b75f2a0808..eb8b569488eb 100644 --- a/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-compr-q6-v2.c @@ -1040,6 +1040,7 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, struct snd_dec_ddp *ddp = &compr->info.codec_param.codec.options.ddp; uint32_t params_length = 0; + memset(params_value, 0, MAX_AC3_PARAM_SIZE); /* check integer overflow */ if (ddp->params_length > UINT_MAX/sizeof(int)) { pr_err("%s: Integer overflow ddp->params_length %d\n", @@ -1080,6 +1081,7 @@ static int msm_compr_ioctl_shared(struct snd_pcm_substream *substream, struct snd_dec_ddp *ddp = &compr->info.codec_param.codec.options.ddp; uint32_t params_length = 0; + memset(params_value, 0, MAX_AC3_PARAM_SIZE); /* check integer overflow */ if (ddp->params_length > UINT_MAX/sizeof(int)) { pr_err("%s: Integer overflow ddp->params_length %d\n", -- cgit v1.2.3 From ce1b4b6fc8d4006885bd2f6af32498f140060e58 Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Fri, 9 Sep 2016 15:32:34 -0700 Subject: ion: Disable ION_HEAP_TYPE_SYSTEM_CONTIG Bug: 30400942 Change-Id: I19fa5bf6e5c66b532b842180b2cf0ae04ddca337 Signed-off-by: Daniel Rosenberg --- drivers/staging/android/ion/ion_heap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 54d3bd98126e..848a7f3591f0 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -325,8 +325,9 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) switch (heap_data->type) { case ION_HEAP_TYPE_SYSTEM_CONTIG: - heap = ion_system_contig_heap_create(heap_data); - break; + pr_err("%s: Heap type is disabled: %d\n", __func__, + heap_data->type); + return ERR_PTR(-EINVAL); case ION_HEAP_TYPE_SYSTEM: heap = ion_system_heap_create(heap_data); break; @@ -365,7 +366,8 @@ void ion_heap_destroy(struct ion_heap *heap) switch (heap->type) { case ION_HEAP_TYPE_SYSTEM_CONTIG: - ion_system_contig_heap_destroy(heap); + pr_err("%s: Heap type is disabled: %d\n", __func__, + heap->type); break; case ION_HEAP_TYPE_SYSTEM: ion_system_heap_destroy(heap); -- cgit v1.2.3 From d36033dffc0307902c1ff63d3cb6780e3491c108 Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Wed, 31 Aug 2016 14:08:16 +0530 Subject: qcedev: Validate Source and Destination addresses Source and Destination addresses passed by user space apps/clients are validated independent of type of operation to mitigate kernel address space exploitation. Bug: 30034511 CRs-Fixed: 1050538 Change-Id: I9ecb0103d7a73eedb2e0d1db1d5613b18dd77e59 Signed-off-by: AnilKumar Chimata Signed-off-by: Biswajit Paul --- drivers/crypto/msm/qcedev.c | 68 ++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c index e63f061175ad..1402d3ded984 100644 --- a/drivers/crypto/msm/qcedev.c +++ b/drivers/crypto/msm/qcedev.c @@ -1234,44 +1234,6 @@ static int qcedev_vbuf_ablk_cipher(struct qcedev_async_req *areq, struct qcedev_cipher_op_req *saved_req; struct qcedev_cipher_op_req *creq = &areq->cipher_op_req; - /* Verify Source Address's */ - for (i = 0; i < areq->cipher_op_req.entries; i++) - if (!access_ok(VERIFY_READ, - (void __user *)areq->cipher_op_req.vbuf.src[i].vaddr, - areq->cipher_op_req.vbuf.src[i].len)) - return -EFAULT; - - /* Verify Destination Address's */ - if (creq->in_place_op != 1) { - for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) { - if ((areq->cipher_op_req.vbuf.dst[i].vaddr != 0) && - (total < creq->data_len)) { - if (!access_ok(VERIFY_WRITE, - (void __user *)creq->vbuf.dst[i].vaddr, - creq->vbuf.dst[i].len)) { - pr_err("%s:DST WR_VERIFY err %d=0x%lx\n", - __func__, i, (uintptr_t) - creq->vbuf.dst[i].vaddr); - return -EFAULT; - } - total += creq->vbuf.dst[i].len; - } - } - } else { - for (i = 0, total = 0; i < creq->entries; i++) { - if (total < creq->data_len) { - if (!access_ok(VERIFY_WRITE, - (void __user *)creq->vbuf.src[i].vaddr, - creq->vbuf.src[i].len)) { - pr_err("%s:SRC WR_VERIFY err %d=0x%lx\n", - __func__, i, (uintptr_t) - creq->vbuf.src[i].vaddr); - return -EFAULT; - } - total += creq->vbuf.src[i].len; - } - } - } total = 0; if (areq->cipher_op_req.mode == QCEDEV_AES_MODE_CTR) @@ -1569,6 +1531,36 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req, __func__, total, req->data_len); goto error; } + /* Verify Source Address's */ + for (i = 0, total = 0; i < req->entries; i++) { + if (total < req->data_len) { + if (!access_ok(VERIFY_READ, + (void __user *)req->vbuf.src[i].vaddr, + req->vbuf.src[i].len)) { + pr_err("%s:SRC RD_VERIFY err %d=0x%lx\n", + __func__, i, (uintptr_t) + req->vbuf.src[i].vaddr); + goto error; + } + total += req->vbuf.src[i].len; + } + } + + /* Verify Destination Address's */ + for (i = 0, total = 0; i < QCEDEV_MAX_BUFFERS; i++) { + if ((req->vbuf.dst[i].vaddr != 0) && + (total < req->data_len)) { + if (!access_ok(VERIFY_WRITE, + (void __user *)req->vbuf.dst[i].vaddr, + req->vbuf.dst[i].len)) { + pr_err("%s:DST WR_VERIFY err %d=0x%lx\n", + __func__, i, (uintptr_t) + req->vbuf.dst[i].vaddr); + goto error; + } + total += req->vbuf.dst[i].len; + } + } return 0; error: return -EINVAL; -- cgit v1.2.3 From fd30110abd9cac2fe630f1584911c4e725d1589c Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Tue, 13 Sep 2016 13:31:57 -0700 Subject: msm: sensor: Avoid potential stack overflow Add a check to validate the user input data is not greater than expected stack buffer size to avoid out of bounds array accesses Bug: 30143904 CRs-Fixed: 1056307 Change-Id: I8b31006772367a120828269243b1971d33a4d7d3 Signed-off-by: VijayaKumar T M Signed-off-by: Biswajit Paul --- drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index 8f911d362477..a4ee5041bfff 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -276,6 +276,12 @@ int32_t msm_camera_cci_i2c_write_seq_table( client_addr_type = client->addr_type; client->addr_type = write_setting->addr_type; + if (reg_setting->reg_data_size > I2C_SEQ_REG_DATA_MAX) { + pr_err("%s: number of bytes %u exceeding the max supported %d\n", + __func__, reg_setting->reg_data_size, I2C_SEQ_REG_DATA_MAX); + return rc; + } + for (i = 0; i < write_setting->size; i++) { rc = msm_camera_cci_i2c_write_seq(client, reg_setting->reg_addr, reg_setting->reg_data, reg_setting->reg_data_size); -- cgit v1.2.3 From d3d4c8b432fbce5e441f6f62f2af59056d9ca3df Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Wed, 7 Sep 2016 12:53:43 +0530 Subject: msm: camera: Restructure data handling to be more robust Use dynamic array allocation instead of static array to prevent stack overflow. User-supplied number of bytes may result in integer overflow. To fix this we check that the num_byte isn't above 8K size. Bug: 30559423 CRs-Fixed: 1060554 Change-Id: I9b05b846e5cc3a62b1a0a67be529f09abc764796 Signed-off-by: VijayaKumar T M Signed-off-by: Biswajit Paul --- .../msm/camera_v2/sensor/io/msm_camera_cci_i2c.c | 6 ++++ .../msm/camera_v2/sensor/io/msm_camera_qup_i2c.c | 39 ++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c index a4ee5041bfff..be7954c3d2c9 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c @@ -69,6 +69,12 @@ int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client, || num_byte == 0) return rc; + if (num_byte > I2C_REG_DATA_MAX) { + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); + return rc; + } + buf = kzalloc(num_byte, GFP_KERNEL); if (!buf) { pr_err("%s:%d no memory\n", __func__, __LINE__); diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c index 3b101798edac..b20fe9f64046 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c @@ -73,7 +73,7 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, enum msm_camera_i2c_data_type data_type) { int32_t rc = -EFAULT; - unsigned char buf[client->addr_type+data_type]; + unsigned char *buf = NULL; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR && client->addr_type != MSM_CAMERA_I2C_WORD_ADDR) @@ -81,6 +81,17 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, && data_type != MSM_CAMERA_I2C_WORD_DATA)) return rc; + if (client->addr_type > UINT_MAX - data_type) { + pr_err("%s: integer overflow prevented\n", __func__); + return rc; + } + + buf = kzalloc(client->addr_type+data_type, GFP_KERNEL); + if (!buf) { + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; + } + if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { buf[0] = addr; } else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) { @@ -90,6 +101,8 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, rc = msm_camera_qup_i2c_rxdata(client, buf, data_type); if (rc < 0) { S_I2C_DBG("%s fail\n", __func__); + kfree(buf); + buf = NULL; return rc; } @@ -99,6 +112,8 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client, *data = buf[0] << 8 | buf[1]; S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data); + kfree(buf); + buf = NULL; return rc; } @@ -106,7 +121,7 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, uint32_t addr, uint8_t *data, uint32_t num_byte) { int32_t rc = -EFAULT; - unsigned char buf[client->addr_type+num_byte]; + unsigned char *buf = NULL; int i; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR @@ -114,6 +129,22 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, || num_byte == 0) return rc; + if (num_byte > I2C_REG_DATA_MAX) { + pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n", + __func__, num_byte, I2C_REG_DATA_MAX); + return rc; + } + if (client->addr_type > UINT_MAX - num_byte) { + pr_err("%s: integer overflow prevented\n", __func__); + return rc; + } + + buf = kzalloc(client->addr_type+num_byte, GFP_KERNEL); + if (!buf) { + pr_err("%s:%d no memory\n", __func__, __LINE__); + return -ENOMEM; + } + if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) { buf[0] = addr; } else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) { @@ -123,6 +154,8 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, rc = msm_camera_qup_i2c_rxdata(client, buf, num_byte); if (rc < 0) { S_I2C_DBG("%s fail\n", __func__); + kfree(buf); + buf = NULL; return rc; } @@ -132,6 +165,8 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client, S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]); S_I2C_DBG("Data: 0x%x\n", data[i]); } + kfree(buf); + buf = NULL; return rc; } -- cgit v1.2.3 From da210a90a724bd3a5ff0e0fcda3d38b5f0b718bc Mon Sep 17 00:00:00 2001 From: vivek mehta Date: Fri, 9 Sep 2016 15:33:40 -0700 Subject: misc: qcom: qdsp6v2: initialize config_32 Not all members of config_32 are set before they are used which might lead to invalid values being passed and used. To fix this issue initialize all member variables of struct config_32 to 0 before assigning specific values individually. Bug: 30741851 Change-Id: Ifea3a6e8bf45481c65a4455ee64318304798fee2 Signed-off-by: vivek mehta --- drivers/misc/qcom/qdsp6v2/aac_in.c | 4 +++- drivers/misc/qcom/qdsp6v2/amrnb_in.c | 5 ++++- drivers/misc/qcom/qdsp6v2/amrwb_in.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_alac.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c | 4 ++++ drivers/misc/qcom/qdsp6v2/audio_ape.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_multi_aac.c | 2 ++ drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 1 + drivers/misc/qcom/qdsp6v2/audio_wmapro.c | 2 ++ drivers/misc/qcom/qdsp6v2/evrc_in.c | 4 +++- drivers/misc/qcom/qdsp6v2/qcelp_in.c | 4 +++- 12 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/aac_in.c b/drivers/misc/qcom/qdsp6v2/aac_in.c index c9d5dbb0b313..7176c114f85b 100644 --- a/drivers/misc/qcom/qdsp6v2/aac_in.c +++ b/drivers/misc/qcom/qdsp6v2/aac_in.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -421,6 +421,8 @@ static long aac_in_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_aac_enc_config cfg; struct msm_audio_aac_enc_config32 cfg_32; + memset(&cfg_32, 0, sizeof(cfg_32)); + cmd = AUDIO_GET_AAC_ENC_CONFIG; rc = aac_in_ioctl_shared(file, cmd, &cfg); if (rc) { diff --git a/drivers/misc/qcom/qdsp6v2/amrnb_in.c b/drivers/misc/qcom/qdsp6v2/amrnb_in.c index eb92137f0671..1bb441bd2ff4 100644 --- a/drivers/misc/qcom/qdsp6v2/amrnb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrnb_in.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2010-2012, 2014 The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2012, 2014, 2016 The Linux Foundation. + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -221,6 +222,8 @@ static long amrnb_in_compat_ioctl(struct file *file, struct msm_audio_amrnb_enc_config_v2 *amrnb_config; struct msm_audio_amrnb_enc_config_v2_32 amrnb_config_32; + memset(&amrnb_config_32, 0, sizeof(amrnb_config_32)); + amrnb_config = (struct msm_audio_amrnb_enc_config_v2 *)audio->enc_cfg; amrnb_config_32.band_mode = amrnb_config->band_mode; diff --git a/drivers/misc/qcom/qdsp6v2/amrwb_in.c b/drivers/misc/qcom/qdsp6v2/amrwb_in.c index 4cea3dc63389..71adbce0e257 100644 --- a/drivers/misc/qcom/qdsp6v2/amrwb_in.c +++ b/drivers/misc/qcom/qdsp6v2/amrwb_in.c @@ -216,6 +216,8 @@ static long amrwb_in_compat_ioctl(struct file *file, struct msm_audio_amrwb_enc_config *amrwb_config; struct msm_audio_amrwb_enc_config_32 amrwb_config_32; + memset(&amrwb_config_32, 0, sizeof(amrwb_config_32)); + amrwb_config = (struct msm_audio_amrwb_enc_config *)audio->enc_cfg; amrwb_config_32.band_mode = amrwb_config->band_mode; diff --git a/drivers/misc/qcom/qdsp6v2/audio_alac.c b/drivers/misc/qcom/qdsp6v2/audio_alac.c index 9748db30fac3..87b09939f9a1 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_alac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_alac.c @@ -196,6 +196,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_alac_config *alac_config; struct msm_audio_alac_config_32 alac_config_32; + memset(&alac_config_32, 0, sizeof(alac_config_32)); + alac_config = (struct msm_audio_alac_config *)audio->codec_cfg; alac_config_32.frameLength = alac_config->frameLength; alac_config_32.compatVersion = diff --git a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c index ee5991177687..025ccfdc39be 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c +++ b/drivers/misc/qcom/qdsp6v2/audio_amrwbplus.c @@ -205,6 +205,10 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_amrwbplus_config_v2 *amrwbplus_config; struct msm_audio_amrwbplus_config_v2_32 amrwbplus_config_32; + + memset(&amrwbplus_config_32, 0, + sizeof(amrwbplus_config_32)); + amrwbplus_config = (struct msm_audio_amrwbplus_config_v2 *) audio->codec_cfg; diff --git a/drivers/misc/qcom/qdsp6v2/audio_ape.c b/drivers/misc/qcom/qdsp6v2/audio_ape.c index b4c2ddb947de..cf9ff72ebc93 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_ape.c +++ b/drivers/misc/qcom/qdsp6v2/audio_ape.c @@ -180,6 +180,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ape_config *ape_config; struct msm_audio_ape_config_32 ape_config_32; + memset(&ape_config_32, 0, sizeof(ape_config_32)); + ape_config = (struct msm_audio_ape_config *)audio->codec_cfg; ape_config_32.compatibleVersion = ape_config->compatibleVersion; ape_config_32.compressionLevel = diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c index 3a8834446ea4..3632fc2b961b 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c +++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c @@ -630,6 +630,8 @@ static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_EFFECTS_GET_BUF_AVAIL32: { struct msm_hwacc_buf_avail32 buf_avail; + memset(&buf_avail, 0, sizeof(buf_avail)); + buf_avail.input_num_avail = atomic_read(&effects->in_count); buf_avail.output_num_avail = atomic_read(&effects->out_count); pr_debug("%s: write buf avail: %d, read buf avail: %d\n", diff --git a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c index a15fd87c7be8..bd2a8b219fb3 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c +++ b/drivers/misc/qcom/qdsp6v2/audio_multi_aac.c @@ -302,6 +302,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_aac_config *aac_config; struct msm_audio_aac_config32 aac_config_32; + memset(&aac_config_32, 0, sizeof(aac_config_32)); + aac_config = (struct msm_audio_aac_config *)audio->codec_cfg; aac_config_32.format = aac_config->format; aac_config_32.audio_object = aac_config->audio_object; diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 753195affef0..7267557d48dc 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -2033,6 +2033,7 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, audio->buf_cfg.frames_per_buf); mutex_lock(&audio->lock); + memset(&cfg_32, 0, sizeof(cfg_32)); cfg_32.meta_info_enable = audio->buf_cfg.meta_info_enable; cfg_32.frames_per_buf = audio->buf_cfg.frames_per_buf; if (copy_to_user((void *)arg, &cfg_32, diff --git a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c index 8d96b99d8f84..711867f80566 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wmapro.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wmapro.c @@ -217,6 +217,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_wmapro_config *wmapro_config; struct msm_audio_wmapro_config32 wmapro_config_32; + memset(&wmapro_config_32, 0, sizeof(wmapro_config_32)); + wmapro_config = (struct msm_audio_wmapro_config *)audio->codec_cfg; wmapro_config_32.armdatareqthr = wmapro_config->armdatareqthr; diff --git a/drivers/misc/qcom/qdsp6v2/evrc_in.c b/drivers/misc/qcom/qdsp6v2/evrc_in.c index 2f931be226c6..aab8e27c0094 100644 --- a/drivers/misc/qcom/qdsp6v2/evrc_in.c +++ b/drivers/misc/qcom/qdsp6v2/evrc_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -224,6 +224,8 @@ static long evrc_in_compat_ioctl(struct file *file, struct msm_audio_evrc_enc_config32 cfg_32; struct msm_audio_evrc_enc_config *enc_cfg; + memset(&cfg_32, 0, sizeof(cfg_32)); + enc_cfg = audio->enc_cfg; cfg_32.cdma_rate = enc_cfg->cdma_rate; cfg_32.min_bit_rate = enc_cfg->min_bit_rate; diff --git a/drivers/misc/qcom/qdsp6v2/qcelp_in.c b/drivers/misc/qcom/qdsp6v2/qcelp_in.c index b5d5ad113722..aabf5d33a507 100644 --- a/drivers/misc/qcom/qdsp6v2/qcelp_in.c +++ b/drivers/misc/qcom/qdsp6v2/qcelp_in.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -225,6 +225,8 @@ static long qcelp_in_compat_ioctl(struct file *file, struct msm_audio_qcelp_enc_config32 cfg_32; struct msm_audio_qcelp_enc_config *enc_cfg; + memset(&cfg_32, 0, sizeof(cfg_32)); + enc_cfg = (struct msm_audio_qcelp_enc_config *)audio->enc_cfg; cfg_32.cdma_rate = enc_cfg->cdma_rate; cfg_32.min_bit_rate = enc_cfg->min_bit_rate; -- cgit v1.2.3 From 95fc8266e58915548fa1df8460a3c4a9429a2b32 Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Fri, 29 Jul 2016 10:40:31 +0200 Subject: UPSTREAM: block: fix use-after-free in seq file (cherry picked from commit 77da160530dd1dc94f6ae15a981f24e5f0021e84) I got a KASAN report of use-after-free: ================================================================== BUG: KASAN: use-after-free in klist_iter_exit+0x61/0x70 at addr ffff8800b6581508 Read of size 8 by task trinity-c1/315 ============================================================================= BUG kmalloc-32 (Not tainted): kasan: bad access detected ----------------------------------------------------------------------------- Disabling lock debugging due to kernel taint INFO: Allocated in disk_seqf_start+0x66/0x110 age=144 cpu=1 pid=315 ___slab_alloc+0x4f1/0x520 __slab_alloc.isra.58+0x56/0x80 kmem_cache_alloc_trace+0x260/0x2a0 disk_seqf_start+0x66/0x110 traverse+0x176/0x860 seq_read+0x7e3/0x11a0 proc_reg_read+0xbc/0x180 do_loop_readv_writev+0x134/0x210 do_readv_writev+0x565/0x660 vfs_readv+0x67/0xa0 do_preadv+0x126/0x170 SyS_preadv+0xc/0x10 do_syscall_64+0x1a1/0x460 return_from_SYSCALL_64+0x0/0x6a INFO: Freed in disk_seqf_stop+0x42/0x50 age=160 cpu=1 pid=315 __slab_free+0x17a/0x2c0 kfree+0x20a/0x220 disk_seqf_stop+0x42/0x50 traverse+0x3b5/0x860 seq_read+0x7e3/0x11a0 proc_reg_read+0xbc/0x180 do_loop_readv_writev+0x134/0x210 do_readv_writev+0x565/0x660 vfs_readv+0x67/0xa0 do_preadv+0x126/0x170 SyS_preadv+0xc/0x10 do_syscall_64+0x1a1/0x460 return_from_SYSCALL_64+0x0/0x6a CPU: 1 PID: 315 Comm: trinity-c1 Tainted: G B 4.7.0+ #62 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 ffffea0002d96000 ffff880119b9f918 ffffffff81d6ce81 ffff88011a804480 ffff8800b6581500 ffff880119b9f948 ffffffff8146c7bd ffff88011a804480 ffffea0002d96000 ffff8800b6581500 fffffffffffffff4 ffff880119b9f970 Call Trace: [] dump_stack+0x65/0x84 [] print_trailer+0x10d/0x1a0 [] object_err+0x2f/0x40 [] kasan_report_error+0x221/0x520 [] __asan_report_load8_noabort+0x3e/0x40 [] klist_iter_exit+0x61/0x70 [] class_dev_iter_exit+0x9/0x10 [] disk_seqf_stop+0x3a/0x50 [] seq_read+0x4b2/0x11a0 [] proc_reg_read+0xbc/0x180 [] do_loop_readv_writev+0x134/0x210 [] do_readv_writev+0x565/0x660 [] vfs_readv+0x67/0xa0 [] do_preadv+0x126/0x170 [] SyS_preadv+0xc/0x10 This problem can occur in the following situation: open() - pread() - .seq_start() - iter = kmalloc() // succeeds - seqf->private = iter - .seq_stop() - kfree(seqf->private) - pread() - .seq_start() - iter = kmalloc() // fails - .seq_stop() - class_dev_iter_exit(seqf->private) // boom! old pointer As the comment in disk_seqf_stop() says, stop is called even if start failed, so we need to reinitialise the private pointer to NULL when seq iteration stops. An alternative would be to set the private pointer to NULL when the kmalloc() in disk_seqf_start() fails. Cc: stable@vger.kernel.org Signed-off-by: Vegard Nossum Acked-by: Tejun Heo Signed-off-by: Jens Axboe Change-Id: I07b33f4b38341f60a37806cdd45b0a0c3ab4d84d Bug: 30942273 Signed-off-by: Siqi Lin --- block/genhd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/genhd.c b/block/genhd.c index c675ad1ad69b..b529e5024d23 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -829,6 +829,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v) if (iter) { class_dev_iter_exit(iter); kfree(iter); + seqf->private = NULL; } } -- cgit v1.2.3 From e6c62bc60f98d2978b735a05d1d144211a092923 Mon Sep 17 00:00:00 2001 From: Rainer Weikusat Date: Thu, 11 Feb 2016 19:37:27 +0000 Subject: UPSTREAM: af_unix: Guard against other == sk in unix_dgram_sendmsg (cherry picked from commit a5527dda344fff0514b7989ef7a755729769daa1) The unix_dgram_sendmsg routine use the following test if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { to determine if sk and other are in an n:1 association (either established via connect or by using sendto to send messages to an unrelated socket identified by address). This isn't correct as the specified address could have been bound to the sending socket itself or because this socket could have been connected to itself by the time of the unix_peer_get but disconnected before the unix_state_lock(other). In both cases, the if-block would be entered despite other == sk which might either block the sender unintentionally or lead to trying to unlock the same spin lock twice for a non-blocking send. Add a other != sk check to guard against this. Fixes: 7d267278a9ec ("unix: avoid use-after-free in ep_remove_wait_queue") Reported-By: Philipp Hahn Signed-off-by: Rainer Weikusat Tested-by: Philipp Hahn Signed-off-by: David S. Miller Fixes: Change-Id: Ia374ee061195088f8c777940baa75cedbe897f4e ("UPSTREAM: unix: avoid use-after-free in ep_remove_wait_queue") Change-Id: I4ebef6a390df3487903b166b837e34c653e01cb2 Signed-off-by: Amit Pundir Bug: 29119002 --- net/unix/af_unix.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 67dc2175ff39..3e2eec6437d5 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1724,7 +1724,12 @@ restart_locked: goto out_unlock; } - if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { + /* other == sk && unix_peer(other) != sk if + * - unix_peer(sk) == NULL, destination address bound to sk + * - unix_peer(sk) == sk by time of get but disconnected before lock + */ + if (other != sk && + unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { if (timeo) { timeo = unix_wait_for_peer(other, timeo); -- cgit v1.2.3 From 754ab71fbc75d356fca32e2c2b77bb0400c68ecb Mon Sep 17 00:00:00 2001 From: Yuan Lin Date: Fri, 16 Sep 2016 14:44:13 -0700 Subject: Revert "Asoc:msm:Added Buffer overflow check" This patch caused a regression, replacing it with a new patch. Bug: 28751152 This reverts commit 18ce8adb5a2c5ab4aa9c1a8a17d206119e64ce96. --- drivers/misc/qcom/qdsp6v2/audio_utils.c | 7 +------ sound/soc/msm/qdsp6v2/q6asm.c | 4 ---- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index d11a6f857baa..cec449dafc70 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -23,7 +23,7 @@ #include #include #include "audio_utils.h" -#define FRAME_SIZE (1 + ((1536+sizeof(struct meta_out_dsp)) * 5)) + static int audio_in_pause(struct q6audio_in *audio) { int rc; @@ -329,11 +329,6 @@ long audio_in_ioctl(struct file *file, rc = -EINVAL; break; } - if ((cfg.buffer_size > FRAME_SIZE) || - (cfg.buffer_count != FRAME_NUM)) { - rc = -EINVAL; - break; - } audio->str_cfg.buffer_size = cfg.buffer_size; audio->str_cfg.buffer_count = cfg.buffer_count; if (audio->opened) { diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 6899fdcff909..e84e5b1969cc 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -53,8 +53,6 @@ #define pr_err(fmt, ...) pr_aud_err(fmt, ##__VA_ARGS__) //HTC_AUD_END -#define FRAME_NUM (8) - enum { ASM_TOPOLOGY_CAL = 0, ASM_CUSTOM_TOP_CAL, @@ -1260,8 +1258,6 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, pr_debug("%s: buffer already allocated\n", __func__); return 0; } - if (bufcnt != FRAME_NUM) - goto fail; mutex_lock(&ac->cmd_lock); if (bufcnt > (LONG_MAX/sizeof(struct audio_buffer))) { pr_err("%s: Buffer size overflows", __func__); -- cgit v1.2.3 From bcdcb0debe8665aff8e420022b647e9ca8ba61a1 Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Wed, 7 Sep 2016 18:02:23 +0530 Subject: ASoC: msm: Add Buffer overflow check The overflow check is required to ensure that user space data in kernel may not go beyond buffer boundary. Bug: 28751152 CRs-Fixed: 1064411 Change-Id: I54c28a8942cf1a6a47a4e8272f3159b35d753ead Signed-off-by: Karthik Reddy Katta Signed-off-by: Biswajit Paul --- drivers/misc/qcom/qdsp6v2/audio_utils.c | 13 +++++++++++++ include/sound/q6asm-v2.h | 2 +- sound/soc/msm/qdsp6v2/q6asm.c | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index cec449dafc70..840597314a5f 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -24,6 +24,15 @@ #include #include "audio_utils.h" +/* + * Define maximum buffer size. Below values are chosen considering the higher + * values used among all native drivers. + */ +#define MAX_FRAME_SIZE 1536 +#define MAX_FRAMES 5 +#define META_SIZE (sizeof(struct meta_out_dsp)) +#define MAX_BUFFER_SIZE (1 + ((MAX_FRAME_SIZE + META_SIZE) * MAX_FRAMES)) + static int audio_in_pause(struct q6audio_in *audio) { int rc; @@ -329,6 +338,10 @@ long audio_in_ioctl(struct file *file, rc = -EINVAL; break; } + if (cfg.buffer_size > MAX_BUFFER_SIZE) { + rc = -EINVAL; + break; + } audio->str_cfg.buffer_size = cfg.buffer_size; audio->str_cfg.buffer_count = cfg.buffer_count; if (audio->opened) { diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index 07ac7aa04340..37687def1ece 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -226,7 +226,7 @@ struct audio_client *q6asm_get_audio_client(int session_id); int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt); + uint32_t bufcnt); int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir /* 1:Out,0:In */, struct audio_client *ac, diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index e84e5b1969cc..48eebd1b9bd4 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1232,7 +1232,7 @@ err: int q6asm_audio_client_buf_alloc(unsigned int dir, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt) + uint32_t bufcnt) { int cnt = 0; int rc = 0; @@ -1259,7 +1259,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, return 0; } mutex_lock(&ac->cmd_lock); - if (bufcnt > (LONG_MAX/sizeof(struct audio_buffer))) { + if (bufcnt > (U32_MAX/sizeof(struct audio_buffer))) { pr_err("%s: Buffer size overflows", __func__); mutex_unlock(&ac->cmd_lock); goto fail; -- cgit v1.2.3 From a1332745c86882d2c63efae34fb16af22d703dbe Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Thu, 15 Sep 2016 17:09:40 -0700 Subject: msm: camera: cpp: Validate frame message before manipulating it. CPP frame message is used to send all frame data to Microcontroller. It is sent every frame. CPP kernel driver has to add information to it before transfer it. The message has to be validated before manipulations. If it is not valid the message and corresponding frame are discarded. Bug: 30074605 CRs-Fixed: 1049826 Change-Id: I3e11ca7f6df4bb0d928512f81f3e3dc40fed791a Signed-off-by: Rajakumar Govindaram Signed-off-by: Biswajit Paul --- .../platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 26 ++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index a4d1b667ccc5..fe12ef5bddca 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -2274,21 +2274,19 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, return -EINVAL; } - if (!new_frame->partial_frame_indicator) { - if (cpp_frame_msg[new_frame->msg_len - 1] != - MSM_CPP_MSG_ID_TRAILER) { - pr_err("Invalid frame message\n"); - return -EINVAL; - } + if (cpp_frame_msg[new_frame->msg_len - 1] != + MSM_CPP_MSG_ID_TRAILER) { + pr_err("Invalid frame message\n"); + return -EINVAL; + } - if ((stripe_base + new_frame->num_strips * stripe_size + 1) != - new_frame->msg_len) { - pr_err("Invalid frame message,len=%d,expected=%d\n", - new_frame->msg_len, - (stripe_base + - new_frame->num_strips * stripe_size + 1)); - return -EINVAL; - } + if ((stripe_base + new_frame->num_strips * stripe_size + 1) != + new_frame->msg_len) { + pr_err("Invalid frame message,len=%d,expected=%d\n", + new_frame->msg_len, + (stripe_base + + new_frame->num_strips * stripe_size + 1)); + return -EINVAL; } if (cpp_dev->iommu_state != CPP_IOMMU_STATE_ATTACHED) { -- cgit v1.2.3 From 0bd3b3f998850ce64eaf0d2c1ec2a858276e6e8f Mon Sep 17 00:00:00 2001 From: vivek mehta Date: Mon, 29 Aug 2016 18:35:52 -0700 Subject: misc: qcom: qdsp6v2: initialize wma_config_32 Not all memebers of wma_config_32 are set before they are used which might lead to invalid values being passed and used. To fix this issue initialize all member variables of struct wma_config_32 to 0 before assigning specific values individually. Bug: 30593266 Change-Id: Ibb082ce691625527e9a9ffd4978dea7ba4df9e84 Signed-off-by: Siena Richard Signed-off-by: vivek mehta Signed-off-by: Siqi Lin --- drivers/misc/qcom/qdsp6v2/audio_wma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/qcom/qdsp6v2/audio_wma.c b/drivers/misc/qcom/qdsp6v2/audio_wma.c index 3d57d38d0fd1..74f678da925a 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_wma.c +++ b/drivers/misc/qcom/qdsp6v2/audio_wma.c @@ -2,7 +2,7 @@ * * Copyright (C) 2008 Google, Inc. * Copyright (C) 2008 HTC Corporation - * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2009-2016, The Linux Foundation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -166,6 +166,8 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_wma_config_v2 *wma_config; struct msm_audio_wma_config_v2_32 wma_config_32; + memset(&wma_config_32, 0, sizeof(wma_config_32)); + wma_config = (struct msm_audio_wma_config_v2 *)audio->codec_cfg; wma_config_32.format_tag = wma_config->format_tag; wma_config_32.numchannels = wma_config->numchannels; -- cgit v1.2.3 From d83ab1b2bb99aee8e688e147dc822487ef6229ea Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Thu, 5 May 2016 16:22:26 -0700 Subject: UPSTREAM: proc: prevent accessing /proc//environ until it's ready (cherry picked from commit 8148a73c9901a8794a50f950083c00ccf97d43b3) If /proc//environ gets read before the envp[] array is fully set up in create_{aout,elf,elf_fdpic,flat}_tables(), we might end up trying to read more bytes than are actually written, as env_start will already be set but env_end will still be zero, making the range calculation underflow, allowing to read beyond the end of what has been written. Fix this as it is done for /proc//cmdline by testing env_end for zero. It is, apparently, intentionally set last in create_*_tables(). This bug was found by the PaX size_overflow plugin that detected the arithmetic underflow of 'this_len = env_end - (env_start + src)' when env_end is still zero. The expected consequence is that userland trying to access /proc//environ of a not yet fully set up process may get inconsistent data as we're in the middle of copying in the environment variables. Fixes: https://forums.grsecurity.net/viewtopic.php?f=3&t=4363 Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=116461 Signed-off-by: Mathias Krause Cc: Emese Revfy Cc: Pax Team Cc: Al Viro Cc: Mateusz Guzik Cc: Alexey Dobriyan Cc: Cyrill Gorcunov Cc: Jarod Wilson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Change-Id: Ia2f58d48c15478ed4b6e237b63e704c70ff21e96 Bug: 30951939 --- fs/proc/base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 34835390bd2c..d523b23b4464 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -752,7 +752,8 @@ static ssize_t environ_read(struct file *file, char __user *buf, int ret = 0; struct mm_struct *mm = file->private_data; - if (!mm) + /* Ensure the process spawned far enough to have an environment. */ + if (!mm || !mm->env_end) return 0; page = (char *)__get_free_page(GFP_TEMPORARY); -- cgit v1.2.3 From 702a4b9b994ecbc05df6df95c7c82b4559e17d15 Mon Sep 17 00:00:00 2001 From: Jianqiang Zhao Date: Fri, 22 Jul 2016 18:25:36 +0800 Subject: msm: msm_bus: fix stack overflow bug Bug: 30311977 Signed-off-by: Jianqiang Zhao Change-Id: I0b9390bcb2e51b4b0ff6e47727ea19f467777fd6 --- drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c b/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c index e4c8f1f446df..01551219fd72 100644 --- a/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c +++ b/drivers/platform/msm/msm_bus/msm_bus_dbg_voter.c @@ -133,10 +133,11 @@ static ssize_t bus_floor_vote_store_api(struct device *dev, return 0; } - if (sscanf(buf, "%s %llu", name, &vote_khz) != 2) { + if (sscanf(buf, "%9s %llu", name, &vote_khz) != 2) { pr_err("%s:return error", __func__); return -EINVAL; } + name[9] = '\0'; pr_info("%s: name %s vote %llu\n", __func__, name, vote_khz); -- cgit v1.2.3 From b8c7a3985f9a1992a326f5ea734c321b9e6c6690 Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Tue, 16 Aug 2016 11:24:00 -0600 Subject: soc: qcom: smp2p: Fix kernel address leak Change format string to %pK instead of %p in the debug statements. This change fixes kernel address leaks from the usage of %p. Bug: 30312054 CRs-Fixed: 1052825 Change-Id: Ib95f691919a2977f5436cd4c6ac4a002d70dd729 Signed-off-by: Chris Lew Signed-off-by: Karthikeyan Ramasubramanian --- drivers/gpio/gpio-msm-smp2p.c | 2 +- drivers/soc/qcom/smp2p.c | 6 +++--- drivers/soc/qcom/smp2p_debug.c | 4 ++-- drivers/soc/qcom/smp2p_test_common.h | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpio-msm-smp2p.c b/drivers/gpio/gpio-msm-smp2p.c index bde81f0473bd..b426a804c0fa 100644 --- a/drivers/gpio/gpio-msm-smp2p.c +++ b/drivers/gpio/gpio-msm-smp2p.c @@ -368,7 +368,7 @@ static int smp2p_irq_map(struct irq_domain *domain_ptr, unsigned int virq, chip = domain_ptr->host_data; if (!chip) { - SMP2P_ERR("%s: invalid domain ptr %p\n", __func__, domain_ptr); + SMP2P_ERR("%s: invalid domain ptr\n", __func__); return -ENODEV; } diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index fc5688b4bc8c..79b8ffbc5ee7 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p.c * - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -519,8 +519,8 @@ static void smp2p_find_entry_v1(struct smp2p_smem __iomem *item, char entry_name[SMP2P_MAX_ENTRY_NAME]; if (!item || !name || !entry_ptr) { - SMP2P_ERR("%s: invalid arguments %p, %p, %p\n", - __func__, item, name, entry_ptr); + SMP2P_ERR("%s: invalid arguments %d %d %d\n", + __func__, !item, !name, !entry_ptr); return; } diff --git a/drivers/soc/qcom/smp2p_debug.c b/drivers/soc/qcom/smp2p_debug.c index 4deb05a08139..8d98d07c1adf 100644 --- a/drivers/soc/qcom/smp2p_debug.c +++ b/drivers/soc/qcom/smp2p_debug.c @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p_debug.c * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -41,7 +41,7 @@ static void smp2p_int_stats(struct seq_file *s) pid != SMP2P_REMOTE_MOCK_PROC) continue; - seq_printf(s, "| %5s (%d) | %11u | %10u | %10u | %p | %08x |\n", + seq_printf(s, "| %5s (%d) | %11u | %10u | %10u | %pK | %08x |\n", int_cfg[pid].name, pid, int_cfg[pid].in_int_id, int_cfg[pid].in_interrupt_count, diff --git a/drivers/soc/qcom/smp2p_test_common.h b/drivers/soc/qcom/smp2p_test_common.h index 747a812d82c5..3be519bc0c96 100644 --- a/drivers/soc/qcom/smp2p_test_common.h +++ b/drivers/soc/qcom/smp2p_test_common.h @@ -1,6 +1,6 @@ /* drivers/soc/qcom/smp2p_test_common.h * - * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2014,2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -49,7 +49,8 @@ void *a_tmp = (a); \ void *b_tmp = (b); \ if (!((a_tmp)cmp(b_tmp))) { \ - seq_printf(s, "%s:%d Fail: " #a "(%p) " #cmp " " #b "(%p)\n", \ + seq_printf(s, "%s:%d Fail: " #a "(%pK) " #cmp \ + " " #b "(%pK)\n", \ __func__, __LINE__, \ a_tmp, b_tmp); \ failed = 1; \ -- cgit v1.2.3 From 71aa2fe9f64d1655a0c493c5b06eb94109c84aa6 Mon Sep 17 00:00:00 2001 From: Calvin Owens Date: Fri, 30 Oct 2015 16:57:00 -0700 Subject: UPSTREAM: sg: Fix double-free when drives detach during SG_IO (cherry picked from commit f3951a3709ff50990bf3e188c27d346792103432) In sg_common_write(), we free the block request and return -ENODEV if the device is detached in the middle of the SG_IO ioctl(). Unfortunately, sg_finish_rem_req() also tries to free srp->rq, so we end up freeing rq->cmd in the already free rq object, and then free the object itself out from under the current user. This ends up corrupting random memory via the list_head on the rq object. The most common crash trace I saw is this: ------------[ cut here ]------------ kernel BUG at block/blk-core.c:1420! Call Trace: [] blk_put_request+0x5b/0x80 [] sg_finish_rem_req+0x6b/0x120 [sg] [] sg_common_write.isra.14+0x459/0x5a0 [sg] [] ? selinux_file_alloc_security+0x48/0x70 [] sg_new_write.isra.17+0x195/0x2d0 [sg] [] sg_ioctl+0x644/0xdb0 [sg] [] do_vfs_ioctl+0x90/0x520 [] ? file_has_perm+0x97/0xb0 [] SyS_ioctl+0x91/0xb0 [] tracesys+0xdd/0xe2 RIP [] __blk_put_request+0x154/0x1a0 The solution is straightforward: just set srp->rq to NULL in the failure branch so that sg_finish_rem_req() doesn't attempt to re-free it. Additionally, since sg_rq_end_io() will never be called on the object when this happens, we need to free memory backing ->cmd if it isn't embedded in the object itself. KASAN was extremely helpful in finding the root cause of this bug. Signed-off-by: Calvin Owens Acked-by: Douglas Gilbert Signed-off-by: Martin K. Petersen Change-Id: I905fb1e66eff9a919e5059934d5165acb6c39980 Bug: 30951599 --- drivers/scsi/sg.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7c4903b618c9..8a2a593c41e9 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -788,8 +788,14 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, return k; /* probably out of space --> ENOMEM */ } if (atomic_read(&sdp->detaching)) { - if (srp->bio) + if (srp->bio) { + if (srp->rq->cmd != srp->rq->__cmd) + kfree(srp->rq->cmd); + blk_end_request_all(srp->rq, -EIO); + srp->rq = NULL; + } + sg_finish_rem_req(srp); return -ENODEV; } -- cgit v1.2.3 From dcd56c50f685c7b7430aa133a48709ba1e06e8de Mon Sep 17 00:00:00 2001 From: Phil Turnbull Date: Tue, 2 Feb 2016 13:36:45 -0500 Subject: BACKPORT: netfilter: nfnetlink: correctly validate length of batch messages (cherry picked from commit c58d6c93680f28ac58984af61d0a7ebf4319c241) If nlh->nlmsg_len is zero then an infinite loop is triggered because 'skb_pull(skb, msglen);' pulls zero bytes. The calculation in nlmsg_len() underflows if 'nlh->nlmsg_len < NLMSG_HDRLEN' which bypasses the length validation and will later trigger an out-of-bound read. If the length validation does fail then the malformed batch message is copied back to userspace. However, we cannot do this because the nlh->nlmsg_len can be invalid. This leads to an out-of-bounds read in netlink_ack: [ 41.455421] ================================================================== [ 41.456431] BUG: KASAN: slab-out-of-bounds in memcpy+0x1d/0x40 at addr ffff880119e79340 [ 41.456431] Read of size 4294967280 by task a.out/987 [ 41.456431] ============================================================================= [ 41.456431] BUG kmalloc-512 (Not tainted): kasan: bad access detected [ 41.456431] ----------------------------------------------------------------------------- ... [ 41.456431] Bytes b4 ffff880119e79310: 00 00 00 00 d5 03 00 00 b0 fb fe ff 00 00 00 00 ................ [ 41.456431] Object ffff880119e79320: 20 00 00 00 10 00 05 00 00 00 00 00 00 00 00 00 ............... [ 41.456431] Object ffff880119e79330: 14 00 0a 00 01 03 fc 40 45 56 11 22 33 10 00 05 .......@EV."3... [ 41.456431] Object ffff880119e79340: f0 ff ff ff 88 99 aa bb 00 14 00 0a 00 06 fe fb ................ ^^ start of batch nlmsg with nlmsg_len=4294967280 ... [ 41.456431] Memory state around the buggy address: [ 41.456431] ffff880119e79400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 41.456431] ffff880119e79480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 41.456431] >ffff880119e79500: 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc fc [ 41.456431] ^ [ 41.456431] ffff880119e79580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 41.456431] ffff880119e79600: fc fc fc fc fc fc fc fc fc fc fb fb fb fb fb fb [ 41.456431] ================================================================== Fix this with better validation of nlh->nlmsg_len and by setting NFNL_BATCH_FAILURE if any batch message fails length validation. CAP_NET_ADMIN is required to trigger the bugs. Fixes: 9ea2aa8b7dba ("netfilter: nfnetlink: validate nfnetlink header from batch") Signed-off-by: Phil Turnbull Signed-off-by: Pablo Neira Ayuso Change-Id: Id3e15c40cb464bf2791af907c235d8a316b2449c Bug: 30947055 --- net/netfilter/nfnetlink.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index e41bab38a3ca..daec7d6957a9 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -321,10 +321,12 @@ replay: nlh = nlmsg_hdr(skb); err = 0; - if (nlmsg_len(nlh) < sizeof(struct nfgenmsg) || - skb->len < nlh->nlmsg_len) { - err = -EINVAL; - goto ack; + if (nlh->nlmsg_len < NLMSG_HDRLEN || + skb->len < nlh->nlmsg_len || + nlmsg_len(nlh) < sizeof(struct nfgenmsg)) { + nfnl_err_reset(&err_list); + success = false; + goto done; } /* Only requests are handled by the kernel */ -- cgit v1.2.3 From db109d43ca581031a1cea713c4073db30a1cd3b6 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 17 Oct 2015 22:57:06 -0400 Subject: UPSTREAM: ext4: fix potential use after free in __ext4_journal_stop There is a use-after-free possibility in __ext4_journal_stop() in the case that we free the handle in the first jbd2_journal_stop() because we're referencing handle->h_err afterwards. This was introduced in 9705acd63b125dee8b15c705216d7186daea4625 and it is wrong. Fix it by storing the handle->h_err value beforehand and avoid referencing potentially freed handle. Fixes: 9705acd63b125dee8b15c705216d7186daea4625 Signed-off-by: Lukas Czerner Reviewed-by: Andreas Dilger Cc: stable@vger.kernel.org Signed-off-by: Steve Pfetsch (cherry picked from commit 6934da9238da947628be83635e365df41064b09b) Bug: 30952474 Change-Id: Ic8490cb55cb42ccb47c4dc6a819a3bc4fad6246f --- fs/ext4/ext4_jbd2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index d41843181818..e770c1ee4613 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -88,13 +88,13 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) return 0; } + err = handle->h_err; if (!handle->h_transaction) { - err = jbd2_journal_stop(handle); - return handle->h_err ? handle->h_err : err; + rc = jbd2_journal_stop(handle); + return err ? err : rc; } sb = handle->h_transaction->t_journal->j_private; - err = handle->h_err; rc = jbd2_journal_stop(handle); if (!err) -- cgit v1.2.3 From 505e48f32f1321ed7cf80d49dd5f31b16da445a8 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Mon, 12 Sep 2016 15:47:42 -0700 Subject: cgroup: prefer %pK to %p Prevents leaking kernel pointers when using kptr_restrict. Bug: 30149174 Change-Id: I0fa3cd8d4a0d9ea76d085bba6020f1eda073c09b --- kernel/cgroup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cgroup.c b/kernel/cgroup.c index bf2543b6f341..359a50e63e1e 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -5566,7 +5566,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) struct task_struct *task; int count = 0; - seq_printf(seq, "css_set %p\n", cset); + seq_printf(seq, "css_set %pK\n", cset); list_for_each_entry(task, &cset->tasks, cg_list) { if (count++ > MAX_TASKS_SHOWN_PER_CSS) -- cgit v1.2.3 From 99ee5e6cf33a3280e030c4b973b1492fae6ea930 Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Wed, 24 Aug 2016 20:49:31 +0530 Subject: msm: kgsl: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which evaluates whether kptr_restrict is set. Bug: 30228438 CRs-Fixed: 1052818 Change-Id: I0778e43e0a03852ca2944377256a7b401586a747 Signed-off-by: Divya Ponnusamy Signed-off-by: Biswajit Paul Signed-off-by: Yueyao (Nathan) Zhu --- drivers/gpu/msm/adreno_debugfs.c | 2 +- drivers/gpu/msm/kgsl.c | 5 ++--- drivers/gpu/msm/kgsl_cffdump.c | 7 ------- drivers/gpu/msm/kgsl_cmdbatch.c | 2 +- drivers/gpu/msm/kgsl_iommu.c | 16 ++++++++-------- drivers/gpu/msm/kgsl_snapshot.c | 4 ---- 6 files changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index 9cbcd06d7658..680827e5b848 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -138,7 +138,7 @@ static void sync_event_print(struct seq_file *s, break; } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: - seq_printf(s, "sync: [%p] %s", sync_event->handle, + seq_printf(s, "sync: [%pK] %s", sync_event->handle, (sync_event->handle && sync_event->handle->fence) ? sync_event->handle->fence->name : "NULL"); break; diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 25f1f9d417ea..9ceb38273d8a 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -3890,9 +3890,8 @@ int kgsl_device_platform_probe(struct kgsl_device *device) disable_irq(device->pwrctrl.interrupt_num); KGSL_DRV_INFO(device, - "dev_id %d regs phys 0x%08lx size 0x%08x virt %p\n", - device->id, device->reg_phys, device->reg_len, - device->reg_virt); + "dev_id %d regs phys 0x%08lx size 0x%08x\n", + device->id, device->reg_phys, device->reg_len); rwlock_init(&device->context_lock); diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c index 2e90f78a303c..8e783f8ce017 100644 --- a/drivers/gpu/msm/kgsl_cffdump.c +++ b/drivers/gpu/msm/kgsl_cffdump.c @@ -513,10 +513,6 @@ EXPORT_SYMBOL(kgsl_cffdump_waitirq); static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, void *prev_subbuf, size_t prev_padding) { - pr_debug("kgsl: cffdump: subbuf_start_handler(subbuf=%p, prev_subbuf" - "=%p, prev_padding=%08zx)\n", subbuf, prev_subbuf, - prev_padding); - if (relay_buf_full(buf)) { if (!suspended) { suspended = 1; @@ -573,9 +569,6 @@ static struct rchan *create_channel(unsigned subbuf_size, unsigned n_subbufs) { struct rchan *chan; - pr_info("kgsl: cffdump: relay: create_channel: subbuf_size %u, " - "n_subbufs %u, dir 0x%p\n", subbuf_size, n_subbufs, dir); - chan = relay_open("cpu", dir, subbuf_size, n_subbufs, &relay_callbacks, NULL); if (!chan) { diff --git a/drivers/gpu/msm/kgsl_cmdbatch.c b/drivers/gpu/msm/kgsl_cmdbatch.c index ceca8b1e1522..6272410ce544 100644 --- a/drivers/gpu/msm/kgsl_cmdbatch.c +++ b/drivers/gpu/msm/kgsl_cmdbatch.c @@ -80,7 +80,7 @@ void kgsl_dump_syncpoints(struct kgsl_device *device, } case KGSL_CMD_SYNCPOINT_TYPE_FENCE: if (event->handle) - dev_err(device->dev, " fence: [%p] %s\n", + dev_err(device->dev, " fence: [%pK] %s\n", event->handle->fence, event->handle->name); else diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index 290bbd76e8e4..9be7914aa0cf 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -277,8 +277,8 @@ static int _iommu_map_sync_pc(struct kgsl_pagetable *pt, _unlock_if_secure_mmu(memdesc, pt->mmu); if (ret) { - KGSL_CORE_ERR("map err: %p, 0x%016llX, 0x%llx, 0x%x, %d\n", - iommu_pt->domain, gpuaddr, size, flags, ret); + KGSL_CORE_ERR("map err: 0x%016llX, 0x%llx, 0x%x, %d\n", + gpuaddr, size, flags, ret); return -ENODEV; } @@ -305,8 +305,8 @@ static int _iommu_unmap_sync_pc(struct kgsl_pagetable *pt, _unlock_if_secure_mmu(memdesc, pt->mmu); if (unmapped != size) { - KGSL_CORE_ERR("unmap err: %p, 0x%016llx, 0x%llx, %zd\n", - iommu_pt->domain, addr, size, unmapped); + KGSL_CORE_ERR("unmap err: 0x%016llx, 0x%llx, %zd\n", + addr, size, unmapped); return -ENODEV; } @@ -375,8 +375,8 @@ static int _iommu_map_sg_offset_sync_pc(struct kgsl_pagetable *pt, if (size != 0) { /* Cleanup on error */ _iommu_unmap_sync_pc(pt, memdesc, addr, mapped); - KGSL_CORE_ERR("map err: %p, 0x%016llX, %d, %x, %zd\n", - iommu_pt->domain, addr, nents, flags, mapped); + KGSL_CORE_ERR("map err: 0x%016llX, %d, %x, %zd\n", + addr, nents, flags, mapped); return -ENODEV; } @@ -405,8 +405,8 @@ static int _iommu_map_sg_sync_pc(struct kgsl_pagetable *pt, _unlock_if_secure_mmu(memdesc, pt->mmu); if (mapped == 0) { - KGSL_CORE_ERR("map err: %p, 0x%016llX, %d, %x, %zd\n", - iommu_pt->domain, addr, nents, flags, mapped); + KGSL_CORE_ERR("map err: 0x%016llX, %d, %x, %zd\n", + addr, nents, flags, mapped); return -ENODEV; } diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c index 69ae2e3fd2d7..debea073dff1 100644 --- a/drivers/gpu/msm/kgsl_snapshot.c +++ b/drivers/gpu/msm/kgsl_snapshot.c @@ -1035,10 +1035,6 @@ void kgsl_snapshot_save_frozen_objs(struct work_struct *work) goto done; snapshot->mempool = vmalloc(size); - if (snapshot->mempool != NULL) - KGSL_CORE_ERR("snapshot: mempool address %p, size %zx\n", - snapshot->mempool, size); - ptr = snapshot->mempool; snapshot->mempool_size = 0; -- cgit v1.2.3 From 358cae34fce9be2df94d35b4f772c9800b55c17a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 15 Dec 2015 13:49:05 +0100 Subject: UPSTREAM: perf: Fix race in swevent hash (cherry picked from commit 12ca6ad2e3a896256f086497a7c7406a547ee373) There's a race on CPU unplug where we free the swevent hash array while it can still have events on. This will result in a use-after-free which is BAD. Simply do not free the hash array on unplug. This leaves the thing around and no use-after-free takes place. When the last swevent dies, we do a for_each_possible_cpu() iteration anyway to clean these up, at which time we'll free it, so no leakage will occur. Reported-by: Sasha Levin Tested-by: Sasha Levin Signed-off-by: Peter Zijlstra (Intel) Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Cc: Vince Weaver Signed-off-by: Ingo Molnar Change-Id: I4972ce74211b6504ff61325c4a4f7b088306d1f9 Bug: 30952077 Signed-off-by: Yueyao (Nathan) Zhu --- kernel/events/core.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 0f199112722f..1241a05d3be9 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -5729,9 +5729,6 @@ struct swevent_htable { /* Recursion avoidance in each contexts */ int recursion[PERF_NR_CONTEXTS]; - - /* Keeps track of cpu being initialized/exited */ - bool online; }; static DEFINE_PER_CPU(struct swevent_htable, swevent_htable); @@ -5978,14 +5975,8 @@ static int perf_swevent_add(struct perf_event *event, int flags) hwc->state = !(flags & PERF_EF_START); head = find_swevent_head(swhash, event); - if (!head) { - /* - * We can race with cpu hotplug code. Do not - * WARN if the cpu just got unplugged. - */ - WARN_ON_ONCE(swhash->online); + if (WARN_ON_ONCE(!head)) return -EINVAL; - } hlist_add_head_rcu(&event->hlist_entry, head); @@ -6053,7 +6044,6 @@ static int swevent_hlist_get_cpu(struct perf_event *event, int cpu) int err = 0; mutex_lock(&swhash->hlist_mutex); - if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) { struct swevent_hlist *hlist; @@ -8178,7 +8168,6 @@ static void perf_event_init_cpu(int cpu) struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); mutex_lock(&swhash->hlist_mutex); - swhash->online = true; if (swhash->hlist_refcount > 0) { struct swevent_hlist *hlist; @@ -8278,14 +8267,7 @@ static void perf_event_start_swclock(int cpu) static void perf_event_exit_cpu(int cpu) { - struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); - perf_event_exit_cpu_context(cpu); - - mutex_lock(&swhash->hlist_mutex); - swhash->online = false; - swevent_hlist_release(swhash); - mutex_unlock(&swhash->hlist_mutex); } #else static inline void perf_event_exit_cpu(int cpu) { } -- cgit v1.2.3 From 5a54ca08ea924cdd4fa4da72ac0af2b9d68d215b Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Tue, 16 Aug 2016 12:46:12 -0700 Subject: msm: crypto: Fix integer over flow check in qcrypto driver Integer overflow check is invalid when ULONG_MAX is used, as ULONG_MAX has typeof 'unsigned long', while req->assoclen, req->crytlen, and qreq.ivsize are 'unsigned int'. Make change to use UINT_MAX instead of ULONG_MAX. Bug: 30515053 CRs-fixed: 1050970 Change-Id: I3782ea7ed2eaacdcad15b34e047a4699bf4f9e4f Signed-off-by: Zhen Kong Signed-off-by: Biswajit Paul Signed-off-by: Yueyao (Nathan) Zhu --- drivers/crypto/msm/qcrypto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index 4c50a33ab4fe..3324c9d164c4 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -2261,12 +2261,12 @@ static int _qcrypto_process_aead(struct crypto_engine *pengine, * include assoicated data, ciphering data stream, * generated MAC, and CCM padding. */ - if ((MAX_ALIGN_SIZE * 2 > ULONG_MAX - req->assoclen) || + if ((MAX_ALIGN_SIZE * 2 > UINT_MAX - req->assoclen) || ((MAX_ALIGN_SIZE * 2 + req->assoclen) > - ULONG_MAX - qreq.ivsize) || + UINT_MAX - qreq.ivsize) || ((MAX_ALIGN_SIZE * 2 + req->assoclen + qreq.ivsize) - > ULONG_MAX - req->cryptlen)) { + > UINT_MAX - req->cryptlen)) { pr_err("Integer overflow on aead req length.\n"); return -EINVAL; } -- cgit v1.2.3 From f74716108d775b560e9abe5111cbbe6856805fed Mon Sep 17 00:00:00 2001 From: Praveen Chavan Date: Mon, 29 Aug 2016 15:11:36 -0700 Subject: msm: vidc: use %pK instead of %p which respects kptr_restrict sysctl. Hide kernel pointers from unprivileged ussers by using %pK format- specifier instead of %p. This respects the kptr_restrict sysctl setting which is by default on. So by default %pK will print zeroes as address. echo 1 to kptr_restrict to print proper kernel addresses. Author: Abdulla Anam CRs-Fixed: 987018 Change-Id: I4772257a557c6730ecc0624cbc8e5614e893e9fd Signed-off-by: Abdulla Anam Signed-off-by: Mishra Mahima Signed-off-by: Praveen Chavan Signed-off-by: Yueyao (Nathan) Zhu Bug: 30076504 --- .../msm/vidc/governors/msm_vidc_table_gov.c | 6 +- .../media/platform/msm/vidc/hfi_packetization.c | 6 +- .../media/platform/msm/vidc/hfi_response_handler.c | 6 +- drivers/media/platform/msm/vidc/msm_smem.c | 32 +++--- drivers/media/platform/msm/vidc/msm_v4l2_vidc.c | 4 +- drivers/media/platform/msm/vidc/msm_vdec.c | 34 +++--- drivers/media/platform/msm/vidc/msm_venc.c | 34 +++--- drivers/media/platform/msm/vidc/msm_vidc.c | 30 ++--- drivers/media/platform/msm/vidc/msm_vidc_common.c | 122 ++++++++++----------- drivers/media/platform/msm/vidc/msm_vidc_dcvs.c | 16 +-- drivers/media/platform/msm/vidc/msm_vidc_debug.c | 21 ++-- .../media/platform/msm/vidc/msm_vidc_res_parse.c | 6 +- drivers/media/platform/msm/vidc/venus_boot.c | 4 +- drivers/media/platform/msm/vidc/venus_hfi.c | 52 ++++----- drivers/media/platform/msm/vidc/vidc_hfi.c | 4 +- drivers/media/platform/msm/vidc/vmem/vmem.c | 7 +- 16 files changed, 191 insertions(+), 193 deletions(-) diff --git a/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c b/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c index f733c08ecd95..dded8a25961a 100644 --- a/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c +++ b/drivers/media/platform/msm/vidc/governors/msm_vidc_table_gov.c @@ -90,7 +90,7 @@ static int msm_vidc_table_get_target_freq(struct devfreq *dev, int i = 0; if (!dev || !frequency || !flag) { - dprintk(VIDC_ERR, "%s: Invalid params %p, %p, %p\n", + dprintk(VIDC_ERR, "%s: Invalid params %pK, %pK, %pK\n", __func__, dev, frequency, flag); return -EINVAL; } @@ -173,7 +173,7 @@ static int msm_vidc_free_bus_table(struct platform_device *pdev, int rc = 0, i = 0; if (!pdev || !data) { - dprintk(VIDC_ERR, "%s: invalid args %p %p\n", + dprintk(VIDC_ERR, "%s: invalid args %pK %pK\n", __func__, pdev, data); return -EINVAL; } @@ -197,7 +197,7 @@ static int msm_vidc_load_bus_table(struct platform_device *pdev, struct device_node *child_node = NULL; if (!pdev || !data) { - dprintk(VIDC_ERR, "%s: invalid args %p %p\n", + dprintk(VIDC_ERR, "%s: invalid args %pK %pK\n", __func__, pdev, data); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c index 2b6246d7e101..ed5edfda9c75 100644 --- a/drivers/media/platform/msm/vidc/hfi_packetization.c +++ b/drivers/media/platform/msm/vidc/hfi_packetization.c @@ -1456,7 +1456,7 @@ int create_pkt_cmd_session_set_property( break; default: dprintk(VIDC_ERR, - "Invalid Rate control setting: %p\n", + "Invalid Rate control setting: %pK\n", pdata); break; } @@ -2175,7 +2175,7 @@ int create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, struct hfi_cmd_sys_test_ssr_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "Invalid params, device: %p\n", pkt); + dprintk(VIDC_ERR, "Invalid params, device: %pK\n", pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_test_ssr_packet); @@ -2188,7 +2188,7 @@ int create_pkt_cmd_sys_image_version( struct hfi_cmd_sys_get_property_packet *pkt) { if (!pkt) { - dprintk(VIDC_ERR, "%s invalid param :%p\n", __func__, pkt); + dprintk(VIDC_ERR, "%s invalid param :%pK\n", __func__, pkt); return -EINVAL; } pkt->size = sizeof(struct hfi_cmd_sys_get_property_packet); diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c index dd9973b965f9..b4bcf2a61435 100644 --- a/drivers/media/platform/msm/vidc/hfi_response_handler.c +++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c @@ -955,7 +955,7 @@ static enum vidc_status hfi_parse_init_done_properties( } default: dprintk(VIDC_DBG, - "%s: default case - data_ptr %p, prop_id 0x%x\n", + "%s: default case - data_ptr %pK, prop_id 0x%x\n", __func__, data_ptr, prop_id); break; } @@ -1055,7 +1055,7 @@ static void hfi_process_sess_get_prop_profile_level( dprintk(VIDC_DBG, "Entered %s\n", __func__); if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_profile_level: bad_prop: %p\n", + "hal_process_sess_get_profile_level: bad_prop: %pK\n", prop); return; } @@ -1086,7 +1086,7 @@ static void hfi_process_sess_get_prop_buf_req( if (!prop) { dprintk(VIDC_ERR, - "hal_process_sess_get_prop_buf_req: bad_prop: %p\n", + "hal_process_sess_get_prop_buf_req: bad_prop: %pK\n", prop); return; } diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index 4ae13944362a..bb2715654f45 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -45,7 +45,7 @@ static int get_device_address(struct smem_client *smem_client, struct context_bank_info *cb = NULL; if (!iova || !buffer_size || !hndl || !smem_client || !mapping_info) { - dprintk(VIDC_ERR, "Invalid params: %p, %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK, %pK, %pK\n", smem_client, hndl, iova, buffer_size); return -EINVAL; } @@ -107,7 +107,7 @@ static int get_device_address(struct smem_client *smem_client, } if (table->sgl) { dprintk(VIDC_DBG, - "%s: CB : %s, DMA buf: %p, device: %p, attach: %p, table: %p, table sgl: %p, rc: %d, dma_address: %pa\n", + "%s: CB : %s, DMA buf: %pK, device: %pK, attach: %pK, table: %pK, table sgl: %pK, rc: %d, dma_address: %pa\n", __func__, cb->name, buf, cb->dev, attach, table, table->sgl, rc, &table->sgl->dma_address); @@ -137,7 +137,7 @@ static int get_device_address(struct smem_client *smem_client, } } - dprintk(VIDC_DBG, "mapped ion handle %p to %pa\n", hndl, iova); + dprintk(VIDC_DBG, "mapped ion handle %pK to %pa\n", hndl, iova); return 0; mem_map_sg_failed: dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL); @@ -157,7 +157,7 @@ static void put_device_address(struct smem_client *smem_client, struct ion_client *clnt = NULL; if (!hndl || !smem_client || !mapping_info) { - dprintk(VIDC_WARN, "Invalid params: %p, %p\n", + dprintk(VIDC_WARN, "Invalid params: %pK, %pK\n", smem_client, hndl); return; } @@ -175,7 +175,7 @@ static void put_device_address(struct smem_client *smem_client, } if (is_iommu_present(smem_client->res)) { dprintk(VIDC_DBG, - "Calling dma_unmap_sg - device: %p, address: %pa, buf: %p, table: %p, attach: %p\n", + "Calling dma_unmap_sg - device: %pK, address: %pa, buf: %pK, table: %pK, attach: %pK\n", mapping_info->dev, &mapping_info->table->sgl->dma_address, mapping_info->buf, mapping_info->table, @@ -204,9 +204,9 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, unsigned long ion_flags = 0; hndl = ion_import_dma_buf(client->clnt, fd); - dprintk(VIDC_DBG, "%s ion handle: %p\n", __func__, hndl); + dprintk(VIDC_DBG, "%s ion handle: %pK\n", __func__, hndl); if (IS_ERR_OR_NULL(hndl)) { - dprintk(VIDC_ERR, "Failed to get handle: %p, %d, %d, %p\n", + dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n", client, fd, offset, hndl); rc = -ENOMEM; goto fail_import_fd; @@ -242,7 +242,7 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, goto fail_device_address; } dprintk(VIDC_DBG, - "%s: ion_handle = %p, fd = %d, device_addr = %pa, size = %zx, kvaddr = %p, buffer_type = %d, flags = %#lx\n", + "%s: ion_handle = %pK, fd = %d, device_addr = %pa, size = %zx, kvaddr = %pK, buffer_type = %d, flags = %#lx\n", __func__, mem->smem_priv, fd, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); return rc; @@ -339,7 +339,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, hndl = ion_alloc(client->clnt, size, align, heap_mask, ion_flags); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, - "Failed to allocate shared memory = %p, %zx, %d, %#x\n", + "Failed to allocate shared memory = %pK, %zx, %d, %#x\n", client, size, align, flags); rc = -ENOMEM; goto fail_shared_mem_alloc; @@ -377,7 +377,7 @@ static int alloc_ion_mem(struct smem_client *client, size_t size, u32 align, } mem->size = size; dprintk(VIDC_DBG, - "%s: ion_handle = %p, device_addr = %pa, size = %#zx, kvaddr = %p, buffer_type = %#x, flags = %#lx\n", + "%s: ion_handle = %pK, device_addr = %pa, size = %#zx, kvaddr = %pK, buffer_type = %#x, flags = %#lx\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type, mem->flags); return rc; @@ -393,7 +393,7 @@ fail_shared_mem_alloc: static void free_ion_mem(struct smem_client *client, struct msm_smem *mem) { dprintk(VIDC_DBG, - "%s: ion_handle = %p, device_addr = %pa, size = %#zx, kvaddr = %p, buffer_type = %#x\n", + "%s: ion_handle = %pK, device_addr = %pa, size = %#zx, kvaddr = %pK, buffer_type = %#x\n", __func__, mem->smem_priv, &mem->device_addr, mem->size, mem->kvaddr, mem->buffer_type); @@ -408,7 +408,7 @@ static void free_ion_mem(struct smem_client *client, struct msm_smem *mem) (u32)mem->buffer_type, -1, mem->size, -1, mem->flags, -1); dprintk(VIDC_DBG, - "%s: Freeing handle %p, client: %p\n", + "%s: Freeing handle %pK, client: %pK\n", __func__, mem->smem_priv, client->clnt); ion_free(client->clnt, mem->smem_priv); trace_msm_smem_buffer_ion_op_end("FREE", (u32)mem->buffer_type, @@ -469,7 +469,7 @@ bool msm_smem_compare_buffers(void *clt, int fd, void *priv) bool ret = false; if (!clt || !priv) { - dprintk(VIDC_ERR, "Invalid params: %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK\n", clt, priv); return false; } @@ -486,7 +486,7 @@ static int ion_cache_operations(struct smem_client *client, int rc = 0; int msm_cache_ops = 0; if (!mem || !client) { - dprintk(VIDC_ERR, "Invalid params: %p, %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK, %pK\n", mem, client); return -EINVAL; } @@ -533,7 +533,7 @@ int msm_smem_cache_operations(void *clt, struct msm_smem *mem, struct smem_client *client = clt; int rc = 0; if (!client) { - dprintk(VIDC_ERR, "Invalid params: %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK\n", client); return -EINVAL; } @@ -684,7 +684,7 @@ struct context_bank_info *msm_smem_get_context_bank(void *clt, cb->buffer_type & buffer_type) { match = cb; dprintk(VIDC_DBG, - "context bank found for CB : %s, device: %p mapping: %p\n", + "context bank found for CB : %s, device: %pK mapping: %pK\n", match->name, match->dev, match->mapping); break; } diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c index 544515a765f6..9d6f325d5a36 100644 --- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c @@ -280,7 +280,7 @@ static int read_platform_resources(struct msm_vidc_core *core, struct platform_device *pdev) { if (!core || !pdev) { - dprintk(VIDC_ERR, "%s: Invalid params %p %p\n", + dprintk(VIDC_ERR, "%s: Invalid params %pK %pK\n", __func__, core, pdev); return -EINVAL; } @@ -657,7 +657,7 @@ static int msm_vidc_remove(struct platform_device *pdev) struct msm_vidc_core *core; if (!pdev) { - dprintk(VIDC_ERR, "%s invalid input %p", __func__, pdev); + dprintk(VIDC_ERR, "%s invalid input %pK", __func__, pdev); return -EINVAL; } diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c index 3ed5f482786d..5e3dd274eedf 100644 --- a/drivers/media/platform/msm/vidc/msm_vdec.c +++ b/drivers/media/platform/msm/vidc/msm_vdec.c @@ -872,7 +872,7 @@ int msm_vdec_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -951,7 +951,7 @@ int msm_vdec_release_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring release output buf\n", + "Core %pK in bad state, ignoring release output buf\n", core); goto exit; } @@ -1049,7 +1049,7 @@ int msm_vdec_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } @@ -1079,7 +1079,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -1526,7 +1526,7 @@ int msm_vdec_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -1546,7 +1546,7 @@ int msm_vdec_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -1604,7 +1604,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q, if (!q || !num_buffers || !num_planes || !sizes || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p, %p, %p\n", + dprintk(VIDC_ERR, "Invalid input, q = %pK, %pK, %pK\n", q, num_buffers, num_planes); return -EINVAL; } @@ -1884,7 +1884,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } msm_dcvs_init_load(inst); @@ -1908,7 +1908,7 @@ static inline int stop_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); return rc; } @@ -1918,7 +1918,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) int rc = 0; struct hfi_device *hdev; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; @@ -1927,7 +1927,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) return -EINVAL; } hdev = inst->core->device; - dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %p\n", + dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n", q->type, inst); switch (q->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: @@ -1945,7 +1945,7 @@ static int msm_vdec_start_streaming(struct vb2_queue *q, unsigned int count) } if (rc) { dprintk(VIDC_ERR, - "Streamon failed on: %d capability for inst: %p\n", + "Streamon failed on: %d capability for inst: %pK\n", q->type, inst); goto stream_start_failed; } @@ -1967,7 +1967,7 @@ static void msm_vdec_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return; } @@ -1993,7 +1993,7 @@ static void msm_vdec_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_RELEASE_RESOURCES_DONE); } @@ -2020,7 +2020,7 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[OUTPUT_PORT] = &vdec_formats[2]; @@ -2748,7 +2748,7 @@ static int msm_vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -2777,7 +2777,7 @@ static int msm_vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } for (c = 0; c < master->ncontrols; ++c) { diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c index 4b7a83d01368..2e79037e18fb 100644 --- a/drivers/media/platform/msm/vidc/msm_venc.c +++ b/drivers/media/platform/msm/vidc/msm_venc.c @@ -1661,13 +1661,13 @@ static inline int msm_venc_power_save_mode_enable(struct msm_vidc_inst *inst) (void *)inst->session, prop_id, pdata); if (rc) { dprintk(VIDC_ERR, - "%s: Failed to set power save mode for inst: %p\n", + "%s: Failed to set power save mode for inst: %pK\n", __func__, inst); goto fail_power_mode_set; } inst->flags |= VIDC_LOW_POWER; msm_dcvs_enc_set_power_save_mode(inst, true); - dprintk(VIDC_INFO, "Power Save Mode set for inst: %p\n", inst); + dprintk(VIDC_INFO, "Power Save Mode set for inst: %pK\n", inst); } fail_power_mode_set: @@ -1712,7 +1712,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst) rc = msm_comm_try_state(inst, MSM_VIDC_START_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto fail_start; } msm_dcvs_init_load(inst); @@ -1726,11 +1726,11 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "Invalid input, q = %p\n", q); + dprintk(VIDC_ERR, "Invalid input, q = %pK\n", q); return -EINVAL; } inst = q->drv_priv; - dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %p\n", + dprintk(VIDC_DBG, "Streamon called on: %d capability for inst: %pK\n", q->type, inst); switch (q->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: @@ -1748,7 +1748,7 @@ static int msm_venc_start_streaming(struct vb2_queue *q, unsigned int count) } if (rc) { dprintk(VIDC_ERR, - "Streamon failed on: %d capability for inst: %p\n", + "Streamon failed on: %d capability for inst: %pK\n", q->type, inst); goto stream_start_failed; } @@ -1770,7 +1770,7 @@ static void msm_venc_stop_streaming(struct vb2_queue *q) struct msm_vidc_inst *inst; int rc = 0; if (!q || !q->drv_priv) { - dprintk(VIDC_ERR, "%s - Invalid input, q = %p\n", __func__, q); + dprintk(VIDC_ERR, "%s - Invalid input, q = %pK\n", __func__, q); return; } @@ -1792,7 +1792,7 @@ static void msm_venc_stop_streaming(struct vb2_queue *q) if (rc) dprintk(VIDC_ERR, - "Failed to move inst: %p, cap = %d to state: %d\n", + "Failed to move inst: %pK, cap = %d to state: %d\n", inst, q->type, MSM_VIDC_CLOSE_DONE); } @@ -3428,7 +3428,7 @@ static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl) if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to start done state\n", inst); + "Failed to move inst: %pK to start done state\n", inst); goto failed_open_done; } @@ -3472,7 +3472,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst) { int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "Invalid input = %p\n", inst); + dprintk(VIDC_ERR, "Invalid input = %pK\n", inst); return -EINVAL; } inst->fmts[CAPTURE_PORT] = &venc_formats[4]; @@ -3516,7 +3516,7 @@ int msm_venc_querycap(struct msm_vidc_inst *inst, struct v4l2_capability *cap) { if (!inst || !cap) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, cap = %p\n", inst, cap); + "Invalid input, inst = %pK, cap = %pK\n", inst, cap); return -EINVAL; } strlcpy(cap->driver, MSM_VIDC_DRV_NAME, sizeof(cap->driver)); @@ -3536,7 +3536,7 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f) int rc = 0; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, f = %p\n", inst, f); + "Invalid input, inst = %pK, f = %pK\n", inst, f); return -EINVAL; } if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { @@ -3593,7 +3593,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) struct hfi_device *hdev; if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3736,7 +3736,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f) if (!inst || !f) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, format = %p\n", inst, f); + "Invalid input, inst = %pK, format = %pK\n", inst, f); return -EINVAL; } @@ -3809,7 +3809,7 @@ int msm_venc_reqbufs(struct msm_vidc_inst *inst, struct v4l2_requestbuffers *b) int rc = 0; if (!inst || !b) { dprintk(VIDC_ERR, - "Invalid input, inst = %p, buffer = %p\n", inst, b); + "Invalid input, inst = %pK, buffer = %pK\n", inst, b); return -EINVAL; } q = msm_comm_get_vb2q(inst, b->type); @@ -3846,7 +3846,7 @@ int msm_venc_prepare_buf(struct msm_vidc_inst *inst, if (inst->state == MSM_VIDC_CORE_INVALID || inst->core->state == VIDC_CORE_INVALID) { dprintk(VIDC_ERR, - "Core %p in bad state, ignoring prepare buf\n", + "Core %pK in bad state, ignoring prepare buf\n", inst->core); goto exit; } @@ -3917,7 +3917,7 @@ int msm_venc_release_buf(struct msm_vidc_inst *inst, rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done state\n", + "Failed to move inst: %pK to release res done state\n", inst); goto exit; } diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index 724ab779571e..99e7115358ca 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -288,7 +288,7 @@ struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list, if (!buf_list || !device_addr) { dprintk(VIDC_ERR, - "Invalid input- device_addr: %pa buf_list: %p\n", + "Invalid input- device_addr: %pa buf_list: %pK\n", &device_addr, buf_list); goto err_invalid_input; } @@ -435,7 +435,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } - dprintk(VIDC_DBG, "[MAP] Create binfo = %p fd = %d type = %d\n", + dprintk(VIDC_DBG, "[MAP] Create binfo = %pK fd = %d type = %d\n", binfo, b->m.planes[0].reserved[0], b->type); for (i = 0; i < b->length; ++i) { @@ -524,7 +524,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } dprintk(VIDC_DBG, - "%s: [MAP] binfo = %p, handle[%d] = %p, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [MAP] binfo = %pK, handle[%d] = %pK, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n", __func__, binfo, i, binfo->handle[i], &binfo->device_addr[i], binfo->fd[i], binfo->buff_off[i], binfo->mapped[i]); @@ -547,7 +547,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, bool found = false, keep_node = false; if (!inst || !binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p %p\n", + dprintk(VIDC_ERR, "%s invalid param: %pK %pK\n", __func__, inst, binfo); return -EINVAL; } @@ -577,7 +577,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, for (i = 0; i < temp->num_planes; i++) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n", __func__, temp, i, temp->handle[i], &temp->device_addr[i], temp->fd[i], temp->buff_off[i], temp->mapped[i]); @@ -606,12 +606,12 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst, } } if (!keep_node) { - dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] AND-FREED binfo: %pK\n", temp); list_del(&temp->list); kfree(temp); } else { temp->inactive = true; - dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %p\n", temp); + dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %pK\n", temp); } exit: return 0; @@ -625,7 +625,7 @@ int qbuf_dynamic_buf(struct msm_vidc_inst *inst, struct v4l2_plane plane[VIDEO_MAX_PLANES] = { {0} }; if (!binfo) { - dprintk(VIDC_ERR, "%s invalid param: %p\n", __func__, binfo); + dprintk(VIDC_ERR, "%s invalid param: %pK\n", __func__, binfo); return -EINVAL; } dprintk(VIDC_DBG, "%s fd[0] = %d\n", __func__, binfo->fd[0]); @@ -648,12 +648,12 @@ int output_buffer_cache_invalidate(struct msm_vidc_inst *inst, int rc = 0; if (!inst) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return -EINVAL; } if (!binfo) { - dprintk(VIDC_ERR, "%s: invalid buffer info: %p\n", + dprintk(VIDC_ERR, "%s: invalid buffer info: %pK\n", __func__, inst); return -EINVAL; } @@ -733,7 +733,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type) rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE); if (rc) { dprintk(VIDC_ERR, - "Failed to move inst: %p to release res done\n", + "Failed to move inst: %pK to release res done\n", inst); } } @@ -797,7 +797,7 @@ free_and_unmap: for (i = 0; i < bi->num_planes; i++) { if (bi->handle[i] && bi->mapped[i]) { dprintk(VIDC_DBG, - "%s: [UNMAP] binfo = %p, handle[%d] = %p, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n", + "%s: [UNMAP] binfo = %pK, handle[%d] = %pK, device_addr = %pa, fd = %d, offset = %d, mapped = %d\n", __func__, bi, i, bi->handle[i], &bi->device_addr[i], bi->fd[i], bi->buff_off[i], bi->mapped[i]); @@ -1001,7 +1001,7 @@ int msm_vidc_enum_framesizes(void *instance, struct v4l2_frmsizeenum *fsize) struct msm_vidc_capability *capability = NULL; if (!inst || !fsize) { - dprintk(VIDC_ERR, "%s: invalid parameter: %p %p\n", + dprintk(VIDC_ERR, "%s: invalid parameter: %pK %pK\n", __func__, inst, fsize); return -EINVAL; } @@ -1163,7 +1163,7 @@ void *msm_vidc_open(int core_id, int session_type) goto err_invalid_core; } - pr_info(VIDC_DBG_TAG "Opening video instance: %p, %d\n", + pr_info(VIDC_DBG_TAG "Opening video instance: %pK, %d\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->bufq[CAPTURE_PORT].lock); @@ -1330,7 +1330,7 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst) for (i = 0; i < MAX_PORT_NUM; i++) vb2_queue_release(&inst->bufq[i].vb2_bufq); - pr_info(VIDC_DBG_TAG "Closed video instance: %p\n", + pr_info(VIDC_DBG_TAG "Closed video instance: %pK\n", VIDC_MSG_PRIO2STRING(VIDC_INFO), inst); kfree(inst); return 0; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c index 7103d04d8ef8..a639c28ea2fc 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_common.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c @@ -341,7 +341,7 @@ int msm_comm_get_inst_load(struct msm_vidc_inst *inst, if (is_non_realtime_session(inst) && (quirks & LOAD_CALC_IGNORE_NON_REALTIME_LOAD)) { if (!inst->prop.fps) { - dprintk(VIDC_INFO, "instance:%p fps = 0\n", inst); + dprintk(VIDC_INFO, "instance:%pK fps = 0\n", inst); load = 0; } else { load = msm_comm_get_mbs_per_sec(inst) / inst->prop.fps; @@ -360,7 +360,7 @@ int msm_comm_get_load(struct msm_vidc_core *core, int num_mbs_per_sec = 0; if (!core) { - dprintk(VIDC_ERR, "Invalid args: %p\n", core); + dprintk(VIDC_ERR, "Invalid args: %pK\n", core); return -EINVAL; } @@ -489,13 +489,13 @@ static int msm_comm_vote_bus(struct msm_vidc_core *core) unsigned long core_freq = 0; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -607,7 +607,7 @@ const struct msm_vidc_format *msm_comm_get_pixel_fmt_index( { int i, k = 0; if (!fmt || index < 0) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p, index = %d\n", + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK, index = %d\n", fmt, index); return NULL; } @@ -629,7 +629,7 @@ struct msm_vidc_format *msm_comm_get_pixel_fmt_fourcc( { int i; if (!fmt) { - dprintk(VIDC_ERR, "Invalid inputs, fmt = %p\n", fmt); + dprintk(VIDC_ERR, "Invalid inputs, fmt = %pK\n", fmt); return NULL; } for (i = 0; i < size; i++) { @@ -857,11 +857,11 @@ static void change_inst_state(struct msm_vidc_inst *inst, mutex_lock(&inst->lock); if (inst->state == MSM_VIDC_CORE_INVALID) { dprintk(VIDC_DBG, - "Inst: %p is in bad state can't change state to %d\n", + "Inst: %pK is in bad state can't change state to %d\n", inst, state); goto exit; } - dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n", + dprintk(VIDC_DBG, "Moved inst: %pK from state: %d to state: %d\n", inst, inst->state, state); inst->state = state; exit: @@ -872,7 +872,7 @@ static int signal_session_msg_receipt(enum hal_command_response cmd, struct msm_vidc_inst *inst) { if (!inst) { - dprintk(VIDC_ERR, "Invalid(%p) instance id\n", inst); + dprintk(VIDC_ERR, "Invalid(%pK) instance id\n", inst); return -EINVAL; } if (IS_HAL_SESSION_CMD(cmd)) { @@ -915,7 +915,7 @@ static int wait_for_state(struct msm_vidc_inst *inst, { int rc = 0; if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto err_same_state; } @@ -1121,7 +1121,7 @@ static void handle_event_change(enum hal_command_response cmd, void *data) struct buffer_info *binfo = NULL, *temp = NULL; u32 *ptr = NULL; - dprintk(VIDC_DBG, "%s - inst: %p buffer: %pa extra: %pa\n", + dprintk(VIDC_DBG, "%s - inst: %pK buffer: %pa extra: %pa\n", __func__, inst, &event_notify->packet_buffer, &event_notify->extra_data_buffer); @@ -1542,11 +1542,11 @@ static void handle_session_error(enum hal_command_response cmd, void *data) } hdev = inst->core->device; - dprintk(VIDC_WARN, "Session error received for session %p\n", inst); + dprintk(VIDC_WARN, "Session error received for session %pK\n", inst); change_inst_state(inst, MSM_VIDC_CORE_INVALID); if (response->status == VIDC_ERR_MAX_CLIENTS) { - dprintk(VIDC_WARN, "Too many clients, rejecting %p", inst); + dprintk(VIDC_WARN, "Too many clients, rejecting %pK", inst); event = V4L2_EVENT_MSM_VIDC_MAX_CLIENTS; /* @@ -1558,10 +1558,10 @@ static void handle_session_error(enum hal_command_response cmd, void *data) msm_comm_session_clean(inst); } else if (response->status == VIDC_ERR_NOT_SUPPORTED) { - dprintk(VIDC_WARN, "Unsupported bitstream in %p", inst); + dprintk(VIDC_WARN, "Unsupported bitstream in %pK", inst); event = V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED; } else { - dprintk(VIDC_WARN, "Unknown session error (%d) for %p\n", + dprintk(VIDC_WARN, "Unknown session error (%d) for %pK\n", response->status, inst); event = V4L2_EVENT_MSM_VIDC_SYS_ERROR; } @@ -1578,7 +1578,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) return; } - dprintk(VIDC_WARN, "%s: Core %p\n", __func__, core); + dprintk(VIDC_WARN, "%s: Core %pK\n", __func__, core); mutex_lock(&core->lock); core->state = VIDC_CORE_INVALID; @@ -1587,7 +1587,7 @@ static void msm_comm_clean_notify_client(struct msm_vidc_core *core) inst->state = MSM_VIDC_CORE_INVALID; mutex_unlock(&inst->lock); dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", __func__, inst); + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); } @@ -1615,7 +1615,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) return; } - dprintk(VIDC_WARN, "SYS_ERROR %d received for core %p\n", cmd, core); + dprintk(VIDC_WARN, "SYS_ERROR %d received for core %pK\n", cmd, core); msm_comm_clean_notify_client(core); hdev = core->device; @@ -1647,12 +1647,12 @@ void msm_comm_session_clean(struct msm_vidc_inst *inst) hdev = inst->core->device; mutex_lock(&inst->lock); if (hdev && inst->session) { - dprintk(VIDC_DBG, "cleaning up instance: %p\n", inst); + dprintk(VIDC_DBG, "cleaning up instance: %pK\n", inst); rc = call_hfi_op(hdev, session_clean, (void *)inst->session); if (rc) { dprintk(VIDC_ERR, - "Session clean failed :%p\n", inst); + "Session clean failed :%pK\n", inst); } inst->session = NULL; } @@ -2066,7 +2066,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data) if (extra_idx && extra_idx < VIDEO_MAX_PLANES) { dprintk(VIDC_DBG, - "extradata: userptr = %p;" + "extradata: userptr = %pK;" " bytesused = %d; length = %d\n", (u8 *)vb->v4l2_planes[extra_idx].m.userptr, vb->v4l2_planes[extra_idx].bytesused, @@ -2222,13 +2222,13 @@ int msm_comm_scale_clocks_load(struct msm_vidc_core *core, int codec = 0; if (!core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "%s Invalid device handle: %p\n", + dprintk(VIDC_ERR, "%s Invalid device handle: %pK\n", __func__, hdev); return -EINVAL; } @@ -2402,7 +2402,7 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst) msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, abort_completion); BUG_ON(msm_vidc_debug_timeout); rc = -EBUSY; @@ -2430,7 +2430,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) mutex_unlock(&core->lock); if (inst->state >= MSM_VIDC_OPEN_DONE && inst->state < MSM_VIDC_CLOSE_DONE) { - dprintk(VIDC_WARN, "%s: abort inst %p\n", + dprintk(VIDC_WARN, "%s: abort inst %pK\n", __func__, inst); rc = msm_comm_session_abort(inst); if (rc) { @@ -2441,7 +2441,7 @@ static void handle_thermal_event(struct msm_vidc_core *core) } change_inst_state(inst, MSM_VIDC_CORE_INVALID); dprintk(VIDC_WARN, - "%s Send sys error for inst %p\n", + "%s Send sys error for inst %pK\n", __func__, inst); msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR); @@ -2641,7 +2641,7 @@ static int msm_comm_session_init(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_OPEN)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2663,7 +2663,7 @@ static int msm_comm_session_init(int flipped_state, if (rc || !inst->session) { dprintk(VIDC_ERR, - "Failed to call session init for: %p, %p, %d, %d\n", + "Failed to call session init for: %pK, %pK, %d, %d\n", inst->core->device, inst, inst->session_type, fourcc); rc = -EINVAL; @@ -2752,7 +2752,7 @@ static int msm_vidc_load_resources(int flipped_state, hdev = core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_LOAD_RESOURCES)) { - dprintk(VIDC_INFO, "inst: %p is already in state: %d\n", + dprintk(VIDC_INFO, "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2788,7 +2788,7 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_START)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2818,7 +2818,7 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_STOP)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2848,7 +2848,7 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst) if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_RELEASE_RESOURCES)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -2880,7 +2880,7 @@ static int msm_comm_session_close(int flipped_state, hdev = inst->core->device; if (IS_ALREADY_IN_STATE(flipped_state, MSM_VIDC_CLOSE)) { dprintk(VIDC_INFO, - "inst: %p is already in state: %d\n", + "inst: %pK is already in state: %d\n", inst, inst->state); goto exit; } @@ -3284,16 +3284,16 @@ int msm_comm_try_state(struct msm_vidc_inst *inst, int state) struct msm_vidc_core *core; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } dprintk(VIDC_DBG, - "Trying to move inst: %p from: %#x to %#x\n", + "Trying to move inst: %pK from: %#x to %#x\n", inst, inst->state, state); core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", inst); + "Invalid core pointer = %pK\n", inst); return -EINVAL; } mutex_lock(&inst->sync_lock); @@ -3703,7 +3703,7 @@ int msm_comm_qbuf(struct msm_vidc_inst *inst, struct vb2_buffer *vb) defer = defer ?: batch_mode && (!output_count || !capture_count); if (defer) { - dprintk(VIDC_DBG, "Deferring queue of %p\n", vb); + dprintk(VIDC_DBG, "Deferring queue of %pK\n", vb); return 0; } @@ -3911,7 +3911,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, */ dprintk(VIDC_ERR, - "In Wrong state to call Buf Req: Inst %p or Core %p\n", + "In Wrong state to call Buf Req: Inst %pK or Core %pK\n", inst, inst->core); rc = -EAGAIN; mutex_unlock(&inst->sync_lock); @@ -3946,7 +3946,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype, msecs_to_jiffies(msm_vidc_hw_rsp_timeout)); if (!rc) { dprintk(VIDC_ERR, - "%s: Wait interrupted or timed out [%p]: %d\n", + "%s: Wait interrupted or timed out [%pK]: %d\n", __func__, inst, SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)); inst->state = MSM_VIDC_CORE_INVALID; @@ -3986,7 +3986,7 @@ int msm_comm_release_output_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); @@ -4001,12 +4001,12 @@ int msm_comm_release_output_buffers(struct msm_vidc_inst *inst) core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } mutex_lock(&inst->outputbufs.lock); @@ -4102,18 +4102,18 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst, enum hal_buffer sufficiency = HAL_BUFFER_NONE; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -4190,18 +4190,18 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -4250,7 +4250,7 @@ int msm_comm_try_set_prop(struct msm_vidc_inst *inst, int rc = 0; struct hfi_device *hdev; if (!inst) { - dprintk(VIDC_ERR, "Invalid input: %p\n", inst); + dprintk(VIDC_ERR, "Invalid input: %pK\n", inst); return -EINVAL; } @@ -4462,7 +4462,7 @@ void msm_comm_flush_pending_dynamic_buffers(struct msm_vidc_inst *inst) list_for_each_entry(binfo, &inst->registeredbufs.list, list) { if (binfo->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { dprintk(VIDC_DBG, - "%s: binfo = %p device_addr = %pa\n", + "%s: binfo = %pK device_addr = %pa\n", __func__, binfo, &binfo->device_addr[0]); buf_ref_put(inst, binfo); } @@ -4481,18 +4481,18 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) struct hfi_device *hdev; if (!inst) { dprintk(VIDC_ERR, - "Invalid instance pointer = %p\n", inst); + "Invalid instance pointer = %pK\n", inst); return -EINVAL; } core = inst->core; if (!core) { dprintk(VIDC_ERR, - "Invalid core pointer = %p\n", core); + "Invalid core pointer = %pK\n", core); return -EINVAL; } hdev = core->device; if (!hdev) { - dprintk(VIDC_ERR, "Invalid device pointer = %p\n", hdev); + dprintk(VIDC_ERR, "Invalid device pointer = %pK\n", hdev); return -EINVAL; } @@ -4510,7 +4510,7 @@ int msm_comm_flush(struct msm_vidc_inst *inst, u32 flags) core->state == VIDC_CORE_INVALID || core->state == VIDC_CORE_UNINIT) { dprintk(VIDC_ERR, - "Core %p and inst %p are in bad state\n", + "Core %pK and inst %pK are in bad state\n", core, inst); msm_comm_flush_in_invalid_state(inst); return 0; @@ -4702,7 +4702,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core, int rc = 0; struct hfi_device *hdev; if (!core || !core->device) { - dprintk(VIDC_WARN, "Invalid parameters: %p\n", core); + dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core); return -EINVAL; } hdev = core->device; @@ -4945,7 +4945,7 @@ int msm_comm_kill_session(struct msm_vidc_inst *inst) change_inst_state(inst, MSM_VIDC_CLOSE_DONE); } else { dprintk(VIDC_WARN, - "Inactive session %p, triggering an internal session error\n", + "Inactive session %pK, triggering an internal session error\n", inst); msm_comm_generate_session_error(inst); @@ -4961,7 +4961,7 @@ struct msm_smem *msm_comm_smem_alloc(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } m = msm_smem_alloc(inst->mem_client, size, align, @@ -4973,7 +4973,7 @@ void msm_comm_smem_free(struct msm_vidc_inst *inst, struct msm_smem *mem) { if (!inst || !inst->core || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return; } msm_smem_free(inst->mem_client, mem); @@ -4984,7 +4984,7 @@ int msm_comm_smem_cache_operations(struct msm_vidc_inst *inst, { if (!inst || !mem) { dprintk(VIDC_ERR, - "%s: invalid params: %p %p\n", __func__, inst, mem); + "%s: invalid params: %pK %pK\n", __func__, inst, mem); return -EINVAL; } return msm_smem_cache_operations(inst->mem_client, mem, cache_ops); @@ -4996,7 +4996,7 @@ struct msm_smem *msm_comm_smem_user_to_kernel(struct msm_vidc_inst *inst, struct msm_smem *m = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s: invalid inst: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s: invalid inst: %pK\n", __func__, inst); return NULL; } @@ -5137,7 +5137,7 @@ int msm_vidc_comm_s_parm(struct msm_vidc_inst *inst, struct v4l2_streamparm *a) fps = fps - 1; if (inst->prop.fps != fps) { - dprintk(VIDC_PROF, "reported fps changed for %p: %d->%d\n", + dprintk(VIDC_PROF, "reported fps changed for %pK: %d->%d\n", inst, inst->prop.fps, fps); inst->prop.fps = fps; frame_rate.frame_rate = inst->prop.fps * BIT(16); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c index fd93f7831777..c03f887be6f6 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_dcvs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -47,7 +47,7 @@ static inline int msm_dcvs_count_active_instances(struct msm_vidc_core *core) struct msm_vidc_inst *inst = NULL; if (!core) { - dprintk(VIDC_ERR, "%s: Invalid args: %p\n", __func__, core); + dprintk(VIDC_ERR, "%s: Invalid args: %pK\n", __func__, core); return -EINVAL; } @@ -95,7 +95,7 @@ static void msm_dcvs_update_dcvs_params(int idx, struct msm_vidc_inst *inst) struct dcvs_table *table = NULL; if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -160,7 +160,7 @@ static void msm_dcvs_dec_check_and_scale_clocks(struct msm_vidc_inst *inst) void msm_dcvs_check_and_scale_clocks(struct msm_vidc_inst *inst, bool is_etb) { if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -216,7 +216,7 @@ void msm_dcvs_init_load(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Load\n"); if (!inst || !inst->core) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -289,7 +289,7 @@ void msm_dcvs_init(struct msm_vidc_inst *inst) dprintk(VIDC_DBG, "Init DCVS Struct\n"); if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } @@ -306,7 +306,7 @@ void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) struct hal_buffer_requirements *output_buf_req; if (!inst) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, inst); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, inst); return; } dcvs = &inst->dcvs; @@ -315,7 +315,7 @@ void msm_dcvs_monitor_buffer(struct msm_vidc_inst *inst) output_buf_req = get_buff_req_buffer(inst, msm_comm_get_hal_output_buffer(inst)); if (!output_buf_req) { - dprintk(VIDC_ERR, "%s : Get output buffer req failed %p\n", + dprintk(VIDC_ERR, "%s : Get output buffer req failed %pK\n", __func__, inst); mutex_unlock(&inst->lock); return; diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c index 7a446cb22670..ccb625f289a5 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c @@ -77,13 +77,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, int i = 0, rc = 0; if (!core || !core->device) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); return 0; } hdev = core->device; INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "CORE %d: %p\n", core->id, core); + write_str(&dbg_buf, "CORE %d: %pK\n", core->id, core); write_str(&dbg_buf, "===============================\n"); write_str(&dbg_buf, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); @@ -153,7 +153,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void) struct dentry *f = debugfs_create_##__type(__name, S_IRUGO | S_IWUSR, \ dir, __value); \ if (IS_ERR_OR_NULL(f)) { \ - dprintk(VIDC_ERR, "Failed creating debugfs file '%pd/%s'\n", \ + dprintk(VIDC_ERR, "Failed creating debugfs file '%pKd/%s'\n", \ dir, __name); \ f = NULL; \ } \ @@ -202,7 +202,7 @@ struct dentry *msm_vidc_debugfs_init_core(struct msm_vidc_core *core, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!core) { - dprintk(VIDC_ERR, "Invalid params, core: %p\n", core); + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", core); goto failed_create_dir; } @@ -266,9 +266,8 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, struct msm_vidc_inst *inst = file->private_data; struct msm_vidc_core *core = inst ? inst->core : NULL; int i, j; - if (!inst || !core) { - dprintk(VIDC_ERR, "Invalid params, core: %p inst %p\n", - core, inst); + if (!inst) { + dprintk(VIDC_ERR, "Invalid params, core: %pK\n", inst); return 0; } if (!get_inst(core, inst)) { @@ -278,10 +277,10 @@ static ssize_t inst_info_read(struct file *file, char __user *buf, INIT_DBG_BUF(dbg_buf); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "INSTANCE: %p (%s)\n", inst, + write_str(&dbg_buf, "INSTANCE: %pK (%s)\n", inst, inst->session_type == MSM_VIDC_ENCODER ? "Encoder" : "Decoder"); write_str(&dbg_buf, "===============================\n"); - write_str(&dbg_buf, "core: %p\n", inst->core); + write_str(&dbg_buf, "core: %pK\n", inst->core); write_str(&dbg_buf, "height: %d\n", inst->prop.height[CAPTURE_PORT]); write_str(&dbg_buf, "width: %d\n", inst->prop.width[CAPTURE_PORT]); write_str(&dbg_buf, "fps: %d\n", inst->prop.fps); @@ -348,10 +347,10 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst, struct dentry *dir = NULL; char debugfs_name[MAX_DEBUGFS_NAME]; if (!inst) { - dprintk(VIDC_ERR, "Invalid params, inst: %p\n", inst); + dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst); goto failed_create_dir; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); dir = debugfs_create_dir(debugfs_name, parent); if (!dir) { dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n"); diff --git a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c index 4503e46b044d..cddcb6fb045e 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +++ b/drivers/media/platform/msm/vidc/msm_vidc_res_parse.c @@ -1209,7 +1209,7 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); dprintk(VIDC_DBG, - "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %p, mapping: %p", + "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, mapping: %pK", cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->dev, cb->mapping); @@ -1233,7 +1233,7 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, enum vidc_ports port; if (!domain || !core) { - dprintk(VIDC_ERR, "%s - invalid param %p %p\n", + dprintk(VIDC_ERR, "%s - invalid param %pK %pK\n", __func__, domain, core); return -EINVAL; } @@ -1255,7 +1255,7 @@ int msm_vidc_smmu_fault_handler(struct iommu_domain *domain, !inst->bit_depth ? "8" : "10"); dprintk(VIDC_ERR, - "---Buffer details for inst: %p of type: %d---\n", + "---Buffer details for inst: %pK of type: %d---\n", inst, inst->session_type); mutex_lock(&inst->registeredbufs.lock); dprintk(VIDC_ERR, "registered buffer list:\n"); diff --git a/drivers/media/platform/msm/vidc/venus_boot.c b/drivers/media/platform/msm/vidc/venus_boot.c index 6e881ab10275..925c97a5b6e8 100644 --- a/drivers/media/platform/msm/vidc/venus_boot.c +++ b/drivers/media/platform/msm/vidc/venus_boot.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -161,7 +161,7 @@ static int venus_setup_cb(struct device *dev, return -ENODEV; } dprintk(VIDC_DBG, - "%s Attached device %p and created mapping %p for %s\n", + "%s Attached device %pK and created mapping %pK for %s\n", __func__, dev, venus_data->mapping, dev_name(dev)); return 0; } diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c index 64a4d9717901..62193255b83e 100644 --- a/drivers/media/platform/msm/vidc/venus_hfi.c +++ b/drivers/media/platform/msm/vidc/venus_hfi.c @@ -341,7 +341,7 @@ static int __write_queue(struct vidc_iface_q_info *qinfo, u8 *packet, } if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); __dump_packet(packet); } @@ -547,7 +547,7 @@ static int __read_queue(struct vidc_iface_q_info *qinfo, u8 *packet, *pb_tx_req_is_set = (1 == queue->qhdr_tx_req) ? 1 : 0; if (msm_vidc_debug & VIDC_PKT) { - dprintk(VIDC_PKT, "%s: %p\n", __func__, qinfo); + dprintk(VIDC_PKT, "%s: %pK\n", __func__, qinfo); __dump_packet(packet); } @@ -574,7 +574,7 @@ static int __smem_alloc(struct venus_hfi_device *dev, goto fail_smem_alloc; } - dprintk(VIDC_DBG, "__smem_alloc: ptr = %p, size = %d\n", + dprintk(VIDC_DBG, "__smem_alloc: ptr = %pK, size = %d\n", alloc->kvaddr, size); rc = msm_smem_cache_operations(dev->hal_client, alloc, SMEM_CACHE_CLEAN); @@ -595,7 +595,7 @@ fail_smem_alloc: static void __smem_free(struct venus_hfi_device *dev, struct msm_smem *mem) { if (!dev || !mem) { - dprintk(VIDC_ERR, "invalid param %p %p\n", dev, mem); + dprintk(VIDC_ERR, "invalid param %pK %pK\n", dev, mem); return; } @@ -608,7 +608,7 @@ static void __write_register(struct venus_hfi_device *device, u32 hwiosymaddr = reg; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } @@ -622,7 +622,7 @@ static void __write_register(struct venus_hfi_device *device, } base_addr = device->hal_data->register_base; - dprintk(VIDC_DBG, "Base addr: %p, written to: %#x, Value: %#x...\n", + dprintk(VIDC_DBG, "Base addr: %pK, written to: %#x, Value: %#x...\n", base_addr, hwiosymaddr, value); base_addr += hwiosymaddr; writel_relaxed(value, base_addr); @@ -634,7 +634,7 @@ static int __read_register(struct venus_hfi_device *device, u32 reg) int rc = 0; u8 *base_addr; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -651,7 +651,7 @@ static int __read_register(struct venus_hfi_device *device, u32 reg) rc = readl_relaxed(base_addr + reg); rmb(); - dprintk(VIDC_DBG, "Base addr: %p, read from: %#x, value: %#x...\n", + dprintk(VIDC_DBG, "Base addr: %pK, read from: %#x, value: %#x...\n", base_addr, reg, rc); return rc; @@ -699,7 +699,7 @@ static void __iommu_detach(struct venus_hfi_device *device) struct context_bank_info *cb; if (!device || !device->res) { - dprintk(VIDC_ERR, "Invalid paramter: %p\n", device); + dprintk(VIDC_ERR, "Invalid parameter: %pK\n", device); return; } @@ -1024,7 +1024,7 @@ static int __set_imem(struct venus_hfi_device *device, struct imem *imem) int rc = 0; if (!device || !device->res || !imem) { - dprintk(VIDC_ERR, "Invalid params, core: %p, imem: %p\n", + dprintk(VIDC_ERR, "Invalid params, core: %pK, imem: %pK\n", device, imem); return -EINVAL; } @@ -1263,7 +1263,7 @@ static unsigned long venus_hfi_get_core_clock_rate(void *dev, bool actual_rate) struct clock_info *vc; if (!device) { - dprintk(VIDC_ERR, "%s Invalid args: %p\n", __func__, device); + dprintk(VIDC_ERR, "%s Invalid args: %pK\n", __func__, device); return -EINVAL; } @@ -1328,7 +1328,7 @@ static int __halt_axi(struct venus_hfi_device *device) u32 reg; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid input: %p\n", device); + dprintk(VIDC_ERR, "Invalid input: %pK\n", device); return -EINVAL; } @@ -1526,7 +1526,7 @@ static int venus_hfi_scale_clocks(void *dev, int load, struct venus_hfi_device *device = dev; if (!device) { - dprintk(VIDC_ERR, "Invalid args: %p\n", device); + dprintk(VIDC_ERR, "Invalid args: %pK\n", device); return -EINVAL; } @@ -2173,7 +2173,7 @@ static int venus_hfi_core_init(void *device) goto err_core_init; } - dprintk(VIDC_DBG, "Dev_Virt: %pa, Reg_Virt: %p\n", + dprintk(VIDC_DBG, "Dev_Virt: %pa, Reg_Virt: %pK\n", &dev->hal_data->firmware_base, dev->hal_data->register_base); @@ -2299,12 +2299,12 @@ static void __core_clear_interrupt(struct venus_hfi_device *device) device->intr_status |= intr_status; device->reg_count++; dprintk(VIDC_DBG, - "INTERRUPT for device: %p: times: %d interrupt_status: %d\n", + "INTERRUPT for device: %pK: times: %d interrupt_status: %d\n", device, device->reg_count, intr_status); } else { device->spur_count++; dprintk(VIDC_INFO, - "SPURIOUS_INTR for device: %p: times: %d interrupt_status: %d\n", + "SPURIOUS_INTR for device: %pK: times: %d interrupt_status: %d\n", device, device->spur_count, intr_status); } @@ -2462,7 +2462,7 @@ static void __set_default_sys_properties(struct venus_hfi_device *device) static void __session_clean(struct hal_session *session) { - dprintk(VIDC_DBG, "deleted the session: %p\n", session); + dprintk(VIDC_DBG, "deleted the session: %pK\n", session); list_del(&session->list); /* Poison the session handle with zeros */ *session = (struct hal_session){ {0} }; @@ -3523,7 +3523,7 @@ static int __response_handler(struct venus_hfi_device *device) (u32)(uintptr_t)*session_id); if (!session) { dprintk(VIDC_ERR, - "Received a packet (%#x) for an unrecognized session (%p), discarding\n", + "Received a packet (%#x) for an unrecognized session (%pK), discarding\n", info->response_type, *session_id); --packet_count; @@ -3573,7 +3573,7 @@ static void venus_hfi_core_work_handler(struct work_struct *work) } if (!device->callback) { - dprintk(VIDC_ERR, "No interrupt callback function: %p\n", + dprintk(VIDC_ERR, "No interrupt callback function: %pK\n", device); goto err_no_work; } @@ -3699,7 +3699,7 @@ static inline int __init_clocks(struct venus_hfi_device *device) struct clock_info *cl = NULL; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -3743,7 +3743,7 @@ static inline void __disable_unprepare_clks(struct venus_hfi_device *device) struct clock_info *cl; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return; } @@ -3760,7 +3760,7 @@ static inline int __prepare_enable_clks(struct venus_hfi_device *device) struct clock_info *cl = NULL, *cl_fail = NULL; int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } @@ -4220,7 +4220,7 @@ static inline int __suspend(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } else if (!device->power_enabled) { dprintk(VIDC_DBG, "Power already disabled\n"); @@ -4252,7 +4252,7 @@ static inline int __resume(struct venus_hfi_device *device) int rc = 0; if (!device) { - dprintk(VIDC_ERR, "Invalid params: %p\n", device); + dprintk(VIDC_ERR, "Invalid params: %pK\n", device); return -EINVAL; } else if (device->power_enabled) { dprintk(VIDC_DBG, "Power is already enabled\n"); @@ -4566,7 +4566,7 @@ static struct venus_hfi_device *__get_device(u32 device_id, hfi_cmd_response_callback callback) { if (!res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p\n", res, callback); + dprintk(VIDC_ERR, "Invalid params: %pK %pK\n", res, callback); return NULL; } @@ -4644,7 +4644,7 @@ int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id, int rc = 0; if (!hdev || !res || !callback) { - dprintk(VIDC_ERR, "Invalid params: %p %p %p\n", + dprintk(VIDC_ERR, "Invalid params: %pK %pK %pK\n", hdev, res, callback); rc = -EINVAL; goto err_venus_hfi_init; diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.c b/drivers/media/platform/msm/vidc/vidc_hfi.c index 16acc477479b..2dc892c7526b 100644 --- a/drivers/media/platform/msm/vidc/vidc_hfi.c +++ b/drivers/media/platform/msm/vidc/vidc_hfi.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -55,7 +55,7 @@ void vidc_hfi_deinitialize(enum msm_vidc_hfi_type hfi_type, struct hfi_device *hdev) { if (!hdev) { - dprintk(VIDC_ERR, "%s invalid device %p", __func__, hdev); + dprintk(VIDC_ERR, "%s invalid device %pK", __func__, hdev); return; } diff --git a/drivers/media/platform/msm/vidc/vmem/vmem.c b/drivers/media/platform/msm/vidc/vmem/vmem.c index 3a2ac31c6450..506121ad0688 100644 --- a/drivers/media/platform/msm/vidc/vmem/vmem.c +++ b/drivers/media/platform/msm/vidc/vmem/vmem.c @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -127,7 +126,7 @@ static inline u32 __readl(void * __iomem addr) { u32 value = 0; - pr_debug("read %p ", addr); + pr_debug("read %pK ", addr); value = readl_relaxed(addr); pr_debug("-> %08x\n", value); @@ -136,7 +135,7 @@ static inline u32 __readl(void * __iomem addr) static inline void __writel(u32 val, void * __iomem addr) { - pr_debug("write %08x -> %p\n", val, addr); + pr_debug("write %08x -> %pK\n", val, addr); writel_relaxed(val, addr); /* * Commit all writes via a mem barrier, as subsequent __readl() -- cgit v1.2.3 From f5c96a8c96615490b72357b1c0940196f7dde474 Mon Sep 17 00:00:00 2001 From: Andrew Chant Date: Wed, 14 Sep 2016 14:12:13 -0700 Subject: input: touchscreen: Synaptics: prevent sysfs races Concurrent sysfs calls can cause ugly race conditions. Return EBUSY on concurrent sysfs calls, and prevent sysfs calls during initial fw load. Change-Id: Iec3db7f3fe9d33104319fd3e2bbf1d70ba68221b Bug: 31252388 Signed-off-by: Andrew Chant --- .../synaptics_dsx_fw_update.c | 133 +++++++++++++++------ 1 file changed, 99 insertions(+), 34 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c index 3887f79a97a0..af6f92553aa7 100644 --- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -768,6 +769,8 @@ static struct device_attribute attrs[] = { static struct synaptics_rmi4_fwu_handle *fwu; DECLARE_COMPLETION(fwu_remove_complete); +DEFINE_MUTEX(fwu_sysfs_mutex); + #ifdef HTC_FEATURE static uint32_t syn_crc(uint16_t *data, uint32_t len) { @@ -5087,6 +5090,9 @@ static void fwu_startup_fw_update_work(struct work_struct *work) } #endif + /* Prevent sysfs operations during initial update. */ + mutex_lock(&fwu_sysfs_mutex); + #ifdef HTC_FEATURE wake_lock(&fwu->fwu_wake_lock); if (bdata->update_feature & SYNAPTICS_RMI4_UPDATE_IMAGE) @@ -5101,7 +5107,7 @@ static void fwu_startup_fw_update_work(struct work_struct *work) #else synaptics_fw_updater(NULL); #endif - + mutex_unlock(&fwu_sysfs_mutex); return; } #endif @@ -5113,11 +5119,15 @@ static ssize_t fwu_sysfs_show_image(struct file *data_file, int retval; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + if (count < fwu->config_size) { dev_err(rmi4_data->pdev->dev.parent, "%s: Not enough space (%d bytes) in buffer\n", __func__, (unsigned int)count); - return -EINVAL; + retval = -EINVAL; + goto show_image_exit; } retval = secure_memcpy(buf, count, fwu->read_config_buf, @@ -5126,10 +5136,14 @@ static ssize_t fwu_sysfs_show_image(struct file *data_file, dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to copy config data\n", __func__); - return retval; + goto show_image_exit; } - return fwu->config_size; + retval = fwu->config_size; + +show_image_exit: + mutex_unlock(&fwu_sysfs_mutex); + return retval; } static ssize_t fwu_sysfs_store_image(struct file *data_file, @@ -5139,18 +5153,24 @@ static ssize_t fwu_sysfs_store_image(struct file *data_file, int retval; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + retval = secure_memcpy(&fwu->ext_data_source[fwu->data_pos], fwu->image_size - fwu->data_pos, buf, count, count); if (retval < 0) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to copy image data\n", __func__); - return retval; + goto store_image_exit; } fwu->data_pos += count; + retval = count; - return count; +store_image_exit: + mutex_unlock(&fwu_sysfs_mutex); + return retval; } static ssize_t fwu_sysfs_do_recovery_store(struct device *dev, @@ -5160,9 +5180,12 @@ static ssize_t fwu_sysfs_do_recovery_store(struct device *dev, unsigned int input; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + if (sscanf(buf, "%u", &input) != 1) { retval = -EINVAL; - goto exit; + goto do_recovery_store_exit; } if (!fwu->in_ub_mode) { @@ -5170,11 +5193,13 @@ static ssize_t fwu_sysfs_do_recovery_store(struct device *dev, "%s: Not in microbootloader mode\n", __func__); retval = -EINVAL; - goto exit; + goto do_recovery_store_exit; } - if (!fwu->ext_data_source) - return -EINVAL; + if (!fwu->ext_data_source) { + retval = -EINVAL; + goto do_recovery_store_exit; + } else fwu->image = fwu->ext_data_source; @@ -5183,15 +5208,18 @@ static ssize_t fwu_sysfs_do_recovery_store(struct device *dev, dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to do recovery\n", __func__); - goto exit; + goto free_data_source_recovery_exit; } retval = count; -exit: +free_data_source_recovery_exit: kfree(fwu->ext_data_source); fwu->ext_data_source = NULL; fwu->image = NULL; + +do_recovery_store_exit: + mutex_unlock(&fwu_sysfs_mutex); return retval; } @@ -5201,9 +5229,13 @@ static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, int retval; unsigned int input; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + if (sscanf(buf, "%u", &input) != 1) { retval = -EINVAL; - goto exit; + goto reflash_store_exit; } if (fwu->in_ub_mode) { @@ -5211,7 +5243,7 @@ static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, "%s: In microbootloader mode\n", __func__); retval = -EINVAL; - goto exit; + goto reflash_store_exit; } //if (!fwu->ext_data_source) @@ -5226,7 +5258,7 @@ static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, if ((input != NORMAL) && (input != FORCE)) { retval = -EINVAL; - goto exit; + goto reflash_store_exit; } if (input == FORCE) @@ -5237,12 +5269,12 @@ static ssize_t fwu_sysfs_do_reflash_store(struct device *dev, dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to do reflash\n", __func__); - goto exit; + goto reflash_store_free_exit; } retval = count; -exit: +reflash_store_free_exit: if (fwu->ext_data_source != NULL) { kfree(fwu->ext_data_source); fwu->ext_data_source = NULL; @@ -5250,6 +5282,9 @@ exit: fwu->image = NULL; fwu->force_update = FORCE_UPDATE; fwu->do_lockdown = DO_LOCKDOWN; + +reflash_store_exit: + mutex_unlock(&fwu_sysfs_mutex); return retval; } @@ -5260,14 +5295,17 @@ static ssize_t fwu_sysfs_write_config_store(struct device *dev, unsigned int input; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + if (sscanf(buf, "%u", &input) != 1) { retval = -EINVAL; - goto exit; + goto write_config_store_exit; } if (input != 1) { retval = -EINVAL; - goto exit; + goto write_config_store_exit; } if (fwu->in_ub_mode) { @@ -5275,28 +5313,32 @@ static ssize_t fwu_sysfs_write_config_store(struct device *dev, "%s: In microbootloader mode\n", __func__); retval = -EINVAL; - goto exit; + goto write_config_store_exit; } - if (!fwu->ext_data_source) - return -EINVAL; - else + if (!fwu->ext_data_source) { + retval = -EINVAL; + goto write_config_store_exit; + } else { fwu->image = fwu->ext_data_source; - + } retval = fwu_start_write_config(); if (retval < 0) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to write config\n", __func__); - goto exit; + goto write_config_store_free_exit; } retval = count; -exit: +write_config_store_free_exit: kfree(fwu->ext_data_source); fwu->ext_data_source = NULL; fwu->image = NULL; + +write_config_store_exit: + mutex_unlock(&fwu_sysfs_mutex); return retval; } @@ -5320,7 +5362,11 @@ static ssize_t fwu_sysfs_read_config_store(struct device *dev, return -EINVAL; } + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; retval = fwu_do_read_config(); + mutex_unlock(&fwu_sysfs_mutex); + if (retval < 0) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to read config\n", @@ -5341,7 +5387,10 @@ static ssize_t fwu_sysfs_config_area_store(struct device *dev, if (retval) return retval; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; fwu->config_area = config_area; + mutex_unlock(&fwu_sysfs_mutex); return count; } @@ -5352,8 +5401,12 @@ static ssize_t fwu_sysfs_image_name_store(struct device *dev, int retval; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; retval = secure_memcpy(fwu->image_name, MAX_IMAGE_NAME_LEN, buf, count, count); + mutex_unlock(&fwu_sysfs_mutex); + if (retval < 0) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to copy image file name\n", @@ -5375,6 +5428,9 @@ static ssize_t fwu_sysfs_image_size_store(struct device *dev, if (retval) return retval; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + fwu->image_size = size; fwu->data_pos = 0; @@ -5382,6 +5438,8 @@ static ssize_t fwu_sysfs_image_size_store(struct device *dev, kfree(fwu->ext_data_source); } fwu->ext_data_source = kzalloc(fwu->image_size, GFP_KERNEL); + mutex_unlock(&fwu_sysfs_mutex); + if (!fwu->ext_data_source) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to alloc mem for image data\n", @@ -5441,14 +5499,17 @@ static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev, unsigned int input; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + if (!mutex_trylock(&fwu_sysfs_mutex)) + return -EBUSY; + if (sscanf(buf, "%u", &input) != 1) { retval = -EINVAL; - goto exit; + goto write_guest_code_store_exit; } if (input != 1) { retval = -EINVAL; - goto exit; + goto write_guest_code_store_exit; } if (fwu->in_ub_mode) { @@ -5456,28 +5517,32 @@ static ssize_t fwu_sysfs_write_guest_code_store(struct device *dev, "%s: In microbootloader mode\n", __func__); retval = -EINVAL; - goto exit; + goto write_guest_code_store_exit; } - if (!fwu->ext_data_source) - return -EINVAL; - else + if (!fwu->ext_data_source) { + retval = -EINVAL; + goto write_guest_code_store_exit; + } else { fwu->image = fwu->ext_data_source; + } retval = fwu_start_write_guest_code(); if (retval < 0) { dev_err(rmi4_data->pdev->dev.parent, "%s: Failed to write guest code\n", __func__); - goto exit; + goto write_guest_code_store_free_exit; } retval = count; -exit: +write_guest_code_store_free_exit: kfree(fwu->ext_data_source); fwu->ext_data_source = NULL; fwu->image = NULL; +write_guest_code_store_exit: + mutex_unlock(&fwu_sysfs_mutex); return retval; } -- cgit v1.2.3 From 3c865718ebf0543a9e19331dceba7c1a2ee6782e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 14 Apr 2016 17:01:17 +0200 Subject: BACKPORT: usb: gadget: f_fs: Fix use-after-free (cherry picked from commit 38740a5b87d53ceb89eb2c970150f6e94e00373a) When using asynchronous read or write operations on the USB endpoints the issuer of the IO request is notified by calling the ki_complete() callback of the submitted kiocb when the URB has been completed. Calling this ki_complete() callback will free kiocb. Make sure that the structure is no longer accessed beyond that point, otherwise undefined behaviour might occur. Fixes: 2e4c7553cd6f ("usb: gadget: f_fs: add aio support") Cc: # v3.15+ Signed-off-by: Lars-Peter Clausen Signed-off-by: Felipe Balbi Change-Id: I3c7b643f6440c4fb6160a57c1058523030b46a6c Bug: 30950866 --- drivers/usb/gadget/function/f_fs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index e389c27d8e20..599a4273d29d 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -689,7 +689,6 @@ static void ffs_user_copy_worker(struct work_struct *work) usb_ep_free_request(io_data->ep, io_data->req); - io_data->kiocb->private = NULL; if (io_data->read) kfree(io_data->iovec); kfree(io_data->buf); -- cgit v1.2.3 From 594c8b47bbd4308502a4b99783b70376eecaea86 Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Tue, 23 Aug 2016 14:41:47 -0700 Subject: msm: camera: cpp: Add validation for v4l2 ioctl arguments In CPP v4l2 ioctl command is made, if _IOC_DIR(cmd) is _IOC_NONE, then the user-supplied argument arg is not checked and an information disclosure is possible Bug: 29464815 CRs-Fixed: 1042068 Change-Id: Iddb291b10cdcb5c42ab8497e06c2ce47885cd5ab Signed-off-by: Sunid Wilson Signed-off-by: Biswajit Paul Signed-off-by: Siqi Lin --- drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index fe12ef5bddca..964b43fb1e51 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -2676,14 +2676,14 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg, break; default: { if (ioctl_ptr == NULL) { - pr_err("Wrong ioctl_ptr %pK\n", ioctl_ptr); + pr_err("Wrong ioctl_ptr for cmd %u\n", cmd); return -EINVAL; } *ioctl_ptr = arg; if ((*ioctl_ptr == NULL) || - ((*ioctl_ptr)->ioctl_ptr == NULL)) { - pr_err("Wrong arg %pK\n", arg); + (*ioctl_ptr)->ioctl_ptr == NULL) { + pr_err("Error invalid ioctl argument cmd %u", cmd); return -EINVAL; } break; @@ -2708,6 +2708,12 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, pr_err("cpp_dev is null\n"); return -EINVAL; } + + if (_IOC_DIR(cmd) == _IOC_NONE) { + pr_err("Invalid ioctl/subdev cmd %u", cmd); + return -EINVAL; + } + rc = msm_cpp_validate_input(cmd, arg, &ioctl_ptr); if (rc != 0) { pr_err("input validation failed\n"); -- cgit v1.2.3 From e0bb388e6482492726a6d79ab67cc2e90dba1803 Mon Sep 17 00:00:00 2001 From: Harshdeep Dhatt Date: Wed, 7 Oct 2015 16:10:36 -0600 Subject: msm: kgsl: Clear the interrupt immediately Sometimes an interrupt from GPU is ignored while we are still executing the previous interrupt. In order to service any interrupt that was fired while executing the interrupt handler, clear the interrupt register immediately. Also, clear the A5XX_INT_RBBM_AHB_ERROR bit not before but after it's serviced in its respective handler. This will avoid firing the main interrupt handler a second time. Change-Id: Ie6b5a511f5b3077adae7d464de437f2aa893b0c9 Signed-off-by: Harshdeep Dhatt (cherry picked from commit fb8021cee910b1eb5f0172d9a63c6a93921358bd) --- drivers/gpu/msm/adreno.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 471b62d420fb..886043c91147 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -593,6 +593,15 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); + /* + * Clear all the interrupt bits but A5XX_INT_RBBM_AHB_ERROR. Because + * even if we clear it here, it will stay high until it is cleared + * in its respective handler. Otherwise, the interrupt handler will + * fire again. + */ + adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, + status & ~BIT(A5XX_INT_RBBM_AHB_ERROR)); + /* Loop through all set interrupts and call respective handlers */ for (tmp = status; tmp != 0;) { i = fls(tmp) - 1; @@ -611,9 +620,14 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) gpudev->irq_trace(adreno_dev, status); - if (status) + /* + * Clear A5XX_INT_RBBM_AHB_ERROR bit after this interrupt has been + * cleared in its respective handler + */ + if (status & BIT(A5XX_INT_RBBM_AHB_ERROR)) adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - status); + BIT(A5XX_INT_RBBM_AHB_ERROR)); + return ret; } -- cgit v1.2.3 From 9236e1d0b9c407aa02fcbbac10267690f66ad56a Mon Sep 17 00:00:00 2001 From: Pat Tjin Date: Wed, 12 Oct 2016 22:03:27 +0000 Subject: Revert "msm: kgsl: Clear the interrupt immediately" This reverts commit e0bb388e6482492726a6d79ab67cc2e90dba1803. Change-Id: I3f55515abd8a0a6c78e84893e56877ec0a1253aa --- drivers/gpu/msm/adreno.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 886043c91147..471b62d420fb 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -593,15 +593,6 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); - /* - * Clear all the interrupt bits but A5XX_INT_RBBM_AHB_ERROR. Because - * even if we clear it here, it will stay high until it is cleared - * in its respective handler. Otherwise, the interrupt handler will - * fire again. - */ - adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - status & ~BIT(A5XX_INT_RBBM_AHB_ERROR)); - /* Loop through all set interrupts and call respective handlers */ for (tmp = status; tmp != 0;) { i = fls(tmp) - 1; @@ -620,14 +611,9 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) gpudev->irq_trace(adreno_dev, status); - /* - * Clear A5XX_INT_RBBM_AHB_ERROR bit after this interrupt has been - * cleared in its respective handler - */ - if (status & BIT(A5XX_INT_RBBM_AHB_ERROR)) + if (status) adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - BIT(A5XX_INT_RBBM_AHB_ERROR)); - + status); return ret; } -- cgit v1.2.3 From a0ce33daf6946ce83de783e09066d0d5a879dabd Mon Sep 17 00:00:00 2001 From: Pat Tjin Date: Wed, 12 Oct 2016 22:12:51 +0000 Subject: Revert "Revert "msm: kgsl: Clear the interrupt immediately"" This reverts commit 9236e1d0b9c407aa02fcbbac10267690f66ad56a. Change-Id: Ifd7609c8077832850ad94e59d959f9411e2440c9 --- drivers/gpu/msm/adreno.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 471b62d420fb..886043c91147 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -593,6 +593,15 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); + /* + * Clear all the interrupt bits but A5XX_INT_RBBM_AHB_ERROR. Because + * even if we clear it here, it will stay high until it is cleared + * in its respective handler. Otherwise, the interrupt handler will + * fire again. + */ + adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, + status & ~BIT(A5XX_INT_RBBM_AHB_ERROR)); + /* Loop through all set interrupts and call respective handlers */ for (tmp = status; tmp != 0;) { i = fls(tmp) - 1; @@ -611,9 +620,14 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) gpudev->irq_trace(adreno_dev, status); - if (status) + /* + * Clear A5XX_INT_RBBM_AHB_ERROR bit after this interrupt has been + * cleared in its respective handler + */ + if (status & BIT(A5XX_INT_RBBM_AHB_ERROR)) adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - status); + BIT(A5XX_INT_RBBM_AHB_ERROR)); + return ret; } -- cgit v1.2.3 From 23f8e8ca93a2a26ae28b030f11dc493b7f92a964 Mon Sep 17 00:00:00 2001 From: Siqi Lin Date: Tue, 11 Oct 2016 11:50:01 -0700 Subject: msm: camera: Avoid exposing kernel addresses Usage of %p exposes the kernel addresses, an easy target to kernel write vulnerabilities. With this patch currently %pK prints only Zeros as address. If you need actual address echo 0 > /proc/sys/kernel/kptr_restrict CRs-Fixed: 987011 Change-Id: I6c79f82376936fc646b723872a96a6694fe47cd9 Signed-off-by: Azam Sadiq Pasha Kapatrala Syed Signed-off-by: Siqi Lin Bug: 29464815 --- drivers/media/platform/msm/camera_v2/isp/msm_isp40.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index 5aa72e251220..5b419ecfcbfd 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -1034,7 +1034,7 @@ static int msm_vfe40_start_fetch_engine(struct vfe_device *vfe_dev, rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { - pr_err("%s: No fetch buffer rc= %d buf= %p\n", + pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } -- cgit v1.2.3 From 3892a11f14ef25d956d007fbd0c27241332693d9 Mon Sep 17 00:00:00 2001 From: Mark Rutland Date: Thu, 8 Jan 2015 11:42:59 +0000 Subject: UPSTREAM: arm64: make sys_call_table const As with x86, mark the sys_call_table const such that it will be placed in the .rodata section. This will cause attempts to modify the table (accidental or deliberate) to fail when strict page permissions are in place. In the absence of strict page permissions, there should be no functional change. Signed-off-by: Mark Rutland Acked-by: Will Deacon Signed-off-by: Catalin Marinas Bug: 31660652 Signed-off-by: Jeff Vander Stoep (cherry picked from commit c623b33b4e9599c6ac5076f7db7369eb9869aa04) Change-Id: I8c5aa13b8adfdb71e3c574a59e5bf63f8cee42c5 --- arch/arm64/kernel/sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c index 3fa98ff14f0e..df20b7918854 100644 --- a/arch/arm64/kernel/sys.c +++ b/arch/arm64/kernel/sys.c @@ -50,7 +50,7 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len, * The sys_call_table array must be 4K aligned to be accessible from * kernel/entry.S. */ -void *sys_call_table[__NR_syscalls] __aligned(4096) = { +void * const sys_call_table[__NR_syscalls] __aligned(4096) = { [0 ... __NR_syscalls - 1] = sys_ni_syscall, #include }; -- cgit v1.2.3 From 5442a0c99c8a33d22363f40543cbca68b4c8e113 Mon Sep 17 00:00:00 2001 From: Siqi Lin Date: Thu, 13 Oct 2016 16:27:46 -0700 Subject: net: ping: Fix stack buffer overflow in ping_common_sendmsg() In ping_common_sendmsg(), when len < icmph_len, memcpy_fromiovec() will access invalid memory because msg->msg_iov only has 1 element and memcpy_fromiovec() attempts to increment it. KASAN report: BUG: KASAN: stack-out-of-bounds in memcpy_fromiovec+0x60/0x114 at addr ffffffc071077da0 Read of size 8 by task trinity-c2/9623 page:ffffffbe034b9a08 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x0() page dumped because: kasan: bad access detected CPU: 0 PID: 9623 Comm: trinity-c2 Tainted: G BU 3.18.0-dirty #15 Hardware name: Google Tegra210 Smaug Rev 1,3+ (DT) Call trace: [] dump_backtrace+0x0/0x1ac arch/arm64/kernel/traps.c:90 [] show_stack+0x10/0x1c arch/arm64/kernel/traps.c:171 [< inline >] __dump_stack lib/dump_stack.c:15 [] dump_stack+0x7c/0xd0 lib/dump_stack.c:50 [< inline >] print_address_description mm/kasan/report.c:147 [< inline >] kasan_report_error mm/kasan/report.c:236 [] kasan_report+0x380/0x4b8 mm/kasan/report.c:259 [< inline >] check_memory_region mm/kasan/kasan.c:264 [] __asan_load8+0x20/0x70 mm/kasan/kasan.c:507 [] memcpy_fromiovec+0x5c/0x114 lib/iovec.c:15 [< inline >] memcpy_from_msg include/linux/skbuff.h:2667 [] ping_common_sendmsg+0x50/0x108 net/ipv4/ping.c:674 [] ping_v4_sendmsg+0xd8/0x698 net/ipv4/ping.c:714 [] inet_sendmsg+0xe0/0x12c net/ipv4/af_inet.c:749 [< inline >] __sock_sendmsg_nosec net/socket.c:624 [< inline >] __sock_sendmsg net/socket.c:632 [] sock_sendmsg+0x124/0x164 net/socket.c:643 [< inline >] SYSC_sendto net/socket.c:1797 [] SyS_sendto+0x178/0x1d8 net/socket.c:1761 Memory state around the buggy address: ffffffc071077c80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 f1 f1 ffffffc071077d00: f1 f1 04 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 >ffffffc071077d80: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 ^ ffffffc071077e00: 00 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 ffffffc071077e80: 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 Bug: 31349935 Change-Id: Ib7385fc26dfe7e07e9bab42a10ff65a37cbaab54 Signed-off-by: Siqi Lin --- net/ipv4/ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 59f8d47bffe4..f65379c4d86d 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -656,7 +656,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, void *user_icmph, size_t icmph_len) { u8 type, code; - if (len > 0xFFFF) + if (len > 0xFFFF || len < icmph_len) return -EMSGSIZE; /* -- cgit v1.2.3 From 1a7952a39e3923d172dd2c119a943f97773dd301 Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Wed, 14 Sep 2016 07:03:44 -0700 Subject: msm: sensor: validate the i2c table index before use Verifying the i2c table index value before accessing the i2c table to avoid memory corruption issues. Bug: 30740545 CRs-Fixed: 1065916 Change-Id: I0e31c22f90006f27a77cd420288334b8355cee95 Signed-off-by: Sureshnaidu Laveti Signed-off-by: Biswajit Paul --- .../platform/msm/camera_v2/sensor/actuator/msm_actuator.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index 0b3e4e1fcf04..bf3973888573 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -101,11 +101,6 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_tbl = a_ctrl->i2c_reg_tbl; for (i = 0; i < size; i++) { - /* check that the index into i2c_tbl cannot grow larger that - the allocated size of i2c_tbl */ - if ((a_ctrl->total_steps + 1) < (a_ctrl->i2c_tbl_index)) - break; - if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) { value = (next_lens_position << write_arr[i].data_shift) | @@ -119,6 +114,11 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte2 = value & 0xFF; CDBG("byte1:0x%x, byte2:0x%x\n", i2c_byte1, i2c_byte2); + if (a_ctrl->i2c_tbl_index > + a_ctrl->total_steps) { + pr_err("failed:i2c table index out of bound\n"); + break; + } i2c_tbl[a_ctrl->i2c_tbl_index]. reg_addr = i2c_byte1; i2c_tbl[a_ctrl->i2c_tbl_index]. @@ -139,6 +139,10 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, i2c_byte2 = (hw_dword & write_arr[i].hw_mask) >> write_arr[i].hw_shift; } + if (a_ctrl->i2c_tbl_index > a_ctrl->total_steps) { + pr_err("failed: i2c table index out of bound\n"); + break; + } CDBG("i2c_byte1:0x%x, i2c_byte2:0x%x\n", i2c_byte1, i2c_byte2); i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1; i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2; -- cgit v1.2.3 From 2777a837f89486aa4bc1fa2fc6e612c6627b5c94 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 25 May 2016 11:48:25 -0400 Subject: UPSTREAM: percpu: fix synchronization between synchronous map extension and chunk destruction (cherry picked from commit 6710e594f71ccaad8101bc64321152af7cd9ea28) For non-atomic allocations, pcpu_alloc() can try to extend the area map synchronously after dropping pcpu_lock; however, the extension wasn't synchronized against chunk destruction and the chunk might get freed while extension is in progress. This patch fixes the bug by putting most of non-atomic allocations under pcpu_alloc_mutex to synchronize against pcpu_balance_work which is responsible for async chunk management including destruction. Signed-off-by: Tejun Heo Reported-and-tested-by: Alexei Starovoitov Reported-by: Vlastimil Babka Reported-by: Sasha Levin Cc: stable@vger.kernel.org # v3.18+ Fixes: 1a4d76076cda ("percpu: implement asynchronous chunk population") Change-Id: I8800962e658e78eac866fff4a4e00294c58a3dec Bug: 31596597 --- mm/percpu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 88bb6c92d83a..ae2288fe8838 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -160,7 +160,7 @@ static struct pcpu_chunk *pcpu_reserved_chunk; static int pcpu_reserved_chunk_limit; static DEFINE_SPINLOCK(pcpu_lock); /* all internal data structures */ -static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop */ +static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext */ static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */ @@ -437,6 +437,8 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc) size_t old_size = 0, new_size = new_alloc * sizeof(new[0]); unsigned long flags; + lockdep_assert_held(&pcpu_alloc_mutex); + new = pcpu_mem_zalloc(new_size); if (!new) return -ENOMEM; @@ -897,6 +899,9 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, return NULL; } + if (!is_atomic) + mutex_lock(&pcpu_alloc_mutex); + spin_lock_irqsave(&pcpu_lock, flags); /* serve reserved allocations from the reserved chunk if available */ @@ -969,12 +974,9 @@ restart: if (is_atomic) goto fail; - mutex_lock(&pcpu_alloc_mutex); - if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) { chunk = pcpu_create_chunk(); if (!chunk) { - mutex_unlock(&pcpu_alloc_mutex); err = "failed to allocate new chunk"; goto fail; } @@ -985,7 +987,6 @@ restart: spin_lock_irqsave(&pcpu_lock, flags); } - mutex_unlock(&pcpu_alloc_mutex); goto restart; area_found: @@ -995,8 +996,6 @@ area_found: if (!is_atomic) { int page_start, page_end, rs, re; - mutex_lock(&pcpu_alloc_mutex); - page_start = PFN_DOWN(off); page_end = PFN_UP(off + size); @@ -1007,7 +1006,6 @@ area_found: spin_lock_irqsave(&pcpu_lock, flags); if (ret) { - mutex_unlock(&pcpu_alloc_mutex); pcpu_free_area(chunk, off, &occ_pages); err = "failed to populate"; goto fail_unlock; @@ -1047,6 +1045,8 @@ fail: /* see the flag handling in pcpu_blance_workfn() */ pcpu_atomic_alloc_failed = true; pcpu_schedule_balance_work(); + } else { + mutex_unlock(&pcpu_alloc_mutex); } return NULL; } -- cgit v1.2.3 From b99cd46839a8c2bfffa09c5d8cb425d5a2cfc047 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 25 May 2016 11:48:25 -0400 Subject: UPSTREAM: percpu: fix synchronization between chunk->map_extend_work and chunk destruction (cherry picked from commit 4f996e234dad488e5d9ba0858bc1bae12eff82c3) Atomic allocations can trigger async map extensions which is serviced by chunk->map_extend_work. pcpu_balance_work which is responsible for destroying idle chunks wasn't synchronizing properly against chunk->map_extend_work and may end up freeing the chunk while the work item is still in flight. This patch fixes the bug by rolling async map extension operations into pcpu_balance_work. Signed-off-by: Tejun Heo Reported-and-tested-by: Alexei Starovoitov Reported-by: Vlastimil Babka Reported-by: Sasha Levin Cc: stable@vger.kernel.org # v3.18+ Fixes: 9c824b6a172c ("percpu: make sure chunk->map array has available space") Change-Id: I8f4aaf7fe0bc0e9f353d41e0a7840c40d6a32117 Bug: 31596597 --- mm/percpu.c | 57 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index ae2288fe8838..5ae6e0284967 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -110,7 +110,7 @@ struct pcpu_chunk { int map_used; /* # of map entries used before the sentry */ int map_alloc; /* # of map entries allocated */ int *map; /* allocation map */ - struct work_struct map_extend_work;/* async ->map[] extension */ + struct list_head map_extend_list;/* on pcpu_map_extend_chunks */ void *data; /* chunk data */ int first_free; /* no free below this */ @@ -164,6 +164,9 @@ static DEFINE_MUTEX(pcpu_alloc_mutex); /* chunk create/destroy, [de]pop, map ext static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */ +/* chunks which need their map areas extended, protected by pcpu_lock */ +static LIST_HEAD(pcpu_map_extend_chunks); + /* * The number of empty populated pages, protected by pcpu_lock. The * reserved chunk doesn't contribute to the count. @@ -397,13 +400,19 @@ static int pcpu_need_to_extend(struct pcpu_chunk *chunk, bool is_atomic) { int margin, new_alloc; + lockdep_assert_held(&pcpu_lock); + if (is_atomic) { margin = 3; if (chunk->map_alloc < - chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW && - pcpu_async_enabled) - schedule_work(&chunk->map_extend_work); + chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW) { + if (list_empty(&chunk->map_extend_list)) { + list_add_tail(&chunk->map_extend_list, + &pcpu_map_extend_chunks); + pcpu_schedule_balance_work(); + } + } } else { margin = PCPU_ATOMIC_MAP_MARGIN_HIGH; } @@ -471,20 +480,6 @@ out_unlock: return 0; } -static void pcpu_map_extend_workfn(struct work_struct *work) -{ - struct pcpu_chunk *chunk = container_of(work, struct pcpu_chunk, - map_extend_work); - int new_alloc; - - spin_lock_irq(&pcpu_lock); - new_alloc = pcpu_need_to_extend(chunk, false); - spin_unlock_irq(&pcpu_lock); - - if (new_alloc) - pcpu_extend_area_map(chunk, new_alloc); -} - /** * pcpu_fit_in_area - try to fit the requested allocation in a candidate area * @chunk: chunk the candidate area belongs to @@ -744,7 +739,7 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void) chunk->map_used = 1; INIT_LIST_HEAD(&chunk->list); - INIT_WORK(&chunk->map_extend_work, pcpu_map_extend_workfn); + INIT_LIST_HEAD(&chunk->map_extend_list); chunk->free_size = pcpu_unit_size; chunk->contig_hint = pcpu_unit_size; @@ -1131,6 +1126,7 @@ static void pcpu_balance_workfn(struct work_struct *work) if (chunk == list_first_entry(free_head, struct pcpu_chunk, list)) continue; + list_del_init(&chunk->map_extend_list); list_move(&chunk->list, &to_free); } @@ -1148,6 +1144,25 @@ static void pcpu_balance_workfn(struct work_struct *work) pcpu_destroy_chunk(chunk); } + /* service chunks which requested async area map extension */ + do { + int new_alloc = 0; + + spin_lock_irq(&pcpu_lock); + + chunk = list_first_entry_or_null(&pcpu_map_extend_chunks, + struct pcpu_chunk, map_extend_list); + if (chunk) { + list_del_init(&chunk->map_extend_list); + new_alloc = pcpu_need_to_extend(chunk, false); + } + + spin_unlock_irq(&pcpu_lock); + + if (new_alloc) + pcpu_extend_area_map(chunk, new_alloc); + } while (chunk); + /* * Ensure there are certain number of free populated pages for * atomic allocs. Fill up from the most packed so that atomic @@ -1648,7 +1663,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, */ schunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); INIT_LIST_HEAD(&schunk->list); - INIT_WORK(&schunk->map_extend_work, pcpu_map_extend_workfn); + INIT_LIST_HEAD(&schunk->map_extend_list); schunk->base_addr = base_addr; schunk->map = smap; schunk->map_alloc = ARRAY_SIZE(smap); @@ -1678,7 +1693,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, if (dyn_size) { dchunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0); INIT_LIST_HEAD(&dchunk->list); - INIT_WORK(&dchunk->map_extend_work, pcpu_map_extend_workfn); + INIT_LIST_HEAD(&dchunk->map_extend_list); dchunk->base_addr = base_addr; dchunk->map = dmap; dchunk->map_alloc = ARRAY_SIZE(dmap); -- cgit v1.2.3 From 51b5da896f29c4ae2deb47a4913dd4430f599999 Mon Sep 17 00:00:00 2001 From: Steve Pfetsch Date: Fri, 14 Oct 2016 15:36:59 -0700 Subject: drivers: video: Add bounds checking in fb_cmap_to_user Verify that unsigned int value will not become negative before cast to signed int. Bug: 31651010 Change-Id: I548a200f678762042617f11100b6966a405a3920 --- drivers/video/fbdev/core/fbcmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c index 6bf80e43cac5..98a919de1601 100644 --- a/drivers/video/fbdev/core/fbcmap.c +++ b/drivers/video/fbdev/core/fbcmap.c @@ -190,6 +190,9 @@ int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to) int tooff = 0, fromoff = 0; int size; + if ((int)(to->start) < 0) + return -EINVAL; + if (to->start > from->start) fromoff = to->start - from->start; else -- cgit v1.2.3 From a4c7c43865713e830eb0ca490d5f6e6a3887b11b Mon Sep 17 00:00:00 2001 From: Min Chong Date: Fri, 14 Oct 2016 13:40:31 -0700 Subject: usb: gadget: f_mbim: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which also evaluates whether kptr_restrict is set. Bug: 31802656 Change-Id: I74e83192e0379586469edba3c7579a1cd75cf3c0 Signed-off-by: Min Chong --- drivers/usb/gadget/function/f_mbim.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/function/f_mbim.c b/drivers/usb/gadget/function/f_mbim.c index 017a2a9cb6ea..717ee2342639 100644 --- a/drivers/usb/gadget/function/f_mbim.c +++ b/drivers/usb/gadget/function/f_mbim.c @@ -741,7 +741,7 @@ static void mbim_notify_complete(struct usb_ep *ep, struct usb_request *req) struct f_mbim *mbim = req->context; struct usb_cdc_notification *event = req->buf; - pr_debug("dev:%p\n", mbim); + pr_debug("dev:%pK\n", mbim); spin_lock(&mbim->lock); switch (req->status) { @@ -771,7 +771,7 @@ static void mbim_notify_complete(struct usb_ep *ep, struct usb_request *req) mbim_do_notify(mbim); spin_unlock(&mbim->lock); - pr_debug("dev:%p Exit\n", mbim); + pr_debug("dev:%pK Exit\n", mbim); } static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req) @@ -782,7 +782,7 @@ static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req) struct f_mbim *mbim = func_to_mbim(f); struct mbim_ntb_input_size *ntb = NULL; - pr_debug("dev:%p\n", mbim); + pr_debug("dev:%pK\n", mbim); req->context = NULL; if (req->status || req->actual != req->length) { @@ -820,7 +820,7 @@ static void mbim_ep0out_complete(struct usb_ep *ep, struct usb_request *req) invalid: usb_ep_set_halt(ep); - pr_err("dev:%p Failed\n", mbim); + pr_err("dev:%pK Failed\n", mbim); return; } @@ -855,7 +855,7 @@ fmbim_cmd_complete(struct usb_ep *ep, struct usb_request *req) if (!first_command_sent) first_command_sent = true; - pr_debug("dev:%p port#%d\n", dev, dev->port_num); + pr_debug("dev:%pK port#%d\n", dev, dev->port_num); cpkt = mbim_alloc_ctrl_pkt(len, GFP_ATOMIC); if (!cpkt) { @@ -1195,7 +1195,7 @@ static int mbim_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return ret; } - pr_info("Set mbim port in_desc = 0x%p\n", + pr_info("Set mbim port in_desc = 0x%pK\n", mbim->bam_port.in->desc); ret = config_ep_by_speed(cdev->gadget, f, @@ -1207,7 +1207,7 @@ static int mbim_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return ret; } - pr_info("Set mbim port out_desc = 0x%p\n", + pr_info("Set mbim port out_desc = 0x%pK\n", mbim->bam_port.out->desc); pr_debug("Activate mbim\n"); @@ -1832,7 +1832,7 @@ mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos) pr_debug("Enter(%zu)\n", count); if (!dev || !req || !req->buf) { - pr_err("%s: dev %p req %p req->buf %p\n", + pr_err("%s: dev %pK req %pK req->buf %pK\n", __func__, dev, req, req ? req->buf : req); return -ENODEV; } @@ -1854,7 +1854,7 @@ mbim_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos) } if (dev->not_port.notify_state != MBIM_NOTIFY_RESPONSE_AVAILABLE) { - pr_err("dev:%p state=%d error\n", dev, + pr_err("dev:%pK state=%d error\n", dev, dev->not_port.notify_state); mbim_unlock(&dev->write_excl); return -EINVAL; -- cgit v1.2.3 From f1ca98fe8121832658a0f58fbd73cdfd8e057a70 Mon Sep 17 00:00:00 2001 From: Min Chong Date: Thu, 13 Oct 2016 17:18:40 -0700 Subject: netfilter: Change %p to %pK in debug messages The format specifier %p can leak kernel addresses while not valuing the kptr_restrict system settings. Use %pK instead of %p, which also evaluates whether kptr_restrict is set. Bug: 31796940 Change-Id: Ia2946d6b493126d68281f97778faf578247f088e Signed-off-by: Min Chong --- net/netfilter/nf_conntrack_core.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 63745440403b..e8c0cb51bd43 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -235,7 +235,7 @@ EXPORT_SYMBOL_GPL(nf_ct_invert_tuple); static void clean_from_lists(struct nf_conn *ct) { - pr_debug("clean_from_lists(%p)\n", ct); + pr_debug("clean_from_lists(%pK)\n", ct); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode); hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode); @@ -301,7 +301,7 @@ destroy_conntrack(struct nf_conntrack *nfct) struct list_head *sip_node_save_list; void (*delete_entry)(struct nf_conn *ct); - pr_debug("destroy_conntrack(%p)\n", ct); + pr_debug("destroy_conntrack(%pK)\n", ct); NF_CT_ASSERT(atomic_read(&nfct->use) == 0); NF_CT_ASSERT(!timer_pending(&ct->timeout)); @@ -346,7 +346,7 @@ destroy_conntrack(struct nf_conntrack *nfct) if (ct->master) nf_ct_put(ct->master); - pr_debug("destroy_conntrack: returning ct=%p to slab\n", ct); + pr_debug("destroy_conntrack: returning ct=%pK to slab\n", ct); nf_conntrack_free(ct); } @@ -635,7 +635,7 @@ __nf_conntrack_confirm(struct sk_buff *skb) * confirmed us. */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); - pr_debug("Confirming conntrack %p\n", ct); + pr_debug("Confirming conntrack %pK\n", ct); /* We have to check the DYING flag after unlink to prevent * a race against nf_ct_get_next_corpse() possibly called from * user context, else we insert an already 'dead' hash, blocking @@ -981,7 +981,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, spin_lock(&nf_conntrack_expect_lock); exp = nf_ct_find_expectation(net, zone, tuple); if (exp) { - pr_debug("conntrack: expectation arrives ct=%p exp=%p\n", + pr_debug("conntrack: expectation arrives ct=%pK exp=%pK\n", ct, exp); /* Welcome, Mr. Bond. We've been expecting you... */ __set_bit(IPS_EXPECTED_BIT, &ct->status); @@ -1074,14 +1074,14 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, } else { /* Once we've had two way comms, always ESTABLISHED. */ if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { - pr_debug("nf_conntrack_in: normal packet for %p\n", ct); + pr_debug("nf_conntrack_in: normal packet for %pK\n", ct); *ctinfo = IP_CT_ESTABLISHED; } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) { - pr_debug("nf_conntrack_in: related packet for %p\n", + pr_debug("nf_conntrack_in: related packet for %pK\n", ct); *ctinfo = IP_CT_RELATED; } else { - pr_debug("nf_conntrack_in: new packet for %p\n", ct); + pr_debug("nf_conntrack_in: new packet for %pK\n", ct); *ctinfo = IP_CT_NEW; } *set_reply = 0; @@ -1223,7 +1223,7 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, /* Should be unconfirmed, so not in hash table yet */ NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); - pr_debug("Altering reply tuple of %p to ", ct); + pr_debug("Altering reply tuple of %pK to ", ct); nf_ct_dump_tuple(newreply); ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply; @@ -1800,7 +1800,7 @@ int nf_conntrack_init_net(struct net *net) if (!net->ct.stat) goto err_pcpu_lists; - net->ct.slabname = kasprintf(GFP_KERNEL, "nf_conntrack_%p", net); + net->ct.slabname = kasprintf(GFP_KERNEL, "nf_conntrack_%pK", net); if (!net->ct.slabname) goto err_slabname; -- cgit v1.2.3 From 8a950b2d64cec7b8022b7572c2d3d9221b2dbab2 Mon Sep 17 00:00:00 2001 From: Min Chong Date: Thu, 13 Oct 2016 09:53:23 -0700 Subject: input: synaptics_dsx: add bounds checks for firmware id A series of characters between '0' and '9' with a length more than MAX_FIRMWARE_ID_LEN causes a heap buffer overflow. This is mitigated by performing a bounds check. Bug: 31911920 Signed-off-by: Mark Salyzyn Signed-off-by: Min Chong Change-Id: Iaefe92df2610153f2d3e2caa58322ae82cb5b7c2 --- .../synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c index af6f92553aa7..05f13b427739 100644 --- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c @@ -30,7 +30,7 @@ * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. * DOLLARS. */ - +#include #include #include #include @@ -2508,15 +2508,15 @@ static int fwu_read_f34_blocks(unsigned short block_cnt, unsigned char cmd) static int fwu_get_image_firmware_id(unsigned int *fw_id) { int retval; - unsigned char index = 0; - char *strptr; char *firmware_id; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; if (fwu->img.contains_firmware_id) { *fw_id = fwu->img.firmware_id; } else { - strptr = strnstr(fwu->image_name, "PR", MAX_IMAGE_NAME_LEN); + size_t index, max_index; + unsigned char *strptr = strnstr(fwu->image_name, "PR", MAX_IMAGE_NAME_LEN); + if (!strptr) { dev_err(rmi4_data->pdev->dev.parent, "%s: No valid PR number (PRxxxxxxx) found in image file name (%s)\n", @@ -2532,7 +2532,11 @@ static int fwu_get_image_firmware_id(unsigned int *fw_id) __func__); return -ENOMEM; } - while (strptr[index] >= '0' && strptr[index] <= '9') { + + max_index = min((ptrdiff_t)(MAX_FIRMWARE_ID_LEN - 1), + &fwu->image_name[MAX_IMAGE_NAME_LEN] - strptr); + index = 0; + while (index < max_index && isdigit(strptr[index])) { firmware_id[index] = strptr[index]; index++; } -- cgit v1.2.3 From a2b6ee9e28747233d363f59e7aa0b023b8b51be5 Mon Sep 17 00:00:00 2001 From: John Dias Date: Mon, 10 Oct 2016 14:44:30 -0700 Subject: perf: protect group_leader from races that cause ctx double-free When moving a group_leader perf event from a software-context to a hardware-context, there's a race in checking and updating that context. The existing locking solution doesn't work; note that it tries to grab a lock inside the group_leader's context object, which you can only get at by going through a pointer that should be protected from these races. To avoid that problem, and to produce a simple solution, we can just use a lock per group_leader to protect all checks on the group_leader's context. The new lock is grabbed and released when no context locks are held. Bug: 30955111 Bug: 31095224 Change-Id: If37124c100ca6f4aa962559fba3bd5dbbec8e052 --- include/linux/perf_event.h | 6 ++++++ kernel/events/core.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index aebe48c51dce..75368f9ea2e6 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -339,6 +339,12 @@ struct perf_event { int nr_siblings; int group_flags; struct perf_event *group_leader; + + /* + * Protect the pmu, attributes and context of a group leader. + * Note: does not protect the pointer to the group_leader. + */ + struct mutex group_leader_mutex; struct pmu *pmu; enum perf_event_active_state state; diff --git a/kernel/events/core.c b/kernel/events/core.c index 1241a05d3be9..197492d6fe03 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6998,6 +6998,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, if (!group_leader) group_leader = event; + mutex_init(&event->group_leader_mutex); mutex_init(&event->child_mutex); INIT_LIST_HEAD(&event->child_list); @@ -7353,6 +7354,16 @@ SYSCALL_DEFINE5(perf_event_open, group_leader = NULL; } + /* + * Take the group_leader's group_leader_mutex before observing + * anything in the group leader that leads to changes in ctx, + * many of which may be changing on another thread. + * In particular, we want to take this lock before deciding + * whether we need to move_group. + */ + if (group_leader) + mutex_lock(&group_leader->group_leader_mutex); + if (pid != -1 && !(flags & PERF_FLAG_PID_CGROUP)) { task = find_lively_task_by_vpid(pid); if (IS_ERR(task)) { @@ -7519,6 +7530,8 @@ SYSCALL_DEFINE5(perf_event_open, perf_install_in_context(ctx, event, event->cpu); perf_unpin_context(ctx); mutex_unlock(&ctx->mutex); + if (group_leader) + mutex_unlock(&group_leader->group_leader_mutex); put_online_cpus(); @@ -7555,6 +7568,8 @@ err_task: if (task) put_task_struct(task); err_group_fd: + if (group_leader) + mutex_unlock(&group_leader->group_leader_mutex); fdput(group); err_fd: put_unused_fd(event_fd); -- cgit v1.2.3 From f9b53dfaa68cfbd496e725b83c6de0f776f9368f Mon Sep 17 00:00:00 2001 From: John Dias Date: Mon, 10 Oct 2016 14:32:55 -0700 Subject: BACKPORT: perf: Fix event->ctx locking There have been a few reported issues wrt. the lack of locking around changing event->ctx. This patch tries to address those. It avoids the whole rwsem thing; and while it appears to work, please give it some thought in review. What I did fail at is sensible runtime checks on the use of event->ctx, the RCU use makes it very hard. Signed-off-by: Peter Zijlstra (Intel) Cc: Paul E. McKenney Cc: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20150123125834.209535886@infradead.org Signed-off-by: Ingo Molnar (cherry picked from commit f63a8daa5812afef4f06c962351687e1ff9ccb2b) Bug: 30955111 Bug: 31095224 Change-Id: I5bab713034e960fad467637e98e914440de5666d --- kernel/events/core.c | 244 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 207 insertions(+), 37 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 197492d6fe03..01eab13ec0e7 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -912,6 +912,77 @@ static void put_ctx(struct perf_event_context *ctx) } } +/* + * Because of perf_event::ctx migration in sys_perf_event_open::move_group and + * perf_pmu_migrate_context() we need some magic. + * + * Those places that change perf_event::ctx will hold both + * perf_event_ctx::mutex of the 'old' and 'new' ctx value. + * + * Lock ordering is by mutex address. There is one other site where + * perf_event_context::mutex nests and that is put_event(). But remember that + * that is a parent<->child context relation, and migration does not affect + * children, therefore these two orderings should not interact. + * + * The change in perf_event::ctx does not affect children (as claimed above) + * because the sys_perf_event_open() case will install a new event and break + * the ctx parent<->child relation, and perf_pmu_migrate_context() is only + * concerned with cpuctx and that doesn't have children. + * + * The places that change perf_event::ctx will issue: + * + * perf_remove_from_context(); + * synchronize_rcu(); + * perf_install_in_context(); + * + * to affect the change. The remove_from_context() + synchronize_rcu() should + * quiesce the event, after which we can install it in the new location. This + * means that only external vectors (perf_fops, prctl) can perturb the event + * while in transit. Therefore all such accessors should also acquire + * perf_event_context::mutex to serialize against this. + * + * However; because event->ctx can change while we're waiting to acquire + * ctx->mutex we must be careful and use the below perf_event_ctx_lock() + * function. + * + * Lock order: + * task_struct::perf_event_mutex + * perf_event_context::mutex + * perf_event_context::lock + * perf_event::child_mutex; + * perf_event::mmap_mutex + * mmap_sem + */ +static struct perf_event_context *perf_event_ctx_lock(struct perf_event *event) +{ + struct perf_event_context *ctx; + +again: + rcu_read_lock(); + ctx = ACCESS_ONCE(event->ctx); + if (!atomic_inc_not_zero(&ctx->refcount)) { + rcu_read_unlock(); + goto again; + } + rcu_read_unlock(); + + mutex_lock(&ctx->mutex); + if (event->ctx != ctx) { + mutex_unlock(&ctx->mutex); + put_ctx(ctx); + goto again; + } + + return ctx; +} + +static void perf_event_ctx_unlock(struct perf_event *event, + struct perf_event_context *ctx) +{ + mutex_unlock(&ctx->mutex); + put_ctx(ctx); +} + /* * This must be done under the ctx->lock, such as to serialize against * context_equiv(), therefore we cannot call put_ctx() since that might end up @@ -1662,7 +1733,7 @@ int __perf_event_disable(void *info) * is the current context on this CPU and preemption is disabled, * hence we can't get into perf_event_task_sched_out for this context. */ -void perf_event_disable(struct perf_event *event) +static void _perf_event_disable(struct perf_event *event) { struct perf_event_context *ctx = event->ctx; struct task_struct *task = ctx->task; @@ -1703,6 +1774,19 @@ retry: } raw_spin_unlock_irq(&ctx->lock); } + +/* + * Strictly speaking kernel users cannot create groups and therefore this + * interface does not need the perf_event_ctx_lock() magic. + */ +void perf_event_disable(struct perf_event *event) +{ + struct perf_event_context *ctx; + + ctx = perf_event_ctx_lock(event); + _perf_event_disable(event); + perf_event_ctx_unlock(event, ctx); +} EXPORT_SYMBOL_GPL(perf_event_disable); static void perf_set_shadow_time(struct perf_event *event, @@ -2166,7 +2250,7 @@ unlock: * perf_event_for_each_child or perf_event_for_each as described * for perf_event_disable. */ -void perf_event_enable(struct perf_event *event) +static void _perf_event_enable(struct perf_event *event) { struct perf_event_context *ctx = event->ctx; struct task_struct *task = ctx->task; @@ -2222,9 +2306,21 @@ retry: out: raw_spin_unlock_irq(&ctx->lock); } + +/* + * See perf_event_disable(); + */ +void perf_event_enable(struct perf_event *event) +{ + struct perf_event_context *ctx; + + ctx = perf_event_ctx_lock(event); + _perf_event_enable(event); + perf_event_ctx_unlock(event, ctx); +} EXPORT_SYMBOL_GPL(perf_event_enable); -int perf_event_refresh(struct perf_event *event, int refresh) +static int _perf_event_refresh(struct perf_event *event, int refresh) { /* * not supported on inherited events @@ -2233,10 +2329,25 @@ int perf_event_refresh(struct perf_event *event, int refresh) return -EINVAL; atomic_add(refresh, &event->event_limit); - perf_event_enable(event); + _perf_event_enable(event); return 0; } + +/* + * See perf_event_disable() + */ +int perf_event_refresh(struct perf_event *event, int refresh) +{ + struct perf_event_context *ctx; + int ret; + + ctx = perf_event_ctx_lock(event); + ret = _perf_event_refresh(event, refresh); + perf_event_ctx_unlock(event, ctx); + + return ret; +} EXPORT_SYMBOL_GPL(perf_event_refresh); static void ctx_sched_out(struct perf_event_context *ctx, @@ -3434,7 +3545,16 @@ static void perf_remove_from_owner(struct perf_event *event) rcu_read_unlock(); if (owner) { - mutex_lock(&owner->perf_event_mutex); + /* + * If we're here through perf_event_exit_task() we're already + * holding ctx->mutex which would be an inversion wrt. the + * normal lock order. + * + * However we can safely take this lock because its the child + * ctx->mutex. + */ + mutex_lock_nested(&owner->perf_event_mutex, SINGLE_DEPTH_NESTING); + /* * We have to re-check the event->owner field, if it is cleared * we raced with perf_event_exit_task(), acquiring the mutex @@ -3569,12 +3689,13 @@ static int perf_event_read_group(struct perf_event *event, u64 read_format, char __user *buf) { struct perf_event *leader = event->group_leader, *sub; - int n = 0, size = 0, ret = -EFAULT; struct perf_event_context *ctx = leader->ctx; - u64 values[5]; + int n = 0, size = 0, ret; u64 count, enabled, running; + u64 values[5]; + + lockdep_assert_held(&ctx->mutex); - mutex_lock(&ctx->mutex); count = perf_event_read_value(leader, &enabled, &running); values[n++] = 1 + leader->nr_siblings; @@ -3589,7 +3710,7 @@ static int perf_event_read_group(struct perf_event *event, size = n * sizeof(u64); if (copy_to_user(buf, values, size)) - goto unlock; + return -EFAULT; ret = size; @@ -3603,14 +3724,11 @@ static int perf_event_read_group(struct perf_event *event, size = n * sizeof(u64); if (copy_to_user(buf + ret, values, size)) { - ret = -EFAULT; - goto unlock; + return -EFAULT; } ret += size; } -unlock: - mutex_unlock(&ctx->mutex); return ret; } @@ -3682,8 +3800,14 @@ static ssize_t perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct perf_event *event = file->private_data; + struct perf_event_context *ctx; + int ret; - return perf_read_hw(event, buf, count); + ctx = perf_event_ctx_lock(event); + ret = perf_read_hw(event, buf, count); + perf_event_ctx_unlock(event, ctx); + + return ret; } static unsigned int perf_poll(struct file *file, poll_table *wait) @@ -3709,7 +3833,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) return events; } -static void perf_event_reset(struct perf_event *event) +static void _perf_event_reset(struct perf_event *event) { (void)perf_event_read(event); local64_set(&event->count, 0); @@ -3728,6 +3852,7 @@ static void perf_event_for_each_child(struct perf_event *event, struct perf_event *child; WARN_ON_ONCE(event->ctx->parent_ctx); + mutex_lock(&event->child_mutex); func(event); list_for_each_entry(child, &event->child_list, child_list) @@ -3741,14 +3866,13 @@ static void perf_event_for_each(struct perf_event *event, struct perf_event_context *ctx = event->ctx; struct perf_event *sibling; - WARN_ON_ONCE(ctx->parent_ctx); - mutex_lock(&ctx->mutex); + lockdep_assert_held(&ctx->mutex); + event = event->group_leader; perf_event_for_each_child(event, func); list_for_each_entry(sibling, &event->sibling_list, group_entry) perf_event_for_each_child(sibling, func); - mutex_unlock(&ctx->mutex); } struct period_event { @@ -3853,25 +3977,24 @@ static int perf_event_set_output(struct perf_event *event, struct perf_event *output_event); static int perf_event_set_filter(struct perf_event *event, void __user *arg); -static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned long arg) { - struct perf_event *event = file->private_data; void (*func)(struct perf_event *); u32 flags = arg; switch (cmd) { case PERF_EVENT_IOC_ENABLE: - func = perf_event_enable; + func = _perf_event_enable; break; case PERF_EVENT_IOC_DISABLE: - func = perf_event_disable; + func = _perf_event_disable; break; case PERF_EVENT_IOC_RESET: - func = perf_event_reset; + func = _perf_event_reset; break; case PERF_EVENT_IOC_REFRESH: - return perf_event_refresh(event, arg); + return _perf_event_refresh(event, arg); case PERF_EVENT_IOC_PERIOD: return perf_event_period(event, (u64 __user *)arg); @@ -3918,6 +4041,19 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return 0; } +static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct perf_event *event = file->private_data; + struct perf_event_context *ctx; + long ret; + + ctx = perf_event_ctx_lock(event); + ret = _perf_ioctl(event, cmd, arg); + perf_event_ctx_unlock(event, ctx); + + return ret; +} + #ifdef CONFIG_COMPAT static long perf_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -3940,11 +4076,15 @@ static long perf_compat_ioctl(struct file *file, unsigned int cmd, int perf_event_task_enable(void) { + struct perf_event_context *ctx; struct perf_event *event; mutex_lock(¤t->perf_event_mutex); - list_for_each_entry(event, ¤t->perf_event_list, owner_entry) - perf_event_for_each_child(event, perf_event_enable); + list_for_each_entry(event, ¤t->perf_event_list, owner_entry) { + ctx = perf_event_ctx_lock(event); + perf_event_for_each_child(event, _perf_event_enable); + perf_event_ctx_unlock(event, ctx); + } mutex_unlock(¤t->perf_event_mutex); return 0; @@ -3952,11 +4092,15 @@ int perf_event_task_enable(void) int perf_event_task_disable(void) { + struct perf_event_context *ctx; struct perf_event *event; mutex_lock(¤t->perf_event_mutex); - list_for_each_entry(event, ¤t->perf_event_list, owner_entry) - perf_event_for_each_child(event, perf_event_disable); + list_for_each_entry(event, ¤t->perf_event_list, owner_entry) { + ctx = perf_event_ctx_lock(event); + perf_event_for_each_child(event, _perf_event_disable); + perf_event_ctx_unlock(event, ctx); + } mutex_unlock(¤t->perf_event_mutex); return 0; @@ -7275,6 +7419,15 @@ out: return ret; } +static void mutex_lock_double(struct mutex *a, struct mutex *b) +{ + if (b < a) + swap(a, b); + + mutex_lock(a); + mutex_lock_nested(b, SINGLE_DEPTH_NESTING); +} + /** * sys_perf_event_open - open a performance event, associate it to a task/cpu * @@ -7290,7 +7443,7 @@ SYSCALL_DEFINE5(perf_event_open, struct perf_event *group_leader = NULL, *output_event = NULL; struct perf_event *event, *sibling; struct perf_event_attr attr; - struct perf_event_context *ctx; + struct perf_event_context *ctx, *uninitialized_var(gctx); struct file *event_file = NULL; struct fd group = {NULL, 0}; struct task_struct *task = NULL; @@ -7492,9 +7645,14 @@ SYSCALL_DEFINE5(perf_event_open, } if (move_group) { - struct perf_event_context *gctx = group_leader->ctx; + gctx = group_leader->ctx; + + /* + * See perf_event_ctx_lock() for comments on the details + * of swizzling perf_event::ctx. + */ + mutex_lock_double(&gctx->mutex, &ctx->mutex); - mutex_lock(&gctx->mutex); perf_remove_from_context(group_leader, false); /* @@ -7509,15 +7667,19 @@ SYSCALL_DEFINE5(perf_event_open, perf_event__state_init(sibling); put_ctx(gctx); } - mutex_unlock(&gctx->mutex); - put_ctx(gctx); + } else { + mutex_lock(&ctx->mutex); } WARN_ON_ONCE(ctx->parent_ctx); - mutex_lock(&ctx->mutex); if (move_group) { + /* + * Wait for everybody to stop referencing the events through + * the old lists, before installing it on new lists. + */ synchronize_rcu(); + perf_install_in_context(ctx, group_leader, group_leader->cpu); get_ctx(ctx); list_for_each_entry(sibling, &group_leader->sibling_list, @@ -7529,6 +7691,11 @@ SYSCALL_DEFINE5(perf_event_open, perf_install_in_context(ctx, event, event->cpu); perf_unpin_context(ctx); + + if (move_group) { + mutex_unlock(&gctx->mutex); + put_ctx(gctx); + } mutex_unlock(&ctx->mutex); if (group_leader) mutex_unlock(&group_leader->group_leader_mutex); @@ -7640,7 +7807,11 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) src_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, src_cpu)->ctx; dst_ctx = &per_cpu_ptr(pmu->pmu_cpu_context, dst_cpu)->ctx; - mutex_lock(&src_ctx->mutex); + /* + * See perf_event_ctx_lock() for comments on the details + * of swizzling perf_event::ctx. + */ + mutex_lock_double(&src_ctx->mutex, &dst_ctx->mutex); list_for_each_entry_safe(event, tmp, &src_ctx->event_list, event_entry) { perf_remove_from_context(event, false); @@ -7648,11 +7819,9 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) put_ctx(src_ctx); list_add(&event->migrate_entry, &events); } - mutex_unlock(&src_ctx->mutex); synchronize_rcu(); - mutex_lock(&dst_ctx->mutex); list_for_each_entry_safe(event, tmp, &events, migrate_entry) { list_del(&event->migrate_entry); if (event->state >= PERF_EVENT_STATE_OFF) @@ -7662,6 +7831,7 @@ void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu) get_ctx(dst_ctx); } mutex_unlock(&dst_ctx->mutex); + mutex_unlock(&src_ctx->mutex); } EXPORT_SYMBOL_GPL(perf_pmu_migrate_context); -- cgit v1.2.3 From 45619caa55254946692bc80ccbd5a762e47b2762 Mon Sep 17 00:00:00 2001 From: Haynes Mathew George Date: Wed, 5 Oct 2016 14:59:39 -0700 Subject: ASoC: msm: lock read/write when add/free audio ion memory As read/write get access to ion memory region as well, it's necessary to lock them when ion memory is about to be added/freed to avoid racing cases. Bug: 31252384 CRs-Fixed: 1071809 Change-Id: I436ead23c93384961b38ca99b9312a40c50ad03a Signed-off-by: Walter Yang Signed-off-by: Haynes Mathew George --- drivers/misc/qcom/qdsp6v2/audio_utils_aio.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c index 7267557d48dc..ea1cb510a97f 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils_aio.c @@ -570,6 +570,8 @@ int audio_aio_release(struct inode *inode, struct file *file) struct q6audio_aio *audio = file->private_data; pr_debug("%s[%p]\n", __func__, audio); mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); audio->wflush = 1; if (audio->wakelock_voted && (audio->audio_ws_mgr != NULL) && @@ -595,6 +597,8 @@ int audio_aio_release(struct inode *inode, struct file *file) wake_up(&audio->event_wait); audio_aio_reset_event_queue(audio); q6asm_audio_client_free(audio->ac); + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); mutex_destroy(&audio->lock); mutex_destroy(&audio->read_lock); @@ -1732,6 +1736,8 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ion_info info; pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio); mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); if (copy_from_user(&info, (void *)arg, sizeof(info))) { pr_err( "%s: copy_from_user for AUDIO_REGISTER_ION failed\n", @@ -1740,12 +1746,16 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } else { rc = audio_aio_ion_add(audio, &info); } + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); break; } case AUDIO_DEREGISTER_ION: { struct msm_audio_ion_info info; mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio); if (copy_from_user(&info, (void *)arg, sizeof(info))) { pr_err( @@ -1755,6 +1765,8 @@ static long audio_aio_ioctl(struct file *file, unsigned int cmd, } else { rc = audio_aio_ion_remove(audio, &info); } + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); break; } @@ -2050,6 +2062,8 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ion_info info; pr_debug("%s[%p]:AUDIO_REGISTER_ION\n", __func__, audio); mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { pr_err("%s: copy_from_user for AUDIO_REGISTER_ION_32 failed\n", __func__); @@ -2059,6 +2073,8 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, info.vaddr = compat_ptr(info_32.vaddr); rc = audio_aio_ion_add(audio, &info); } + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); break; } @@ -2066,6 +2082,8 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, struct msm_audio_ion_info32 info_32; struct msm_audio_ion_info info; mutex_lock(&audio->lock); + mutex_lock(&audio->read_lock); + mutex_lock(&audio->write_lock); pr_debug("%s[%p]:AUDIO_DEREGISTER_ION\n", __func__, audio); if (copy_from_user(&info_32, (void *)arg, sizeof(info_32))) { pr_err("%s: copy_from_user for AUDIO_DEREGISTER_ION_32 failed\n", @@ -2076,6 +2094,8 @@ static long audio_aio_compat_ioctl(struct file *file, unsigned int cmd, info.vaddr = compat_ptr(info_32.vaddr); rc = audio_aio_ion_remove(audio, &info); } + mutex_unlock(&audio->write_lock); + mutex_unlock(&audio->read_lock); mutex_unlock(&audio->lock); break; } -- cgit v1.2.3 From 1e91b0c12f1077e0df78a1c87014ef41aa398be1 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 7 Oct 2016 13:54:56 -0700 Subject: msm: mdss: blacklist %p kptr_restrict Bug: 30148242 Change-Id: I7dde70a8998719daf4c3dd4495951995138fa6ec --- drivers/video/msm/mdss/mdp3.c | 16 ++--- drivers/video/msm/mdss/mdp3_dma.c | 2 +- drivers/video/msm/mdss/mdp3_ppp_hwio.c | 6 +- drivers/video/msm/mdss/mdss_compat_utils.c | 18 ++--- drivers/video/msm/mdss/mdss_debug.c | 6 +- drivers/video/msm/mdss/mdss_debug_xlog.c | 12 ++-- drivers/video/msm/mdss/mdss_dsi.c | 26 +++---- drivers/video/msm/mdss/mdss_dsi_clk.c | 6 +- drivers/video/msm/mdss/mdss_dsi_host.c | 2 +- drivers/video/msm/mdss/mdss_dsi_panel.c | 10 +-- drivers/video/msm/mdss/mdss_fb.c | 10 +-- drivers/video/msm/mdss/mdss_hdmi_tx.c | 6 +- drivers/video/msm/mdss/mdss_mdp.c | 12 ++-- drivers/video/msm/mdss/mdss_mdp_debug.c | 2 +- drivers/video/msm/mdss/mdss_mdp_intf_cmd.c | 6 +- drivers/video/msm/mdss/mdss_mdp_intf_video.c | 10 +-- drivers/video/msm/mdss/mdss_mdp_layer.c | 4 +- drivers/video/msm/mdss/mdss_mdp_overlay.c | 10 +-- drivers/video/msm/mdss/mdss_mdp_pipe.c | 2 +- drivers/video/msm/mdss/mdss_mdp_pp.c | 72 ++++++++++---------- drivers/video/msm/mdss/mdss_mdp_pp_cache_config.c | 66 +++++++++--------- drivers/video/msm/mdss/mdss_mdp_pp_common.c | 4 +- drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c | 82 +++++++++++------------ drivers/video/msm/mdss/mdss_mdp_pp_v3.c | 34 +++++----- drivers/video/msm/mdss/mdss_mdp_util.c | 6 +- drivers/video/msm/mdss/mdss_util.c | 2 +- drivers/video/msm/mdss/mhl3/mhl_linux_tx.c | 2 +- drivers/video/msm/mdss/mhl3/mhl_supp.c | 12 ++-- drivers/video/msm/mdss/mhl3/platform.c | 6 +- drivers/video/msm/mdss/mhl3/si_8620_drv.c | 4 +- drivers/video/msm/mdss/mhl3/si_emsc_hid.c | 4 +- drivers/video/msm/mdss/mhl3/si_mdt_inputdev.c | 24 +++---- drivers/video/msm/mdss/mhl3/si_mhl2_edid_3d.c | 26 +++---- 33 files changed, 255 insertions(+), 255 deletions(-) diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c index 0bfeb3b10f04..3bd94c68d561 100644 --- a/drivers/video/msm/mdss/mdp3.c +++ b/drivers/video/msm/mdss/mdp3.c @@ -1125,7 +1125,7 @@ static int mdp3_res_init(void) mdp3_res->ion_client = msm_ion_client_create(mdp3_res->pdev->name); if (IS_ERR_OR_NULL(mdp3_res->ion_client)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdp3_res->ion_client); mdp3_res->ion_client = NULL; return -EINVAL; @@ -1555,7 +1555,7 @@ void mdp3_unmap_iommu(struct ion_client *client, struct ion_handle *handle) mutex_lock(&mdp3_res->iommu_lock); meta = mdp3_iommu_meta_lookup(table); if (!meta) { - WARN(1, "%s: buffer was never mapped for %p\n", __func__, + WARN(1, "%s: buffer was never mapped for %pK\n", __func__, handle); mutex_unlock(&mdp3_res->iommu_lock); return; @@ -1581,7 +1581,7 @@ static void mdp3_iommu_meta_add(struct mdp3_iommu_meta *meta) } else if (meta->table > entry->table) { p = &(*p)->rb_right; } else { - pr_err("%s: handle %p already exists\n", __func__, + pr_err("%s: handle %pK already exists\n", __func__, entry->handle); BUG(); } @@ -1644,7 +1644,7 @@ static int mdp3_iommu_map_iommu(struct mdp3_iommu_meta *meta, ret = iommu_map_range(domain, meta->iova_addr + padding, table->sgl, size, prot); if (ret) { - pr_err("%s: could not map %pa in domain %p\n", + pr_err("%s: could not map %pa in domain %pK\n", __func__, &meta->iova_addr, domain); unmap_size = padding; goto out2; @@ -1767,12 +1767,12 @@ int mdp3_self_map_iommu(struct ion_client *client, struct ion_handle *handle, } } else { if (iommu_meta->flags != iommu_flags) { - pr_err("%s: hndl %p already mapped with diff flag\n", + pr_err("%s: hndl %pK already mapped with diff flag\n", __func__, handle); ret = -EINVAL; goto out_unlock; } else if (iommu_meta->mapped_size != iova_length) { - pr_err("%s: hndl %p already mapped with diff len\n", + pr_err("%s: hndl %pK already mapped with diff len\n", __func__, handle); ret = -EINVAL; goto out_unlock; @@ -1806,7 +1806,7 @@ int mdp3_put_img(struct mdp3_img_data *data, int client) fdput(data->srcp_f); memset(&data->srcp_f, 0, sizeof(struct fd)); } else if (!IS_ERR_OR_NULL(data->srcp_dma_buf)) { - pr_debug("ion hdl = %p buf=0x%pa\n", data->srcp_dma_buf, + pr_debug("ion hdl = %pK buf=0x%pa\n", data->srcp_dma_buf, &data->addr); if (!iclient) { pr_err("invalid ion client\n"); @@ -1909,7 +1909,7 @@ done: data->addr += img->offset; data->len -= img->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%lx\n", + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%lx\n", img->memory_id, data->srcp_dma_buf, &data->addr, data->len); diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c index d4c83d6e33f0..8b382ea6fd95 100644 --- a/drivers/video/msm/mdss/mdp3_dma.c +++ b/drivers/video/msm/mdss/mdp3_dma.c @@ -721,7 +721,7 @@ retry_dma_done: retry_vsync: rc = wait_for_completion_timeout(&dma->vsync_comp, KOFF_TIMEOUT); - pr_err("%s VID DMA Buff Addr %p\n", __func__, buf); + pr_err("%s VID DMA Buff Addr %pK\n", __func__, buf); if (rc <= 0 && --retry_count) { int vsync = MDP3_REG_READ(MDP3_REG_INTR_STATUS) & (1 << MDP3_INTR_LCDC_START_OF_FRAME); diff --git a/drivers/video/msm/mdss/mdp3_ppp_hwio.c b/drivers/video/msm/mdss/mdp3_ppp_hwio.c index 5ba3fbdb6238..a4c66939bb18 100644 --- a/drivers/video/msm/mdss/mdp3_ppp_hwio.c +++ b/drivers/video/msm/mdss/mdp3_ppp_hwio.c @@ -1308,7 +1308,7 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) pr_debug("ROI(x %d,y %d,w %d, h %d) ", blit_op->src.roi.x, blit_op->src.roi.y, blit_op->src.roi.width, blit_op->src.roi.height); - pr_debug("Addr_P0 %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + pr_debug("Addr_P0 %pK, Stride S0 %d Addr_P1 %pK, Stride S1 %d\n", blit_op->src.p0, blit_op->src.stride0, blit_op->src.p1, blit_op->src.stride1); @@ -1320,7 +1320,7 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) pr_debug("ROI(x %d,y %d, w %d, h %d) ", blit_op->bg.roi.x, blit_op->bg.roi.y, blit_op->bg.roi.width, blit_op->bg.roi.height); - pr_debug("Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + pr_debug("Addr %pK, Stride S0 %d Addr_P1 %pK, Stride S1 %d\n", blit_op->bg.p0, blit_op->bg.stride0, blit_op->bg.p1, blit_op->bg.stride1); } @@ -1331,7 +1331,7 @@ int config_ppp_op_mode(struct ppp_blit_op *blit_op) pr_debug("ROI(x %d,y %d, w %d, h %d) ", blit_op->dst.roi.x, blit_op->dst.roi.y, blit_op->dst.roi.width, blit_op->dst.roi.height); - pr_debug("Addr %p, Stride S0 %d Addr_P1 %p, Stride S1 %d\n", + pr_debug("Addr %pK, Stride S0 %d Addr_P1 %pK, Stride S1 %d\n", blit_op->dst.p0, blit_op->src.stride0, blit_op->dst.p1, blit_op->dst.stride1); diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c index e883f045967d..5ad51dd23f3b 100644 --- a/drivers/video/msm/mdss/mdss_compat_utils.c +++ b/drivers/video/msm/mdss/mdss_compat_utils.c @@ -150,7 +150,7 @@ static struct mdp_input_layer32 *__create_layer_list32( compat_ptr(commit32->commit_v1.input_layers), sizeof(struct mdp_input_layer32) * layer_count); if (ret) { - pr_err("layer list32 copy from user failed, ptr %p\n", + pr_err("layer list32 copy from user failed, ptr %pK\n", compat_ptr(commit32->commit_v1.input_layers)); kfree(layer_list32); ret = -EFAULT; @@ -182,7 +182,7 @@ static int __copy_scale_params(struct mdp_input_layer *layer, sizeof(struct mdp_scale_data)); if (ret) { kfree(scale); - pr_err("scale param copy from user failed, ptr %p\n", + pr_err("scale param copy from user failed, ptr %pK\n", compat_ptr(layer32->scale)); ret = -EFAULT; } else { @@ -307,7 +307,7 @@ static int __compat_atomic_commit(struct fb_info *info, unsigned int cmd, ret = copy_from_user(&commit32, (void __user *)argp, sizeof(struct mdp_layer_commit32)); if (ret) { - pr_err("%s:copy_from_user failed, ptr %p\n", __func__, + pr_err("%s:copy_from_user failed, ptr %pK\n", __func__, (void __user *)argp); ret = -EFAULT; return ret; @@ -325,7 +325,7 @@ static int __compat_atomic_commit(struct fb_info *info, unsigned int cmd, compat_ptr(commit32.commit_v1.output_layer), buffer_size); if (ret) { - pr_err("fail to copy output layer from user, ptr %p\n", + pr_err("fail to copy output layer from user, ptr %pK\n", compat_ptr(commit32.commit_v1.output_layer)); ret = -EFAULT; goto layer_list_err; @@ -3418,7 +3418,7 @@ static int __copy_layer_igc_lut_data_v1_7( cfg_payload32, sizeof(struct mdp_igc_lut_data_v1_7_32)); if (ret) { - pr_err("copy from user failed, IGC cfg payload = %p\n", + pr_err("copy from user failed, IGC cfg payload = %pK\n", cfg_payload32); ret = -EFAULT; goto exit; @@ -3493,7 +3493,7 @@ static int __copy_layer_hist_lut_data_v1_7( cfg_payload32, sizeof(struct mdp_hist_lut_data_v1_7_32)); if (ret) { - pr_err("copy from user failed, hist lut cfg_payload = %p\n", + pr_err("copy from user failed, hist lut cfg_payload = %pK\n", cfg_payload32); ret = -EFAULT; goto exit; @@ -3565,7 +3565,7 @@ static int __copy_layer_pa_data_v1_7( cfg_payload32, sizeof(struct mdp_pa_data_v1_7_32)); if (ret) { - pr_err("copy from user failed, pa cfg_payload = %p\n", + pr_err("copy from user failed, pa cfg_payload = %pK\n", cfg_payload32); ret = -EFAULT; goto exit; @@ -3707,7 +3707,7 @@ static int __copy_layer_pp_info_pcc_params( compat_ptr(pp_info32->pcc_cfg_data.cfg_payload), sizeof(struct mdp_pcc_data_v1_7)); if (ret) { - pr_err("compat copy of PCC cfg payload failed, ptr %p\n", + pr_err("compat copy of PCC cfg payload failed, ptr %pK\n", compat_ptr( pp_info32->pcc_cfg_data.cfg_payload)); ret = -EFAULT; @@ -3741,7 +3741,7 @@ static int __copy_layer_pp_info_params(struct mdp_input_layer *layer, compat_ptr(layer32->pp_info), sizeof(struct mdp_overlay_pp_params32)); if (ret) { - pr_err("pp info copy from user failed, pp_info %p\n", + pr_err("pp info copy from user failed, pp_info %pK\n", compat_ptr(layer32->pp_info)); ret = -EFAULT; goto exit; diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c index bd51ea6e7f9c..aef02ef8c3b3 100644 --- a/drivers/video/msm/mdss/mdss_debug.c +++ b/drivers/video/msm/mdss/mdss_debug.c @@ -1348,7 +1348,7 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, return NULL; } - pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%p)\n", + pr_debug("MISR Module(%d) CTRL(0x%x) SIG(0x%x) intf_base(0x%pK)\n", block_id, map->ctrl_reg, map->value_reg, intf_base); return map; } @@ -1421,7 +1421,7 @@ int mdss_misr_set(struct mdss_data_type *mdata, bool use_mdp_up_misr = false; if (!mdata || !req || !ctl) { - pr_err("Invalid input params: mdata = %p req = %p ctl = %p", + pr_err("Invalid input params: mdata = %pK req = %pK ctl = %pK", mdata, req, ctl); return -EINVAL; } @@ -1501,7 +1501,7 @@ int mdss_misr_set(struct mdss_data_type *mdata, writel_relaxed(config, mdata->mdp_base + map->ctrl_reg); - pr_debug("MISR_CTRL=0x%x [base:0x%p reg:0x%x config:0x%x]\n", + pr_debug("MISR_CTRL=0x%x [base:0x%pK reg:0x%x config:0x%x]\n", readl_relaxed(mdata->mdp_base + map->ctrl_reg), mdata->mdp_base, map->ctrl_reg, config); } diff --git a/drivers/video/msm/mdss/mdss_debug_xlog.c b/drivers/video/msm/mdss/mdss_debug_xlog.c index 1797628d24b5..488f6ab053f5 100644 --- a/drivers/video/msm/mdss/mdss_debug_xlog.c +++ b/drivers/video/msm/mdss/mdss_debug_xlog.c @@ -253,7 +253,7 @@ static void mdss_dump_debug_bus(u32 bus_dump_flag, if (*dump_mem) { dump_addr = *dump_mem; - pr_info("%s: start_addr:0x%p end_addr:0x%p\n", + pr_info("%s: start_addr:0x%pK end_addr:0x%pK\n", __func__, dump_addr, dump_addr + list_size); } else { in_mem = false; @@ -371,7 +371,7 @@ static void mdss_dump_vbif_debug_bus(u32 bus_dump_flag, if (*dump_mem) { dump_addr = *dump_mem; - pr_info("%s: start_addr:0x%p end_addr:0x%p\n", + pr_info("%s: start_addr:0x%pK end_addr:0x%pK\n", __func__, dump_addr, dump_addr + list_size); } else { in_mem = false; @@ -431,7 +431,7 @@ void mdss_dump_reg(const char *dump_name, u32 reg_dump_flag, char *addr, if (*dump_mem) { dump_addr = *dump_mem; - pr_info("%s: start_addr:0x%p end_addr:0x%p reg_addr=0x%p\n", + pr_info("%s: start_addr:0x%pK end_addr:0x%pK reg_addr=0x%pK\n", dump_name, dump_addr, dump_addr + (u32)len * 16, addr); } else { @@ -452,7 +452,7 @@ void mdss_dump_reg(const char *dump_name, u32 reg_dump_flag, char *addr, xc = readl_relaxed(addr+0xc); if (in_log) - pr_info("%p : %08x %08x %08x %08x\n", addr, x0, x4, x8, + pr_info("%pK : %08x %08x %08x %08x\n", addr, x0, x4, x8, xc); if (dump_addr && in_mem) { @@ -490,7 +490,7 @@ static void mdss_dump_reg_by_ranges(struct mdss_debug_base *dbg, len = get_dump_range(&xlog_node->offset, dbg->max_offset); addr = dbg->base + xlog_node->offset.start; - pr_debug("%s: range_base=0x%p start=0x%x end=0x%x\n", + pr_debug("%s: range_base=0x%pK start=0x%x end=0x%x\n", xlog_node->range_name, addr, xlog_node->offset.start, xlog_node->offset.end); @@ -501,7 +501,7 @@ static void mdss_dump_reg_by_ranges(struct mdss_debug_base *dbg, } else { /* If there is no list to dump ranges, dump all registers */ pr_info("Ranges not found, will dump full registers"); - pr_info("base:0x%p len:0x%zu\n", dbg->base, dbg->max_offset); + pr_info("base:0x%pK len:0x%zu\n", dbg->base, dbg->max_offset); addr = dbg->base; len = dbg->max_offset; mdss_dump_reg((const char *)dbg->name, reg_dump_flag, addr, diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c index de9f393b5d32..649780a43ddb 100644 --- a/drivers/video/msm/mdss/mdss_dsi.c +++ b/drivers/video/msm/mdss/mdss_dsi.c @@ -1131,7 +1131,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) panel_info = &ctrl_pdata->panel_data.panel_info; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); if (power_state == panel_info->panel_power_state) { @@ -1312,7 +1312,7 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) mdss_dsi_validate_debugfs_info(ctrl_pdata); cur_power_state = pdata->panel_info.panel_power_state; - pr_debug("%s+: ctrl=%p ndx=%d cur_power_state=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, cur_power_state); pinfo = &pdata->panel_info; @@ -1484,7 +1484,7 @@ static int mdss_dsi_unblank(struct mdss_panel_data *pdata) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d cur_power_state=%d ctrl_state=%x\n", + pr_debug("%s+: ctrl=%pK ndx=%d cur_power_state=%d ctrl_state=%x\n", __func__, ctrl_pdata, ctrl_pdata->ndx, pdata->panel_info.panel_power_state, ctrl_pdata->ctrl_state); @@ -1567,7 +1567,7 @@ static int mdss_dsi_blank(struct mdss_panel_data *pdata, int power_state) panel_data); mipi = &pdata->panel_info.mipi; - pr_debug("%s+: ctrl=%p ndx=%d power_state=%d\n", + pr_debug("%s+: ctrl=%pK ndx=%d power_state=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx, power_state); mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle, @@ -1638,7 +1638,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle, @@ -1672,7 +1672,7 @@ int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s+: ctrl=%p ndx=%d\n", __func__, + pr_debug("%s+: ctrl=%pK ndx=%d\n", __func__, ctrl_pdata, ctrl_pdata->ndx); WARN((ctrl_pdata->ctrl_state & CTRL_STATE_PANEL_INIT), @@ -2995,7 +2995,7 @@ static int mdss_dsi_get_bridge_chip_params(struct mdss_panel_info *pinfo, u32 temp_val = 0; if (!ctrl_pdata || !pdev || !pinfo) { - pr_err("%s: Invalid Params ctrl_pdata=%p, pdev=%p\n", __func__, + pr_err("%s: Invalid Params ctrl_pdata=%pK, pdev=%pK\n", __func__, ctrl_pdata, pdev); rc = -EINVAL; goto end; @@ -3332,7 +3332,7 @@ static int mdss_dsi_res_init(struct platform_device *pdev) mdss_dsi_res->shared_data = devm_kzalloc(&pdev->dev, sizeof(struct dsi_shared_data), GFP_KERNEL); - pr_debug("%s Allocated shared_data=%p\n", __func__, + pr_debug("%s Allocated shared_data=%pK\n", __func__, mdss_dsi_res->shared_data); if (!mdss_dsi_res->shared_data) { pr_err("%s Unable to alloc mem for shared_data\n", @@ -3398,7 +3398,7 @@ static int mdss_dsi_res_init(struct platform_device *pdev) rc = -ENOMEM; goto mem_fail; } - pr_debug("%s Allocated ctrl_pdata[%d]=%p\n", + pr_debug("%s Allocated ctrl_pdata[%d]=%pK\n", __func__, i, mdss_dsi_res->ctrl_pdata[i]); mdss_dsi_res->ctrl_pdata[i]->shared_data = mdss_dsi_res->shared_data; @@ -3408,7 +3408,7 @@ static int mdss_dsi_res_init(struct platform_device *pdev) } mdss_dsi_res->pdev = pdev; - pr_debug("%s: Setting up mdss_dsi_res=%p\n", __func__, mdss_dsi_res); + pr_debug("%s: Setting up mdss_dsi_res=%pK\n", __func__, mdss_dsi_res); return 0; @@ -3735,11 +3735,11 @@ int mdss_dsi_retrieve_ctrl_resources(struct platform_device *pdev, int mode, pr_debug("%s:%d unable to remap dsi phy regulator resources\n", __func__, __LINE__); else - pr_info("%s: phy_regulator_base=%p phy_regulator_size=%x\n", + pr_info("%s: phy_regulator_base=%pK phy_regulator_size=%x\n", __func__, ctrl->phy_regulator_io.base, ctrl->phy_regulator_io.len); - pr_info("%s: ctrl_base=%p ctrl_size=%x phy_base=%p phy_size=%x\n", + pr_info("%s: ctrl_base=%pK ctrl_size=%x phy_base=%pK phy_size=%x\n", __func__, ctrl->ctrl_base, ctrl->reg_size, ctrl->phy_io.base, ctrl->phy_io.len); @@ -3883,7 +3883,7 @@ static int mdss_dsi_parse_ctrl_params(struct platform_device *ctrl_pdev, data = of_get_property(ctrl_pdev->dev.of_node, "qcom,display-id", &len); if (!data || len <= 0) - pr_err("%s:%d Unable to read qcom,display-id, data=%p,len=%d\n", + pr_err("%s:%d Unable to read qcom,display-id, data=%pK,len=%d\n", __func__, __LINE__, data, len); else snprintf(ctrl_pdata->panel_data.panel_info.display_id, diff --git a/drivers/video/msm/mdss/mdss_dsi_clk.c b/drivers/video/msm/mdss/mdss_dsi_clk.c index 377aeb7cad47..ec339ba735c7 100644 --- a/drivers/video/msm/mdss/mdss_dsi_clk.c +++ b/drivers/video/msm/mdss/mdss_dsi_clk.c @@ -754,7 +754,7 @@ int mdss_dsi_clk_req_state(void *client, enum mdss_dsi_clk_type clk, if (!client || !clk || clk > (MDSS_DSI_CORE_CLK | MDSS_DSI_LINK_CLK) || state > MDSS_DSI_CLK_EARLY_GATE) { - pr_err("Invalid params, client = %p, clk = 0x%x, state = %d\n", + pr_err("Invalid params, client = %pK, clk = 0x%x, state = %d\n", client, clk, state); return -EINVAL; } @@ -852,7 +852,7 @@ int mdss_dsi_clk_set_link_rate(void *client, enum mdss_dsi_link_clk_type clk, struct mdss_dsi_clk_mngr *mngr; if (!client || (clk > MDSS_DSI_LINK_CLK_MAX)) { - pr_err("Invalid params, client = %p, clk = 0x%x", client, clk); + pr_err("Invalid params, client = %pK, clk = 0x%x", client, clk); return -EINVAL; } @@ -951,7 +951,7 @@ int mdss_dsi_clk_force_toggle(void *client, u32 clk) struct mdss_dsi_clk_mngr *mngr; if (!client || !clk || clk >= MDSS_DSI_CLKS_MAX) { - pr_err("Invalid params, client = %p, clk = 0x%x\n", + pr_err("Invalid params, client = %pK, clk = 0x%x\n", client, clk); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index ff87b03dc705..d29037be7e61 100644 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -104,7 +104,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev, if (ctrl->mdss_util->register_irq(ctrl->dsi_hw)) pr_err("%s: mdss_register_irq failed.\n", __func__); - pr_debug("%s: ndx=%d base=%p\n", __func__, ctrl->ndx, ctrl->ctrl_base); + pr_debug("%s: ndx=%d base=%pK\n", __func__, ctrl->ndx, ctrl->ctrl_base); init_completion(&ctrl->dma_comp); init_completion(&ctrl->mdp_comp); diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c index a4f475ae5e99..00db79a08025 100644 --- a/drivers/video/msm/mdss/mdss_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_dsi_panel.c @@ -881,7 +881,7 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); pinfo = &pdata->panel_info; if (pinfo->dcs_cmd_by_left && ctrl->ndx != DSI_CTRL_LEFT) @@ -919,7 +919,7 @@ static int mdss_dsi_panel_off(struct mdss_panel_data *pdata) ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d\n", __func__, ctrl, ctrl->ndx); + pr_debug("%s: ctrl=%pK ndx=%d\n", __func__, ctrl, ctrl->ndx); if (pinfo->dcs_cmd_by_left) { if (ctrl->ndx != DSI_CTRL_LEFT) @@ -954,7 +954,7 @@ static int mdss_dsi_panel_low_power_config(struct mdss_panel_data *pdata, ctrl = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); - pr_debug("%s: ctrl=%p ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, + pr_debug("%s: ctrl=%pK ndx=%d enable=%d\n", __func__, ctrl, ctrl->ndx, enable); /* Any panel specific low power commands/config */ @@ -2314,7 +2314,7 @@ static int mdss_dsi_panel_timing_from_dt(struct device_node *np, if (np->name) { pt->timing.name = kstrdup(np->name, GFP_KERNEL); - pr_info("%s: found new timing \"%s\" (%p)\n", __func__, + pr_info("%s: found new timing \"%s\" (%pK)\n", __func__, np->name, &pt->timing); } @@ -2723,7 +2723,7 @@ static int mdss_panel_parse_dt(struct device_node *np, bridge_chip_name = of_get_property(np, "qcom,bridge-name", &len); if (!bridge_chip_name || len <= 0) { - pr_err("%s:%d Unable to read qcom,bridge_name, data=%p,len=%d\n", + pr_err("%s:%d Unable to read qcom,bridge_name, data=%pK,len=%d\n", __func__, __LINE__, bridge_chip_name, len); rc = -EINVAL; goto error; diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 6e28ec73f564..808b3fe8fae9 100644 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -2101,7 +2101,7 @@ int mdss_fb_alloc_fb_ion_memory(struct msm_fb_data_type *mfd, size_t fb_size) rc = PTR_ERR(vaddr); goto err_unmap; } - pr_debug("alloc 0x%zuB vaddr = %p for fb%d\n", fb_size, + pr_debug("alloc 0x%zuB vaddr = %pK for fb%d\n", fb_size, vaddr, mfd->index); mfd->fbi->screen_base = (char *) vaddr; @@ -2200,7 +2200,7 @@ static int mdss_fb_fbmem_ion_mmap(struct fb_info *info, vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - pr_debug("vma=%p, addr=%x len=%ld\n", + pr_debug("vma=%pK, addr=%x len=%ld\n", vma, (unsigned int)addr, len); pr_debug("vm_start=%x vm_end=%x vm_page_prot=%ld\n", (unsigned int)vma->vm_start, @@ -2367,7 +2367,7 @@ static int mdss_fb_alloc_fbmem_iommu(struct msm_fb_data_type *mfd, int dom) return -ERANGE; } - pr_debug("alloc 0x%zxB @ (%pa phys) (0x%p virt) (%pa iova) for fb%d\n", + pr_debug("alloc 0x%zxB @ (%pa phys) (0x%pK virt) (%pa iova) for fb%d\n", size, &phys, virt, &mfd->iova, mfd->index); mfd->fbi->screen_base = virt; @@ -2655,7 +2655,7 @@ static int mdss_fb_open(struct fb_info *info, int user) } mfd->ref_cnt++; - pr_debug("mfd refcount:%d file:%p\n", mfd->ref_cnt, info->file); + pr_debug("mfd refcount:%d file:%pK\n", mfd->ref_cnt, info->file); return 0; @@ -2720,7 +2720,7 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all) pr_warn("file node not found or wrong ref cnt: release all:%d refcnt:%d\n", release_all, mfd->ref_cnt); - pr_debug("current process=%s pid=%d mfd->ref=%d file:%p\n", + pr_debug("current process=%s pid=%d mfd->ref=%d file:%pK\n", task->comm, current->tgid, mfd->ref_cnt, info->file); if (!mfd->ref_cnt || release_all) { diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c index 365bc2639cd5..b5611f45741c 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_tx.c +++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c @@ -1295,7 +1295,7 @@ static int hdmi_tx_sysfs_create(struct hdmi_tx_ctrl *hdmi_ctrl, return rc; } hdmi_ctrl->kobj = &fbi->dev->kobj; - DEV_DBG("%s: sysfs group %p\n", __func__, hdmi_ctrl->kobj); + DEV_DBG("%s: sysfs group %pK\n", __func__, hdmi_ctrl->kobj); return 0; } /* hdmi_tx_sysfs_create */ @@ -3842,7 +3842,7 @@ static int hdmi_tx_init_resource(struct hdmi_tx_ctrl *hdmi_ctrl) DEV_DBG("%s: '%s' remap failed or not available\n", __func__, hdmi_tx_io_name(i)); } - DEV_INFO("%s: '%s': start = 0x%p, len=0x%x\n", __func__, + DEV_INFO("%s: '%s': start = 0x%pK, len=0x%x\n", __func__, hdmi_tx_io_name(i), pdata->io[i].base, pdata->io[i].len); } @@ -4345,7 +4345,7 @@ static int hdmi_tx_get_dt_data(struct platform_device *pdev, data = of_get_property(pdev->dev.of_node, "qcom,display-id", &len); if (!data || len <= 0) - pr_err("%s:%d Unable to read qcom,display-id, data=%p,len=%d\n", + pr_err("%s:%d Unable to read qcom,display-id, data=%pK,len=%d\n", __func__, __LINE__, data, len); else snprintf(hdmi_ctrl->panel_data.panel_info.display_id, diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c index ddb9c61f21d6..52cbebd4287f 100644 --- a/drivers/video/msm/mdss/mdss_mdp.c +++ b/drivers/video/msm/mdss/mdss_mdp.c @@ -599,7 +599,7 @@ struct reg_bus_client *mdss_reg_bus_vote_client_create(char *client_name) strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN); client->usecase_ndx = VOTE_INDEX_DISABLE; client->id = id; - pr_debug("bus vote client %s created:%p id :%d\n", client_name, + pr_debug("bus vote client %s created:%pK id :%d\n", client_name, client, id); id++; list_add(&client->list, &mdss_res->reg_bus_clist); @@ -613,7 +613,7 @@ void mdss_reg_bus_vote_client_destroy(struct reg_bus_client *client) if (!client) { pr_err("reg bus vote: invalid client handle\n"); } else { - pr_debug("bus vote client %s destroyed:%p id:%u\n", + pr_debug("bus vote client %s destroyed:%pK id:%u\n", client->name, client, client->id); mutex_lock(&mdss_res->reg_bus_lock); list_del_init(&client->list); @@ -1978,7 +1978,7 @@ static u32 mdss_mdp_res_init(struct mdss_data_type *mdata) mdata->iclient = msm_ion_client_create(mdata->pdev->name); if (IS_ERR_OR_NULL(mdata->iclient)) { - pr_err("msm_ion_client_create() return error (%p)\n", + pr_err("msm_ion_client_create() return error (%pK)\n", mdata->iclient); mdata->iclient = NULL; } @@ -2587,7 +2587,7 @@ static int mdss_mdp_probe(struct platform_device *pdev) if (rc) pr_debug("unable to map MDSS VBIF non-realtime base\n"); else - pr_debug("MDSS VBIF NRT HW Base addr=%p len=0x%x\n", + pr_debug("MDSS VBIF NRT HW Base addr=%pK len=0x%x\n", mdata->vbif_nrt_io.base, mdata->vbif_nrt_io.len); res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -3403,7 +3403,7 @@ static int mdss_mdp_cdm_addr_setup(struct mdss_data_type *mdata, atomic_set(&head[i].kref.refcount, 0); mutex_init(&head[i].lock); init_completion(&head[i].free_comp); - pr_debug("%s: cdm off (%d) = %p\n", __func__, i, head[i].base); + pr_debug("%s: cdm off (%d) = %pK\n", __func__, i, head[i].base); } mdata->cdm_off = head; @@ -3470,7 +3470,7 @@ static int mdss_mdp_dsc_addr_setup(struct mdss_data_type *mdata, for (i = 0; i < len; i++) { head[i].num = i; head[i].base = (mdata->mdss_io.base) + dsc_offsets[i]; - pr_debug("dsc off (%d) = %p\n", i, head[i].base); + pr_debug("dsc off (%d) = %pK\n", i, head[i].base); } mdata->dsc_off = head; diff --git a/drivers/video/msm/mdss/mdss_mdp_debug.c b/drivers/video/msm/mdss/mdss_mdp_debug.c index 25702b54f91a..7e0fd0f49700 100644 --- a/drivers/video/msm/mdss/mdss_mdp_debug.c +++ b/drivers/video/msm/mdss/mdss_mdp_debug.c @@ -988,7 +988,7 @@ void mdss_mdp_debug_mid(u32 mid) len = get_dump_range(&xlog_node->offset, blk_base->max_offset); addr = blk_base->base + xlog_node->offset.start; - pr_info("%s: mid:%d range_base=0x%p start=0x%x end=0x%x\n", + pr_info("%s: mid:%d range_base=0x%pK start=0x%x end=0x%x\n", xlog_node->range_name, mid, addr, xlog_node->offset.start, xlog_node->offset.end); diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 6b91259f2680..09c4418f1397 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -1889,7 +1889,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), ctl->roi_bkup.w, ctl->roi_bkup.h); - pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__, + pr_debug("%s: intf_num=%d ctx=%pK koff_cnt=%d\n", __func__, ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt)); rc = wait_event_timeout(ctx->pp_waitq, @@ -2141,7 +2141,7 @@ int mdss_mdp_cmd_set_autorefresh_mode(struct mdss_mdp_ctl *mctl, int frame_cnt) struct mdss_panel_info *pinfo; if (!mctl || !mctl->is_master || !mctl->panel_data) { - pr_err("invalid ctl mctl:%p pdata:%p\n", + pr_err("invalid ctl mctl:%pK pdata:%pK\n", mctl, mctl ? mctl->panel_data : 0); return -ENODEV; } @@ -3202,7 +3202,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, ctx->intf_stopped = 0; - pr_debug("%s: ctx=%p num=%d aux=%d\n", __func__, ctx, + pr_debug("%s: ctx=%pK num=%d aux=%d\n", __func__, ctx, default_pp_num, aux_pp_num); MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt)); diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c index 395744902f69..f2741331f877 100644 --- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c @@ -297,7 +297,7 @@ int mdss_mdp_video_addr_setup(struct mdss_data_type *mdata, for (i = 0; i < count; i++) { head[i].base = mdata->mdss_io.base + offsets[i]; - pr_debug("adding Video Intf #%d offset=0x%x virt=%p\n", i, + pr_debug("adding Video Intf #%d offset=0x%x virt=%pK\n", i, offsets[i], head[i].base); head[i].ref_cnt = 0; head[i].intf_num = i + MDSS_MDP_INTF0; @@ -880,7 +880,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, ctx->intf_num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, ctx->intf_num, ctx->base); ret = mdss_mdp_video_ctx_stop(ctl, pinfo, ctx); @@ -898,7 +898,7 @@ static int mdss_mdp_video_intfs_stop(struct mdss_mdp_ctl *ctl, pr_err("Intf %d not in use\n", (inum + MDSS_MDP_INTF0)); return -ENODEV; } - pr_debug("stop ctl=%d video Intf #%d base=%p", ctl->num, + pr_debug("stop ctl=%d video Intf #%d base=%pK", ctl->num, sctx->intf_num, sctx->base); ret = mdss_mdp_video_ctx_stop(ctl, pinfo, sctx); @@ -1923,7 +1923,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; } else { pr_err("Invalid intf number: %d\n", (inum + MDSS_MDP_INTF0)); @@ -1956,7 +1956,7 @@ static int mdss_mdp_video_intfs_setup(struct mdss_mdp_ctl *ctl, (inum + MDSS_MDP_INTF0)); return -EBUSY; } - pr_debug("video Intf #%d base=%p", ctx->intf_num, ctx->base); + pr_debug("video Intf #%d base=%pK", ctx->intf_num, ctx->base); ctx->ref_cnt++; ctl->intf_ctx[SLAVE_CTX] = ctx; diff --git a/drivers/video/msm/mdss/mdss_mdp_layer.c b/drivers/video/msm/mdss/mdss_mdp_layer.c index 271e59319b6d..20e43864af11 100644 --- a/drivers/video/msm/mdss/mdss_mdp_layer.c +++ b/drivers/video/msm/mdss/mdss_mdp_layer.c @@ -476,7 +476,7 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd, mixer = mdss_mdp_mixer_get(mdp5_data->ctl, mixer_mux); pipe->src_fmt = mdss_mdp_get_format_params(layer->buffer.format); if (!pipe->src_fmt || !mixer) { - pr_err("invalid layer format:%d or mixer:%p\n", + pr_err("invalid layer format:%d or mixer:%pK\n", layer->buffer.format, pipe->mixer_left); ret = -EINVAL; goto end; @@ -1910,7 +1910,7 @@ validate_exit: } } else { pipe->file = file; - pr_debug("file pointer attached with pipe is %p\n", + pr_debug("file pointer attached with pipe is %pK\n", file); } } diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c index ac41dd6d96e7..c1772b1a2507 100644 --- a/drivers/video/msm/mdss/mdss_mdp_overlay.c +++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c @@ -1081,7 +1081,7 @@ struct mdss_mdp_data *mdss_mdp_overlay_buf_alloc(struct msm_fb_data_type *mfd, list_move_tail(&buf->buf_list, &mdp5_data->bufs_used); list_add_tail(&buf->pipe_list, &pipe->buf_queue); - pr_debug("buffer alloc: %p\n", buf); + pr_debug("buffer alloc: %pK\n", buf); return buf; } @@ -1135,7 +1135,7 @@ void mdss_mdp_overlay_buf_free(struct msm_fb_data_type *mfd, buf->last_freed = local_clock(); buf->state = MDP_BUF_STATE_UNUSED; - pr_debug("buffer freed: %p\n", buf); + pr_debug("buffer freed: %pK\n", buf); list_move_tail(&buf->buf_list, &mdp5_data->bufs_pool); } @@ -1512,7 +1512,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd) if (buf) { switch (buf->state) { case MDP_BUF_STATE_READY: - pr_debug("pnum=%d buf=%p first buffer ready\n", + pr_debug("pnum=%d buf=%pK first buffer ready\n", pipe->num, buf); break; case MDP_BUF_STATE_ACTIVE: @@ -1532,7 +1532,7 @@ static int __overlay_queue_pipes(struct msm_fb_data_type *mfd) } break; default: - pr_err("invalid state of buf %p=%d\n", + pr_err("invalid state of buf %pK=%d\n", buf, buf->state); BUG(); break; @@ -2233,7 +2233,7 @@ static int __mdss_mdp_overlay_release_all(struct msm_fb_data_type *mfd, u32 unset_ndx = 0; int cnt = 0; - pr_debug("releasing all resources for fb%d file:%p\n", + pr_debug("releasing all resources for fb%d file:%pK\n", mfd->index, file); mutex_lock(&mdp5_data->ov_lock); diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c index 2b16ab5afc7b..b7aba6dc0c8a 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pipe.c +++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c @@ -2728,7 +2728,7 @@ int mdss_mdp_pipe_queue_data(struct mdss_mdp_pipe *pipe, mdss_mdp_pipe_write(pipe, MDSS_MDP_REG_SSPP_MULTI_REC_OP_MODE, multirect_opmode); if (src_data == NULL) { - pr_debug("src_data=%p pipe num=%dx\n", + pr_debug("src_data=%pK pipe num=%dx\n", src_data, pipe->num); goto update_nobuf; } diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c index 0b0d2d9735d7..0b9ecaec694f 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp.c @@ -1158,7 +1158,7 @@ static int pp_rgb_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op) int ret = 0; if (!pipe) { - pr_err("invalid param pipe %p\n", pipe); + pr_err("invalid param pipe %pK\n", pipe); return -EINVAL; } if (pipe->flags & MDP_OVERLAY_PP_CFG_EN && @@ -1176,7 +1176,7 @@ static int pp_dma_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op) int ret = 0; if (!pipe) { - pr_err("invalid param pipe %p\n", pipe); + pr_err("invalid param pipe %pK\n", pipe); return -EINVAL; } if (pipe->flags & MDP_OVERLAY_PP_CFG_EN && @@ -1793,7 +1793,7 @@ void mdss_mdp_pipe_pp_clear(struct mdss_mdp_pipe *pipe) struct pp_hist_col_info *hist_info; if (!pipe) { - pr_err("Invalid pipe context passed, %p\n", + pr_err("Invalid pipe context passed, %pK\n", pipe); return; } @@ -1919,7 +1919,7 @@ static int pp_mixer_setup(struct mdss_mdp_mixer *mixer) struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (!mixer || !mixer->ctl || !mixer->ctl->mfd || !mdata) { - pr_err("invalid parameters, mixer %p ctl %p mfd %p mdata %p\n", + pr_err("invalid parameters, mixer %pK ctl %pK mfd %pK mdata %pK\n", mixer, (mixer ? mixer->ctl : NULL), (mixer ? (mixer->ctl ? mixer->ctl->mfd : NULL) : NULL), mdata); @@ -2566,7 +2566,7 @@ int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd) struct mdp_pa_v2_cfg_data *pa_v2_cache_cfg = NULL; if (!mfd) { - pr_err("invalid input: mfd = 0x%p\n", mfd); + pr_err("invalid input: mfd = 0x%pK\n", mfd); return -EINVAL; } @@ -2656,7 +2656,7 @@ int mdss_mdp_pp_resume(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -2797,7 +2797,7 @@ static int mdss_mdp_pp_dt_parse(struct device *dev) ret = 0; } } else { - pr_err("invalid dev %p mdata %p\n", dev, mdata); + pr_err("invalid dev %pK mdata %pK\n", dev, mdata); ret = -EINVAL; } bail_out: @@ -2931,7 +2931,7 @@ int mdss_mdp_pp_overlay_init(struct msm_fb_data_type *mfd) struct mdss_data_type *mdata = mdss_mdp_get_mdata(); if (!mfd || !mdata) { - pr_err("Invalid mfd %p mdata %p\n", mfd, mdata); + pr_err("Invalid mfd %pK mdata %pK\n", mfd, mdata); return -EPERM; } @@ -2947,7 +2947,7 @@ int mdss_mdp_pp_default_overlay_config(struct msm_fb_data_type *mfd, int ret = 0; if (!mfd || !pdata) { - pr_err("Invalid parameters mfd %p pdata %p\n", mfd, pdata); + pr_err("Invalid parameters mfd %pK pdata %pK\n", mfd, pdata); return -EINVAL; } @@ -3000,7 +3000,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -3019,7 +3019,7 @@ static int pp_ad_calc_bl(struct msm_fb_data_type *mfd, int bl_in, int *bl_out, if (!ad->bl_mfd || !ad->bl_mfd->panel_info || !ad->bl_att_lut) { - pr_err("Invalid ad info: bl_mfd = 0x%p, ad->bl_mfd->panel_info = 0x%p, bl_att_lut = 0x%p\n", + pr_err("Invalid ad info: bl_mfd = 0x%pK, ad->bl_mfd->panel_info = 0x%pK, bl_att_lut = 0x%pK\n", ad->bl_mfd, (!ad->bl_mfd) ? NULL : ad->bl_mfd->panel_info, ad->bl_att_lut); @@ -3511,7 +3511,7 @@ int mdss_mdp_pcc_config(struct msm_fb_data_type *mfd, if (pp_ops[PCC].pp_get_config) { addr = mdss_mdp_get_dspp_addr_off(disp_num); if (IS_ERR_OR_NULL(addr)) { - pr_err("invalid dspp base_addr %p\n", + pr_err("invalid dspp base_addr %pK\n", addr); ret = -EINVAL; goto pcc_clk_off; @@ -4199,7 +4199,7 @@ int mdss_mdp_hist_lut_config(struct msm_fb_data_type *mfd, mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON); base_addr = mdss_mdp_get_dspp_addr_off(dspp_num); if (IS_ERR_OR_NULL(base_addr)) { - pr_err("invalid base addr %p\n", + pr_err("invalid base addr %pK\n", base_addr); ret = -EINVAL; goto hist_lut_clk_off; @@ -4453,7 +4453,7 @@ int mdss_mdp_gamut_config(struct msm_fb_data_type *mfd, if (pp_ops[GAMUT].pp_get_config) { addr = mdss_mdp_get_dspp_addr_off(disp_num); if (IS_ERR_OR_NULL(addr)) { - pr_err("invalid dspp base addr %p\n", + pr_err("invalid dspp base addr %pK\n", addr); ret = -EINVAL; goto gamut_clk_off; @@ -4639,7 +4639,7 @@ static int pp_hist_enable(struct pp_hist_col_info *hist_info, spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_err("%s Hist collection has already been enabled %p\n", + pr_err("%s Hist collection has already been enabled %pK\n", __func__, hist_info->base); ret = -EBUSY; goto exit; @@ -4788,7 +4788,7 @@ static int pp_hist_disable(struct pp_hist_col_info *hist_info) spin_lock_irqsave(&hist_info->hist_lock, flag); if (hist_info->col_en == false) { spin_unlock_irqrestore(&hist_info->hist_lock, flag); - pr_debug("Histogram already disabled (%p)\n", hist_info->base); + pr_debug("Histogram already disabled (%pK)\n", hist_info->base); ret = -EINVAL; goto exit; } @@ -4885,7 +4885,7 @@ int mdss_mdp_hist_intr_req(struct mdss_intr *intr, u32 bits, bool en) unsigned long flag; int ret = 0; if (!intr) { - pr_err("NULL addr passed, %p\n", intr); + pr_err("NULL addr passed, %pK\n", intr); return -EINVAL; } @@ -5449,7 +5449,7 @@ static int mdss_mdp_get_ad(struct msm_fb_data_type *mfd, *ret_ad = NULL; if (!mfd) { - pr_err("invalid parameter mfd %p\n", mfd); + pr_err("invalid parameter mfd %pK\n", mfd); return -EINVAL; } mdata = mfd_to_mdata(mfd); @@ -5496,7 +5496,7 @@ static int pp_ad_invalidate_input(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -5531,7 +5531,7 @@ int mdss_mdp_ad_config(struct msm_fb_data_type *mfd, mfd->index); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -5648,7 +5648,7 @@ int mdss_mdp_ad_input(struct msm_fb_data_type *mfd, mfd->index); return ret; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -6007,7 +6007,7 @@ static int mdss_mdp_ad_ipc_reset(struct msm_fb_data_type *mfd) struct mdss_ad_info *ad; if (!mfd) { - pr_err("mfd = 0x%p\n", mfd); + pr_err("mfd = 0x%pK\n", mfd); return -EINVAL; } @@ -6017,7 +6017,7 @@ static int mdss_mdp_ad_ipc_reset(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -6041,13 +6041,13 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) u32 width; if (!mfd) { - pr_err("mfd = 0x%p\n", mfd); + pr_err("mfd = 0x%pK\n", mfd); return -EINVAL; } ctl = mfd_to_ctl(mfd); if (!ctl) { - pr_err("ctl = 0x%p\n", ctl); + pr_err("ctl = 0x%pK\n", ctl); return -EINVAL; } sctl = mdss_mdp_get_split_ctl(ctl); @@ -6058,7 +6058,7 @@ static int mdss_mdp_ad_setup(struct msm_fb_data_type *mfd) mfd->index); return 0; } else if (ret || !ad) { - pr_err("Failed to get ad info: ret = %d, ad = 0x%p.\n", + pr_err("Failed to get ad info: ret = %d, ad = 0x%pK.\n", ret, ad); return ret; } @@ -6242,7 +6242,7 @@ static void pp_ad_calc_worker(struct work_struct *work) } mdp5_data = mfd_to_mdp5_data(ad->mfd); if (!mdp5_data) { - pr_err("mdp5_data = 0x%p\n", mdp5_data); + pr_err("mdp5_data = 0x%pK\n", mdp5_data); mutex_unlock(&ad->lock); return; } @@ -6250,7 +6250,7 @@ static void pp_ad_calc_worker(struct work_struct *work) ctl = mfd_to_ctl(ad->mfd); mdata = mfd_to_mdata(ad->mfd); if (!ctl || !mdata || ad->calc_hw_num >= mdata->nad_cfgs) { - pr_err("ctl = 0x%p, mdata = 0x%p, ad->calc_hw_num = %d, mdata->nad_cfg = %d\n", + pr_err("ctl = 0x%pK, mdata = 0x%pK, ad->calc_hw_num = %d, mdata->nad_cfg = %d\n", ctl, mdata, ad->calc_hw_num, (!mdata ? 0 : mdata->nad_cfgs)); mutex_unlock(&ad->lock); @@ -6861,7 +6861,7 @@ static int sspp_cache_location(u32 pipe_type, enum pp_config_block *block) int ret = 0; if (!block) { - pr_err("invalid params %p\n", block); + pr_err("invalid params %pK\n", block); return -EINVAL; } switch (pipe_type) { @@ -6890,7 +6890,7 @@ int mdss_mdp_pp_sspp_config(struct mdss_mdp_pipe *pipe) int ret = 0; if (!pipe) { - pr_err("invalid params, pipe %p\n", pipe); + pr_err("invalid params, pipe %pK\n", pipe); return -EINVAL; } @@ -7012,7 +7012,7 @@ static int pp_update_pcc_pipe_setup(struct mdss_mdp_pipe *pipe, u32 location) char __iomem *pipe_base = NULL; if (!pipe) { - pr_err("invalid param pipe %p\n", pipe); + pr_err("invalid param pipe %pK\n", pipe); return -EINVAL; } @@ -7064,7 +7064,7 @@ int mdss_mdp_pp_get_version(struct mdp_pp_feature_version *version) u32 ver_info = mdp_pp_legacy; if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); ret = -EINVAL; goto exit_version; } @@ -7145,7 +7145,7 @@ int mdss_mdp_copy_layer_pp_info(struct mdp_input_layer *layer) uint32_t ops; if (!layer) { - pr_err("invalid layer pointer passed %p\n", layer); + pr_err("invalid layer pointer passed %pK\n", layer); return -EFAULT; } @@ -7157,7 +7157,7 @@ int mdss_mdp_copy_layer_pp_info(struct mdp_input_layer *layer) ret = copy_from_user(pp_info, layer->pp_info, sizeof(struct mdp_overlay_pp_params)); if (ret) { - pr_err("layer list copy from user failed, pp_info = %p\n", + pr_err("layer list copy from user failed, pp_info = %pK\n", layer->pp_info); ret = -EFAULT; goto exit_pp_info; @@ -7290,7 +7290,7 @@ static int pp_mfd_ad_release_all(struct msm_fb_data_type *mfd) int ret = 0; if (!mdata || !mfd) { - pr_err("invalid params mdata %p mfd %p\n", mdata, mfd); + pr_err("invalid params mdata %pK mfd %pK\n", mdata, mfd); return -EINVAL; } if (!mdata->ad_calc_wq) @@ -7398,7 +7398,7 @@ static int pp_ppb_setup(struct mdss_mdp_mixer *mixer) int ret = 0; if (!mixer || !mixer->ctl || !mixer->ctl->mfd) { - pr_err("invalid parameters, mixer %p ctl %p mfd %p\n", + pr_err("invalid parameters, mixer %pK ctl %pK mfd %pK\n", mixer, (mixer ? mixer->ctl : NULL), (mixer ? (mixer->ctl ? mixer->ctl->mfd : NULL) : NULL)); return -EINVAL; diff --git a/drivers/video/msm/mdss/mdss_mdp_pp_cache_config.c b/drivers/video/msm/mdss/mdss_mdp_pp_cache_config.c index d1b3f1a89812..ab178ae45cf8 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp_cache_config.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp_cache_config.c @@ -103,7 +103,7 @@ static int pp_hist_lut_cache_params_v1_7(struct mdp_hist_lut_data *config, int ret = 0; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -113,7 +113,7 @@ static int pp_hist_lut_cache_params_v1_7(struct mdp_hist_lut_data *config, return -EINVAL; } if (!mdss_pp_res->pp_data_v1_7) { - pr_err("invalid pp_data_v1_7 %p\n", mdss_pp_res->pp_data_v1_7); + pr_err("invalid pp_data_v1_7 %pK\n", mdss_pp_res->pp_data_v1_7); return -EINVAL; } @@ -165,7 +165,7 @@ static int pp_hist_lut_cache_params_pipe_v1_7(struct mdp_hist_lut_data *config, int ret = 0; if (!config || !pipe) { - pr_err("Invalid param config %p pipe %p\n", + pr_err("Invalid param config %pK pipe %pK\n", config, pipe); return -EINVAL; } @@ -236,7 +236,7 @@ int pp_hist_lut_cache_params(struct mdp_hist_lut_data *config, int ret = 0; if (!config || !res_cache) { - pr_err("invalid param config %p res_cache %p\n", + pr_err("invalid param config %pK res_cache %pK\n", config, res_cache); return -EINVAL; } @@ -245,7 +245,7 @@ int pp_hist_lut_cache_params(struct mdp_hist_lut_data *config, return -EINVAL; } if (!res_cache->mdss_pp_res && !res_cache->pipe_res) { - pr_err("NULL payload for block %d mdss_pp_res %p pipe_res %p\n", + pr_err("NULL payload for block %d mdss_pp_res %pK pipe_res %pK\n", res_cache->block, res_cache->mdss_pp_res, res_cache->pipe_res); return -EINVAL; @@ -286,7 +286,7 @@ int pp_dither_cache_params_v1_7(struct mdp_dither_cfg_data *config, struct mdp_dither_data_v1_7 *v17_cache_data = NULL, v17_usr_config; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -296,7 +296,7 @@ int pp_dither_cache_params_v1_7(struct mdp_dither_cfg_data *config, return -EINVAL; } if (!mdss_pp_res->pp_data_v1_7) { - pr_err("invalid pp_data_v1_7 %p\n", mdss_pp_res->pp_data_v1_7); + pr_err("invalid pp_data_v1_7 %pK\n", mdss_pp_res->pp_data_v1_7); return -EINVAL; } @@ -358,7 +358,7 @@ int pp_dither_cache_params(struct mdp_dither_cfg_data *config, { int ret = 0; if (!config || !mdss_pp_res) { - pr_err("invalid param config %pi pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -387,7 +387,7 @@ static int pp_gamut_cache_params_v1_7(struct mdp_gamut_cfg_data *config, int ret = 0, i = 0; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -398,7 +398,7 @@ static int pp_gamut_cache_params_v1_7(struct mdp_gamut_cfg_data *config, return -EINVAL; } if (!mdss_pp_res->pp_data_v1_7) { - pr_err("invalid pp_data_v1_7 %p\n", mdss_pp_res->pp_data_v1_7); + pr_err("invalid pp_data_v1_7 %pK\n", mdss_pp_res->pp_data_v1_7); return -EINVAL; } res_cache = mdss_pp_res->pp_data_v1_7; @@ -555,7 +555,7 @@ int pp_gamut_cache_params(struct mdp_gamut_cfg_data *config, { int ret = 0; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -578,7 +578,7 @@ static int pp_pcc_cache_params_pipe_v1_7(struct mdp_pcc_cfg_data *config, struct mdp_pcc_data_v1_7 *v17_cache_data = NULL, v17_usr_config; if (!pipe || !config) { - pr_err("invalid params pipe %p config %p\n", pipe, config); + pr_err("invalid params pipe %pK config %pK\n", pipe, config); return -EINVAL; } @@ -636,7 +636,7 @@ static int pp_pcc_cache_params_v1_7(struct mdp_pcc_cfg_data *config, struct mdp_pcc_data_v1_7 *v17_cache_data, v17_usr_config; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -647,7 +647,7 @@ static int pp_pcc_cache_params_v1_7(struct mdp_pcc_cfg_data *config, return -EINVAL; } if (!mdss_pp_res->pp_data_v1_7) { - pr_err("invalid pp_data_v1_7 %p\n", mdss_pp_res->pp_data_v1_7); + pr_err("invalid pp_data_v1_7 %pK\n", mdss_pp_res->pp_data_v1_7); return -EINVAL; } @@ -687,7 +687,7 @@ int pp_pcc_cache_params(struct mdp_pcc_cfg_data *config, { int ret = 0; if (!config || !res_cache) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, res_cache); return -EINVAL; } @@ -696,7 +696,7 @@ int pp_pcc_cache_params(struct mdp_pcc_cfg_data *config, return -EINVAL; } if (!res_cache->mdss_pp_res && !res_cache->pipe_res) { - pr_err("NULL payload for block %d mdss_pp_res %p pipe_res %p\n", + pr_err("NULL payload for block %d mdss_pp_res %pK pipe_res %pK\n", res_cache->block, res_cache->mdss_pp_res, res_cache->pipe_res); return -EINVAL; @@ -735,7 +735,7 @@ static int pp_igc_lut_cache_params_v1_7(struct mdp_igc_lut_data *config, struct mdp_igc_lut_data_v1_7 *v17_cache_data, v17_usr_config; u32 disp_num; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -745,7 +745,7 @@ static int pp_igc_lut_cache_params_v1_7(struct mdp_igc_lut_data *config, return -EINVAL; } if (!mdss_pp_res->pp_data_v1_7) { - pr_err("invalid pp_data_v1_7 %p\n", mdss_pp_res->pp_data_v1_7); + pr_err("invalid pp_data_v1_7 %pK\n", mdss_pp_res->pp_data_v1_7); return -EINVAL; } res_cache = mdss_pp_res->pp_data_v1_7; @@ -781,7 +781,7 @@ static int pp_igc_lut_cache_params_v1_7(struct mdp_igc_lut_data *config, } if (copy_from_kernel && (!v17_usr_config.c0_c1_data || !v17_usr_config.c2_data)) { - pr_err("copy from kernel invalid params c0_c1_data %p c2_data %p\n", + pr_err("copy from kernel invalid params c0_c1_data %pK c2_data %pK\n", v17_usr_config.c0_c1_data, v17_usr_config.c2_data); ret = -EINVAL; @@ -837,7 +837,7 @@ static int pp_igc_lut_cache_params_pipe_v1_7(struct mdp_igc_lut_data *config, struct mdp_igc_lut_data_v1_7 *v17_cache_data = NULL, v17_usr_config; int ret = 0, fix_up = 0, i = 0; if (!config || !pipe) { - pr_err("invalid param config %p pipe %p\n", + pr_err("invalid param config %pK pipe %pK\n", config, pipe); return -EINVAL; } @@ -865,7 +865,7 @@ static int pp_igc_lut_cache_params_pipe_v1_7(struct mdp_igc_lut_data *config, if (!v17_usr_config.c0_c1_data || !v17_usr_config.c2_data || v17_usr_config.len != IGC_LUT_ENTRIES) { - pr_err("invalid c0_c1data %p c2_data %p tbl len %d\n", + pr_err("invalid c0_c1data %pK c2_data %pK tbl len %d\n", v17_usr_config.c0_c1_data, v17_usr_config.c2_data, v17_usr_config.len); @@ -959,7 +959,7 @@ int pp_igc_lut_cache_params(struct mdp_igc_lut_data *config, { int ret = 0; if (!config || !res_cache) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, res_cache); return -EINVAL; } @@ -968,7 +968,7 @@ int pp_igc_lut_cache_params(struct mdp_igc_lut_data *config, return -EINVAL; } if (!res_cache->mdss_pp_res && !res_cache->pipe_res) { - pr_err("NULL payload for block %d mdss_pp_res %p pipe_res %p\n", + pr_err("NULL payload for block %d mdss_pp_res %pK pipe_res %pK\n", res_cache->block, res_cache->mdss_pp_res, res_cache->pipe_res); ret = -EINVAL; @@ -1103,7 +1103,7 @@ int pp_pgc_lut_cache_params(struct mdp_pgc_lut_data *config, { int ret = 0; if (!config || !mdss_pp_res) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -1128,7 +1128,7 @@ static int pp_pa_cache_params_v1_7(struct mdp_pa_v2_cfg_data *config, int disp_num, ret = 0; if (!config || !mdss_pp_res) { - pr_err("Invalid param config %p pp_res %p\n", + pr_err("Invalid param config %pK pp_res %pK\n", config, mdss_pp_res); return -EINVAL; } @@ -1140,7 +1140,7 @@ static int pp_pa_cache_params_v1_7(struct mdp_pa_v2_cfg_data *config, } if (!mdss_pp_res->pp_data_v1_7) { - pr_err("Invalid pp_data_v1_7 %p\n", mdss_pp_res->pp_data_v1_7); + pr_err("Invalid pp_data_v1_7 %pK\n", mdss_pp_res->pp_data_v1_7); return -EINVAL; } @@ -1228,7 +1228,7 @@ static int pp_pa_cache_params_pipe_v1_7(struct mdp_pa_v2_cfg_data *config, int ret = 0; if (!config || !pipe) { - pr_err("Invalid param config %p pipe %p\n", + pr_err("Invalid param config %pK pipe %pK\n", config, pipe); return -EINVAL; } @@ -1284,7 +1284,7 @@ int pp_pa_cache_params(struct mdp_pa_v2_cfg_data *config, { int ret = 0; if (!config || !res_cache) { - pr_err("invalid param config %p pp_res %p\n", + pr_err("invalid param config %pK pp_res %pK\n", config, res_cache); return -EINVAL; } @@ -1293,7 +1293,7 @@ int pp_pa_cache_params(struct mdp_pa_v2_cfg_data *config, return -EINVAL; } if (!res_cache->mdss_pp_res && !res_cache->pipe_res) { - pr_err("NULL payload for block %d mdss_pp_res %p pipe_res %p\n", + pr_err("NULL payload for block %d mdss_pp_res %pK pipe_res %pK\n", res_cache->block, res_cache->mdss_pp_res, res_cache->pipe_res); return -EINVAL; @@ -1344,7 +1344,7 @@ int pp_copy_layer_igc_payload(struct mdp_overlay_pp_params *pp_info) pp_info->igc_cfg.cfg_payload, sizeof(struct mdp_igc_lut_data_v1_7)); if (ret) { - pr_err("layer list copy from user failed, IGC cfg payload = %p\n", + pr_err("layer list copy from user failed, IGC cfg payload = %pK\n", pp_info->igc_cfg.cfg_payload); ret = -EFAULT; kfree(cfg_payload); @@ -1382,7 +1382,7 @@ int pp_copy_layer_hist_lut_payload(struct mdp_overlay_pp_params *pp_info) pp_info->hist_lut_cfg.cfg_payload, sizeof(struct mdp_hist_lut_data_v1_7)); if (ret) { - pr_err("layer list copy from user failed, Hist LUT cfg payload = %p\n", + pr_err("layer list copy from user failed, Hist LUT cfg payload = %pK\n", pp_info->hist_lut_cfg.cfg_payload); ret = -EFAULT; kfree(cfg_payload); @@ -1420,7 +1420,7 @@ int pp_copy_layer_pa_payload(struct mdp_overlay_pp_params *pp_info) pp_info->pa_v2_cfg_data.cfg_payload, sizeof(struct mdp_pa_data_v1_7)); if (ret) { - pr_err("layer list copy from user failed, PA cfg payload = %p\n", + pr_err("layer list copy from user failed, PA cfg payload = %pK\n", pp_info->pa_v2_cfg_data.cfg_payload); ret = -EFAULT; kfree(cfg_payload); @@ -1458,7 +1458,7 @@ int pp_copy_layer_pcc_payload(struct mdp_overlay_pp_params *pp_info) pp_info->pcc_cfg_data.cfg_payload, sizeof(struct mdp_pcc_data_v1_7)); if (ret) { - pr_err("layer list copy from user failed, PCC cfg payload = %p\n", + pr_err("layer list copy from user failed, PCC cfg payload = %pK\n", pp_info->pcc_cfg_data.cfg_payload); ret = -EFAULT; kfree(cfg_payload); diff --git a/drivers/video/msm/mdss/mdss_mdp_pp_common.c b/drivers/video/msm/mdss/mdss_mdp_pp_common.c index 7742b5e4ad0c..f3eccfe957f7 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp_common.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp_common.c @@ -20,7 +20,7 @@ void pp_pa_set_sts(struct pp_sts_type *pp_sts, int enable_flag, int block_type) { if (!pp_sts) { - pr_err("invalid input pp_sts %p\n", pp_sts); + pr_err("invalid input pp_sts %pK\n", pp_sts); return; } @@ -34,7 +34,7 @@ void pp_pa_set_sts(struct pp_sts_type *pp_sts, } if (!pa_data) { - pr_err("invalid input pa_data %p\n", pa_data); + pr_err("invalid input pa_data %pK\n", pa_data); return; } diff --git a/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c b/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c index 1470915a1253..1e4adc984802 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp_v1_7.c @@ -246,7 +246,7 @@ static void pp_gamut_clock_gating_en(char __iomem *base_addr); void *pp_get_driver_ops_v1_7(struct mdp_pp_driver_ops *ops) { if (!ops) { - pr_err("PP driver ops invalid %p\n", ops); + pr_err("PP driver ops invalid %pK\n", ops); return ERR_PTR(-EINVAL); } @@ -308,7 +308,7 @@ static void pp_opmode_config(int location, struct pp_sts_type *pp_sts, u32 *opmode, int side) { if (!pp_sts || !opmode) { - pr_err("Invalid pp_sts %p or opmode %p\n", pp_sts, opmode); + pr_err("Invalid pp_sts %pK or opmode %pK\n", pp_sts, opmode); return; } switch (location) { @@ -362,7 +362,7 @@ static int pp_hist_lut_get_config(char __iomem *base_addr, void *cfg_data, struct mdp_hist_lut_data *lut_cfg_data = NULL; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -374,7 +374,7 @@ static int pp_hist_lut_get_config(char __iomem *base_addr, void *cfg_data, } if (lut_cfg_data->version != mdp_hist_lut_v1_7 || !lut_cfg_data->cfg_payload) { - pr_err("invalid hist_lut version %d payload %p\n", + pr_err("invalid hist_lut version %d payload %pK\n", lut_cfg_data->version, lut_cfg_data->cfg_payload); return -EINVAL; } @@ -439,7 +439,7 @@ static int pp_hist_lut_set_config(char __iomem *base_addr, char __iomem *hist_addr = NULL, *swap_addr = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -465,12 +465,12 @@ static int pp_hist_lut_set_config(char __iomem *base_addr, } lut_data = lut_cfg_data->cfg_payload; if (!lut_data) { - pr_err("invalid hist_lut cfg_payload %p\n", lut_data); + pr_err("invalid hist_lut cfg_payload %pK\n", lut_data); return -EINVAL; } if (lut_data->len != ENHIST_LUT_ENTRIES || !lut_data->data) { - pr_err("invalid hist_lut len %d data %p\n", + pr_err("invalid hist_lut len %d data %pK\n", lut_data->len, lut_data->data); return -EINVAL; } @@ -535,7 +535,7 @@ static int pp_dither_set_config(char __iomem *base_addr, uint32_t *pdata = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -563,7 +563,7 @@ static int pp_dither_set_config(char __iomem *base_addr, dither_data = dither_cfg_data->cfg_payload; if (!dither_data) { - pr_err("invalid payload for dither %p\n", dither_data); + pr_err("invalid payload for dither %pK\n", dither_data); return -EINVAL; } @@ -611,7 +611,7 @@ static int pp_hist_get_config(char __iomem *base_addr, void *cfg_data, struct pp_hist_col_info *hist_info = NULL; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -649,7 +649,7 @@ static int pp_get_hist_offset(u32 block, u32 *ctl_off) int ret = 0; if (!ctl_off) { - pr_err("invalid params ctl_off %p\n", ctl_off); + pr_err("invalid params ctl_off %pK\n", ctl_off); return -EINVAL; } switch (block) { @@ -670,7 +670,7 @@ static int pp_get_hist_offset(u32 block, u32 *ctl_off) static int pp_get_hist_isr(u32 *isr_mask) { if (!isr_mask) { - pr_err("invalid params isr_mask %p\n", isr_mask); + pr_err("invalid params isr_mask %pK\n", isr_mask); return -EINVAL; } @@ -696,7 +696,7 @@ static int pp_gamut_get_config(char __iomem *base_addr, void *cfg_data, u32 clk_gate_disable = 0; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -834,7 +834,7 @@ static int pp_gamut_set_config(char __iomem *base_addr, struct mdp_gamut_data_v1_7 *gamut_data = NULL; char __iomem *base_addr_scale = base_addr; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -856,7 +856,7 @@ static int pp_gamut_set_config(char __iomem *base_addr, gamut_data = (struct mdp_gamut_data_v1_7 *) gamut_cfg_data->cfg_payload; if (!gamut_data) { - pr_err("invalid payload for gamut %p\n", gamut_data); + pr_err("invalid payload for gamut %pK\n", gamut_data); return -EINVAL; } @@ -875,7 +875,7 @@ static int pp_gamut_set_config(char __iomem *base_addr, for (i = 0; i < MDP_GAMUT_TABLE_NUM_V1_7; i++) { if (!gamut_data->c0_data[i] || !gamut_data->c1_c2_data[i] || (gamut_data->tbl_size[i] != tbl_sz)) { - pr_err("invalid param for c0 %p c1c2 %p table %d size %d expected sz %d\n", + pr_err("invalid param for c0 %pK c1c2 %pK table %d size %d expected sz %d\n", gamut_data->c0_data[i], gamut_data->c1_c2_data[i], i, gamut_data->tbl_size[i], tbl_sz); @@ -886,7 +886,7 @@ static int pp_gamut_set_config(char __iomem *base_addr, (!gamut_data->scale_off_data[i] || (gamut_data->tbl_scale_off_sz[i] != MDP_GAMUT_SCALE_OFF_SZ))) { - pr_err("invalid param for scale table %p for c%d size %d expected size%d\n", + pr_err("invalid param for scale table %pK for c%d size %d expected size%d\n", gamut_data->scale_off_data[i], i, gamut_data->tbl_scale_off_sz[i], MDP_GAMUT_SCALE_OFF_SZ); @@ -951,7 +951,7 @@ static int pp_pcc_set_config(char __iomem *base_addr, u32 opmode = 0; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -966,7 +966,7 @@ static int pp_pcc_set_config(char __iomem *base_addr, } pcc_data = pcc_cfg_data->cfg_payload; if (!pcc_data) { - pr_err("invalid payload for pcc %p\n", pcc_data); + pr_err("invalid payload for pcc %pK\n", pcc_data); return -EINVAL; } @@ -1036,7 +1036,7 @@ static int pp_pcc_get_config(char __iomem *base_addr, void *cfg_data, struct mdp_pcc_data_v1_7 pcc_data; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -1233,7 +1233,7 @@ static void pp_pa_set_six_zone(char __iomem *base_addr, if (!pa_data->six_zone_len || !pa_data->six_zone_curve_p0 || !pa_data->six_zone_curve_p1) { - pr_err("Invalid six zone data: len %d curve_p0 %p curve_p1 %p\n", + pr_err("Invalid six zone data: len %d curve_p0 %pK curve_p1 %pK\n", pa_data->six_zone_len, pa_data->six_zone_curve_p0, pa_data->six_zone_curve_p1); @@ -1283,7 +1283,7 @@ static int pp_pa_set_config(char __iomem *base_addr, int ret = 0; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -1308,7 +1308,7 @@ static int pp_pa_set_config(char __iomem *base_addr, pa_data = pa_cfg_data->cfg_payload; if (!pa_data) { - pr_err("invalid payload for pa %p\n", pa_data); + pr_err("invalid payload for pa %pK\n", pa_data); return -EINVAL; } @@ -1557,7 +1557,7 @@ static int pp_pa_get_config(char __iomem *base_addr, void *cfg_data, char __iomem *pa_hold_addr = NULL; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -1690,7 +1690,7 @@ static int pp_igc_set_config(char __iomem *base_addr, u32 data; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -1698,7 +1698,7 @@ static int pp_igc_set_config(char __iomem *base_addr, lut_cfg_data = (struct mdp_igc_lut_data *) cfg_data; if (lut_cfg_data->version != mdp_igc_v1_7 || !lut_cfg_data->cfg_payload) { - pr_err_once("invalid igc version %d payload %p\n", + pr_err_once("invalid igc version %d payload %pK\n", lut_cfg_data->version, lut_cfg_data->cfg_payload); return -EINVAL; } @@ -1717,7 +1717,7 @@ static int pp_igc_set_config(char __iomem *base_addr, lut_data = lut_cfg_data->cfg_payload; if (lut_data->len != IGC_LUT_ENTRIES || !lut_data->c0_c1_data || !lut_data->c2_data) { - pr_err("invalid lut len %d c0_c1_data %p c2_data %p\n", + pr_err("invalid lut len %d c0_c1_data %pK c2_data %pK\n", lut_data->len, lut_data->c0_c1_data, lut_data->c2_data); return -EINVAL; } @@ -1784,7 +1784,7 @@ static int pp_igc_get_config(char __iomem *base_addr, void *cfg_data, u32 data = 0, sz = 0; if (!base_addr || !cfg_data || block_type != DSPP) { - pr_err("invalid params base_addr %p cfg_data %p block_type %d\n", + pr_err("invalid params base_addr %pK cfg_data %pK block_type %d\n", base_addr, cfg_data, block_type); return -EINVAL; } @@ -1796,7 +1796,7 @@ static int pp_igc_get_config(char __iomem *base_addr, void *cfg_data, if (lut_cfg_data->version != mdp_igc_v1_7 || !lut_cfg_data->cfg_payload || lut_cfg_data->block > IGC_MASK_MAX) { - pr_err("invalid igc version %d payload %p block %d\n", + pr_err("invalid igc version %d payload %pK block %d\n", lut_cfg_data->version, lut_cfg_data->cfg_payload, lut_cfg_data->block); ret = -EINVAL; @@ -1861,7 +1861,7 @@ static int pp_pgc_set_config(char __iomem *base_addr, struct mdp_pgc_lut_data_v1_7 *pgc_data_v17 = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -1887,13 +1887,13 @@ static int pp_pgc_set_config(char __iomem *base_addr, pgc_data_v17 = (struct mdp_pgc_lut_data_v1_7 *) pgc_data->cfg_payload; if (!pgc_data_v17) { - pr_err("invalid payload for GC %p\n", pgc_data_v17); + pr_err("invalid payload for GC %pK\n", pgc_data_v17); return -EINVAL; } if (pgc_data_v17->len != PGC_LUT_ENTRIES || !pgc_data_v17->c0_data || !pgc_data_v17->c1_data || !pgc_data_v17->c2_data) { - pr_err("Invalid params entries %d c0_data %p c1_data %p c2_data %p\n", + pr_err("Invalid params entries %d c0_data %pK c1_data %pK c2_data %pK\n", pgc_data_v17->len, pgc_data_v17->c0_data, pgc_data_v17->c1_data, pgc_data_v17->c2_data); return -EINVAL; @@ -1948,7 +1948,7 @@ static int pp_pgc_get_config(char __iomem *base_addr, void *cfg_data, struct mdp_pgc_lut_data *pgc_data = NULL; struct mdp_pgc_lut_data_v1_7 *pgc_data_v17 = NULL; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p block_type %d\n", + pr_err("invalid params base_addr %pK cfg_data %pK block_type %d\n", base_addr, cfg_data, block_type); return -EINVAL; } @@ -1956,7 +1956,7 @@ static int pp_pgc_get_config(char __iomem *base_addr, void *cfg_data, pgc_data_v17 = (struct mdp_pgc_lut_data_v1_7 *) pgc_data->cfg_payload; if (pgc_data->version != mdp_pgc_v1_7 || !pgc_data_v17) { - pr_err("invalid pgc version %d payload %p\n", + pr_err("invalid pgc version %d payload %pK\n", pgc_data->version, pgc_data_v17); return -EINVAL; } @@ -2018,7 +2018,7 @@ static int pp_pgc_get_config(char __iomem *base_addr, void *cfg_data, static int pp_pcc_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_pcc_v1_7; @@ -2028,7 +2028,7 @@ static int pp_pcc_get_version(u32 *version) static int pp_igc_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_igc_v1_7; @@ -2038,7 +2038,7 @@ static int pp_igc_get_version(u32 *version) static int pp_pgc_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_pgc_v1_7; @@ -2048,7 +2048,7 @@ static int pp_pgc_get_version(u32 *version) static int pp_pa_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_pa_v1_7; @@ -2058,7 +2058,7 @@ static int pp_pa_get_version(u32 *version) static int pp_gamut_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_gamut_v1_7; @@ -2068,7 +2068,7 @@ static int pp_gamut_get_version(u32 *version) static int pp_dither_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_dither_v1_7; @@ -2078,7 +2078,7 @@ static int pp_dither_get_version(u32 *version) static int pp_hist_lut_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_hist_lut_v1_7; diff --git a/drivers/video/msm/mdss/mdss_mdp_pp_v3.c b/drivers/video/msm/mdss/mdss_mdp_pp_v3.c index 4920c5387e2c..ce915e919caa 100644 --- a/drivers/video/msm/mdss/mdss_mdp_pp_v3.c +++ b/drivers/video/msm/mdss/mdss_mdp_pp_v3.c @@ -117,7 +117,7 @@ void *pp_get_driver_ops_v3(struct mdp_pp_driver_ops *ops) void *pp_cfg = NULL; if (!ops) { - pr_err("PP driver ops invalid %p\n", ops); + pr_err("PP driver ops invalid %pK\n", ops); return ERR_PTR(-EINVAL); } @@ -158,7 +158,7 @@ static int pp_get_hist_offset(u32 block, u32 *ctl_off) int ret = 0; if (!ctl_off) { - pr_err("invalid params ctl_off %p\n", ctl_off); + pr_err("invalid params ctl_off %pK\n", ctl_off); return -EINVAL; } @@ -184,7 +184,7 @@ static int pp_hist_set_config(char __iomem *base_addr, struct pp_hist_col_info *hist_info = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -220,7 +220,7 @@ static int pp_hist_get_config(char __iomem *base_addr, void *cfg_data, char __iomem *hist_addr; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -253,7 +253,7 @@ static int pp_hist_lut_get_config(char __iomem *base_addr, void *cfg_data, struct mdp_hist_lut_data *lut_cfg_data = NULL; if (!base_addr || !cfg_data) { - pr_err("invalid params base_addr %p cfg_data %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK\n", base_addr, cfg_data); return -EINVAL; } @@ -270,7 +270,7 @@ static int pp_hist_lut_get_config(char __iomem *base_addr, void *cfg_data, } if (lut_cfg_data->version != mdp_hist_lut_v1_7 || !lut_cfg_data->cfg_payload) { - pr_err("invalid hist_lut version %d payload %p\n", + pr_err("invalid hist_lut version %d payload %pK\n", lut_cfg_data->version, lut_cfg_data->cfg_payload); return -EINVAL; } @@ -317,7 +317,7 @@ static int pp_hist_lut_set_config(char __iomem *base_addr, char __iomem *hist_lut_addr = NULL, *swap_addr = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -344,12 +344,12 @@ static int pp_hist_lut_set_config(char __iomem *base_addr, } lut_data = lut_cfg_data->cfg_payload; if (!lut_data) { - pr_err("invalid hist_lut cfg_payload %p\n", lut_data); + pr_err("invalid hist_lut cfg_payload %pK\n", lut_data); return -EINVAL; } if (lut_data->len != ENHIST_LUT_ENTRIES || !lut_data->data) { - pr_err("invalid hist_lut len %d data %p\n", + pr_err("invalid hist_lut len %d data %pK\n", lut_data->len, lut_data->data); return -EINVAL; } @@ -386,7 +386,7 @@ hist_lut_set_sts: static int pp_hist_lut_get_version(u32 *version) { if (!version) { - pr_err("invalid param version %p\n", version); + pr_err("invalid param version %pK\n", version); return -EINVAL; } *version = mdp_hist_lut_v1_7; @@ -399,7 +399,7 @@ static void pp_hist_lut_opmode_config(char __iomem *base_addr, u32 opmode = 0; if (!base_addr || !pp_sts) { - pr_err("invalid params base_addr %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK pp_sts_type %pK\n", base_addr, pp_sts); return; } @@ -428,7 +428,7 @@ static int pp_pa_set_config(char __iomem *base_addr, char __iomem *block_addr = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -459,7 +459,7 @@ static int pp_pa_set_config(char __iomem *base_addr, pa_data = pa_cfg_data->cfg_payload; if (!pa_data) { - pr_err("invalid payload for pa %p\n", pa_data); + pr_err("invalid payload for pa %pK\n", pa_data); return -EINVAL; } @@ -508,7 +508,7 @@ static int pp_dither_set_config(char __iomem *base_addr, char __iomem *dither_opmode = NULL; if (!base_addr || !cfg_data || !pp_sts) { - pr_err("invalid params base_addr %p cfg_data %p pp_sts_type %p\n", + pr_err("invalid params base_addr %pK cfg_data %pK pp_sts_type %pK\n", base_addr, cfg_data, pp_sts); return -EINVAL; } @@ -537,7 +537,7 @@ static int pp_dither_set_config(char __iomem *base_addr, dither_data = dither_cfg_data->cfg_payload; if (!dither_data) { - pr_err("invalid payload for dither %p\n", dither_data); + pr_err("invalid payload for dither %pK\n", dither_data); return -EINVAL; } @@ -592,7 +592,7 @@ static void pp_opmode_config(int location, struct pp_sts_type *pp_sts, u32 *opmode, int side) { if (!pp_sts || !opmode) { - pr_err("Invalid pp_sts %p or opmode %p\n", pp_sts, opmode); + pr_err("Invalid pp_sts %pK or opmode %pK\n", pp_sts, opmode); return; } switch (location) { @@ -726,7 +726,7 @@ static void pp_pa_set_six_zone(char __iomem *base_addr, if (pa_data->six_zone_len != MDP_SIX_ZONE_LUT_SIZE || !pa_data->six_zone_curve_p0 || !pa_data->six_zone_curve_p1) { - pr_err("Invalid six zone data: len %d curve_p0 %p curve_p1 %p\n", + pr_err("Invalid six zone data: len %d curve_p0 %pK curve_p1 %pK\n", pa_data->six_zone_len, pa_data->six_zone_curve_p0, pa_data->six_zone_curve_p1); diff --git a/drivers/video/msm/mdss/mdss_mdp_util.c b/drivers/video/msm/mdss/mdss_mdp_util.c index 8b659d6a0b6e..83330e1d4f15 100644 --- a/drivers/video/msm/mdss/mdss_mdp_util.c +++ b/drivers/video/msm/mdss/mdss_mdp_util.c @@ -931,7 +931,7 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator, pr_debug("pmem buf=0x%pa\n", &data->addr); memset(&data->srcp_f, 0, sizeof(struct fd)); } else if (!IS_ERR_OR_NULL(data->srcp_dma_buf)) { - pr_debug("ion hdl=%p buf=0x%pa\n", data->srcp_dma_buf, + pr_debug("ion hdl=%pK buf=0x%pa\n", data->srcp_dma_buf, &data->addr); if (!iclient) { pr_err("invalid ion client\n"); @@ -1096,7 +1096,7 @@ static int mdss_mdp_get_img(struct msmfb_data *img, data->addr += data->offset; data->len -= data->offset; - pr_debug("mem=%d ihdl=%p buf=0x%pa len=0x%lx\n", img->memory_id, + pr_debug("mem=%d ihdl=%pK buf=0x%pa len=0x%lx\n", img->memory_id, data->srcp_dma_buf, &data->addr, data->len); } else { mdss_mdp_put_img(data, rotator, dir); @@ -1161,7 +1161,7 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data, bool rotator, data->addr += data->offset; data->len -= data->offset; - pr_debug("ihdl=%p buf=0x%pa len=0x%lx\n", + pr_debug("ihdl=%pK buf=0x%pa len=0x%lx\n", data->srcp_dma_buf, &data->addr, data->len); } else { mdss_mdp_put_img(data, rotator, dir); diff --git a/drivers/video/msm/mdss/mdss_util.c b/drivers/video/msm/mdss/mdss_util.c index db318de6fc6d..d2610ff80878 100644 --- a/drivers/video/msm/mdss/mdss_util.c +++ b/drivers/video/msm/mdss/mdss_util.c @@ -33,7 +33,7 @@ int mdss_register_irq(struct mdss_hw *hw) if (!mdss_irq_handlers[hw->hw_ndx]) mdss_irq_handlers[hw->hw_ndx] = hw; else - pr_err("panel %d's irq at %p is already registered\n", + pr_err("panel %d's irq at %pK is already registered\n", hw->hw_ndx, hw->irq_handler); spin_unlock_irqrestore(&mdss_lock, irq_flags); diff --git a/drivers/video/msm/mdss/mhl3/mhl_linux_tx.c b/drivers/video/msm/mdss/mhl3/mhl_linux_tx.c index 1514f021414a..04ba7a00bb2b 100644 --- a/drivers/video/msm/mdss/mhl3/mhl_linux_tx.c +++ b/drivers/video/msm/mdss/mhl3/mhl_linux_tx.c @@ -5599,7 +5599,7 @@ static int is_timer_handle_valid(struct mhl_dev_context *dev_context, } if (timer != timer_handle) { - MHL_TX_DBG_WARN("Invalid timer handle %p received\n", + MHL_TX_DBG_WARN("Invalid timer handle %pK received\n", timer_handle); return -EINVAL; } diff --git a/drivers/video/msm/mdss/mhl3/mhl_supp.c b/drivers/video/msm/mdss/mhl3/mhl_supp.c index 7055d8cd758d..29de6d0b6401 100644 --- a/drivers/video/msm/mdss/mhl3/mhl_supp.c +++ b/drivers/video/msm/mdss/mhl3/mhl_supp.c @@ -185,7 +185,7 @@ static struct cbus_req *get_free_cbus_queue_entry_impl( req->function = function; req->line = line; req->sequence = dev_context->sequence++; - /*MHL_TX_DBG_ERR(,"q %d get:0x%p %s:%d\n", + /*MHL_TX_DBG_ERR(,"q %d get:0x%pK %s:%d\n", req->sequence,req,function,line); */ return req; } @@ -197,7 +197,7 @@ static void return_cbus_queue_entry_impl(struct mhl_dev_context *dev_context, struct cbus_req *pReq, const char *function, int line) { - /* MHL_TX_DBG_ERR(,"q ret:0x%p %s:%d\n",pReq,function,line); */ + /* MHL_TX_DBG_ERR(,"q ret:0x%pK %s:%d\n",pReq,function,line); */ list_add(&pReq->link, &dev_context->cbus_free_list); } @@ -372,7 +372,7 @@ static struct block_req *start_new_block_marshalling_req_impl( sizeof(payload->as_bytes) - sizeof(struct SI_PACK_THIS_STRUCT standard_transport_header_t); dev_context->block_protocol.marshalling_req = req; - MHL_TX_DBG_WARN("q %d get:0x%p %s:%d\n", req->sequence, req, function, + MHL_TX_DBG_WARN("q %d get:0x%pK %s:%d\n", req->sequence, req, function, line); return req; } @@ -384,7 +384,7 @@ static void return_block_queue_entry_impl(struct mhl_dev_context *dev_context, struct block_req *pReq, const char *function, int line) { - /* MHL_TX_DBG_ERR(,"q ret:0x%p %s:%d\n",pReq,function,line); */ + /* MHL_TX_DBG_ERR(,"q ret:0x%pK %s:%d\n",pReq,function,line); */ list_add(&pReq->link, &dev_context->block_protocol.free_list); } @@ -1283,7 +1283,7 @@ void si_mhl_tx_drive_states(struct mhl_dev_context *dev_context) if (req == NULL) return; - MHL_TX_DBG_INFO("req: %p\n", req); + MHL_TX_DBG_INFO("req: %pK\n", req); /* coordinate write burst requests and grants. */ if (MHL_MSC_MSG == req->command) { dev_context->msc_msg_last_data = req->msg_data[1]; @@ -1298,7 +1298,7 @@ void si_mhl_tx_drive_states(struct mhl_dev_context *dev_context) } } - MHL_TX_DBG_INFO("req: %p\n", req); + MHL_TX_DBG_INFO("req: %pK\n", req); if (req) { uint8_t ret_val; dev_context->current_cbus_req = req; diff --git a/drivers/video/msm/mdss/mhl3/platform.c b/drivers/video/msm/mdss/mhl3/platform.c index c0e5174880b8..b0c7e8aabb23 100644 --- a/drivers/video/msm/mdss/mhl3/platform.c +++ b/drivers/video/msm/mdss/mhl3/platform.c @@ -1590,7 +1590,7 @@ static int __devinit si_8620_mhl_tx_i2c_probe(struct i2c_client *client, { int ret; - pr_info("%s(), i2c_device_id = %p\n", __func__, id); + pr_info("%s(), i2c_device_id = %pK\n", __func__, id); #if defined(SIMG_USE_DTS) /* @@ -1844,7 +1844,7 @@ static int __devinit si_8620_mhl_tx_spi_probe(struct spi_device *spi) { int ret; - pr_info("%s(), spi = %p\n", __func__, spi); + pr_info("%s(), spi = %pK\n", __func__, spi); spi->bits_per_word = 8; spi_dev = spi; spi_bus_num = spi->master->bus_num; @@ -2161,7 +2161,7 @@ static void __exit si_8620_exit(void) for (idx = 0; idx < ARRAY_SIZE(device_addresses); idx++) { MHL_TX_DBG_INFO("\n"); if (device_addresses[idx].client != NULL) { - MHL_TX_DBG_INFO("unregistering device:%p\n", + MHL_TX_DBG_INFO("unregistering device:%pK\n", device_addresses[idx].client); i2c_unregister_device(device_addresses[idx]. client); diff --git a/drivers/video/msm/mdss/mhl3/si_8620_drv.c b/drivers/video/msm/mdss/mhl3/si_8620_drv.c index dd71f1becd1e..9d68f285d581 100644 --- a/drivers/video/msm/mdss/mhl3/si_8620_drv.c +++ b/drivers/video/msm/mdss/mhl3/si_8620_drv.c @@ -2367,7 +2367,7 @@ int si_mhl_tx_drv_get_edid_fifo_partial_block(struct drv_hw_context *hw_context, offset = EDID_BLOCK_SIZE * (hw_context->edid_fifo_block_number & 0x01); offset += start; - MHL_TX_DBG_INFO("%p %p\n", hw_context, edid_buf); + MHL_TX_DBG_INFO("%pK %pK\n", hw_context, edid_buf); if (EDID_BLOCK_SIZE == (offset + length)) hw_context->edid_fifo_block_number++; @@ -2401,7 +2401,7 @@ int si_mhl_tx_drv_get_edid_fifo_next_block(struct drv_hw_context *hw_context, offset = EDID_BLOCK_SIZE * (hw_context->edid_fifo_block_number & 0x01); - MHL_TX_DBG_INFO("%p %p\n", hw_context, edid_buf); + MHL_TX_DBG_INFO("%pK %pK\n", hw_context, edid_buf); hw_context->edid_fifo_block_number++; #ifdef MANUAL_EDID_FETCH diff --git a/drivers/video/msm/mdss/mhl3/si_emsc_hid.c b/drivers/video/msm/mdss/mhl3/si_emsc_hid.c index 17d33c99ef54..51e2eda2827e 100644 --- a/drivers/video/msm/mdss/mhl3/si_emsc_hid.c +++ b/drivers/video/msm/mdss/mhl3/si_emsc_hid.c @@ -461,7 +461,7 @@ static int mhl3_send_ack(struct mhl3_hid_data *mhid, uint8_t reason) return -ENODEV; MHL3_HID_DBG_WARN("%s - HID_ACK reason code: %02X\n", __func__, reason); - MHL3_HID_DBG_ERR("mhid->mdev: %p\n", mhid->mdev); + MHL3_HID_DBG_ERR("mhid->mdev: %pK\n", mhid->mdev); mhid->out_data[0] = MHL3_HID_ACK; mhid->out_data[1] = reason; @@ -1089,7 +1089,7 @@ mhid_cleanup: mhl3_send_ack(mhid, HID_ACK_NODEV); mhid->flags |= HID_FLAGS_WQ_CANCEL; - MHL3_HID_DBG_ERR("WORK QUEUE function FAIL - mhid: %p\n", mhid); + MHL3_HID_DBG_ERR("WORK QUEUE function FAIL - mhid: %pK\n", mhid); mhl3_disconnect_and_destroy_hid_device(mhid); /* diff --git a/drivers/video/msm/mdss/mhl3/si_mdt_inputdev.c b/drivers/video/msm/mdss/mhl3/si_mdt_inputdev.c index 13d2a08831af..89d3fdf43f53 100644 --- a/drivers/video/msm/mdss/mhl3/si_mdt_inputdev.c +++ b/drivers/video/msm/mdss/mhl3/si_mdt_inputdev.c @@ -80,10 +80,10 @@ static void destroy_mouse(struct mhl_dev_context *dev_context) if (dev_context->mdt_devs.dev_mouse == NULL) return; - MHL_TX_DBG_INFO("Unregistering mouse: %p\n", + MHL_TX_DBG_INFO("Unregistering mouse: %pK\n", dev_context->mdt_devs.dev_mouse); input_unregister_device(dev_context->mdt_devs.dev_mouse); - MHL_TX_DBG_INFO("Freeing mouse: %p\n", dev_context->mdt_devs.dev_mouse); + MHL_TX_DBG_INFO("Freeing mouse: %pK\n", dev_context->mdt_devs.dev_mouse); input_free_device(dev_context->mdt_devs.dev_mouse); dev_context->mdt_devs.dev_mouse = NULL; } @@ -93,10 +93,10 @@ static void destroy_keyboard(struct mhl_dev_context *dev_context) if (dev_context->mdt_devs.dev_keyboard == NULL) return; - MHL_TX_DBG_INFO("Unregistering keyboard: %p\n", + MHL_TX_DBG_INFO("Unregistering keyboard: %pK\n", dev_context->mdt_devs.dev_keyboard); input_unregister_device(dev_context->mdt_devs.dev_keyboard); - MHL_TX_DBG_INFO("Freeing keyboard: %p\n", + MHL_TX_DBG_INFO("Freeing keyboard: %pK\n", dev_context->mdt_devs.dev_keyboard); input_free_device(dev_context->mdt_devs.dev_keyboard); dev_context->mdt_devs.dev_keyboard = NULL; @@ -107,10 +107,10 @@ static void destroy_touchscreen(struct mhl_dev_context *dev_context) if (dev_context->mdt_devs.dev_touchscreen == NULL) return; - MHL_TX_DBG_INFO("Unregistering mouse: %p\n", + MHL_TX_DBG_INFO("Unregistering mouse: %pK\n", dev_context->mdt_devs.dev_touchscreen); input_unregister_device(dev_context->mdt_devs.dev_touchscreen); - MHL_TX_DBG_INFO("Freeing mouse: %p\n", + MHL_TX_DBG_INFO("Freeing mouse: %pK\n", dev_context->mdt_devs.dev_touchscreen); input_free_device(dev_context->mdt_devs.dev_touchscreen); dev_context->mdt_devs.dev_touchscreen = NULL; @@ -130,7 +130,7 @@ int init_mdt_keyboard(struct mhl_dev_context *dev_context) MHL_TX_DBG_ERR("Not enough memory\n"); return -ENOMEM; } - MHL_TX_DBG_INFO("Allocated keyboard: %p\n", dev_keyboard); + MHL_TX_DBG_INFO("Allocated keyboard: %pK\n", dev_keyboard); set_bit(EV_KEY, dev_keyboard->evbit); set_bit(EV_REP, dev_keyboard->evbit); @@ -158,7 +158,7 @@ int init_mdt_keyboard(struct mhl_dev_context *dev_context) return error; } - MHL_TX_DBG_INFO("Registered keyboard: %p\n", dev_keyboard); + MHL_TX_DBG_INFO("Registered keyboard: %pK\n", dev_keyboard); dev_context->mdt_devs.dev_keyboard = dev_keyboard; @@ -175,7 +175,7 @@ int init_mdt_mouse(struct mhl_dev_context *dev_context) MHL_TX_DBG_ERR("Not enough memory\n"); return -ENOMEM; } - MHL_TX_DBG_INFO("Allocated mouse: %p\n", dev_mouse); + MHL_TX_DBG_INFO("Allocated mouse: %pK\n", dev_mouse); set_bit(EV_REL, dev_mouse->evbit); set_bit(EV_KEY, dev_mouse->evbit); @@ -208,7 +208,7 @@ int init_mdt_mouse(struct mhl_dev_context *dev_context) return error; } - MHL_TX_DBG_INFO("Registered mouse: %p\n", dev_mouse); + MHL_TX_DBG_INFO("Registered mouse: %pK\n", dev_mouse); dev_context->mdt_devs.dev_mouse = dev_mouse; @@ -226,7 +226,7 @@ int init_mdt_touchscreen(struct mhl_dev_context *dev_context) return -ENOMEM; } - MHL_TX_DBG_INFO("Allocated touch screen: %p\n", dev_touchscreen); + MHL_TX_DBG_INFO("Allocated touch screen: %pK\n", dev_touchscreen); #if !defined(SINGLE_TOUCH) && defined(KERNEL_2_6_38_AND_LATER) input_mt_init_slots(dev_touchscreen, MAX_TOUCH_CONTACTS); @@ -301,7 +301,7 @@ int init_mdt_touchscreen(struct mhl_dev_context *dev_context) input_free_device(dev_touchscreen); return error; } - MHL_TX_DBG_INFO("Registered touchscreen: %p\n", dev_touchscreen); + MHL_TX_DBG_INFO("Registered touchscreen: %pK\n", dev_touchscreen); dev_context->mdt_devs.dev_touchscreen = dev_touchscreen; diff --git a/drivers/video/msm/mdss/mhl3/si_mhl2_edid_3d.c b/drivers/video/msm/mdss/mhl3/si_mhl2_edid_3d.c index fd6918fbf1ff..9eb4e7db1ff1 100644 --- a/drivers/video/msm/mdss/mhl3/si_mhl2_edid_3d.c +++ b/drivers/video/msm/mdss/mhl3/si_mhl2_edid_3d.c @@ -1118,7 +1118,7 @@ static void tx_prune_dtd_list(struct edid_3d_data_t *mhl_edid_3d_data, if ((0 != p_desc->dtd.pixel_clock_low) || (0 != p_desc->dtd.pixel_clock_high)) { MHL_TX_EDID_INFO( - "pix clock non-zero p_desc:%p", p_desc) + "pix clock non-zero p_desc:%pK", p_desc) if ((0 == p_desc->dtd.horz_active_7_0) && (0 == p_desc->dtd.horz_active_blanking_high. horz_active_11_8)) { @@ -1133,7 +1133,7 @@ static void tx_prune_dtd_list(struct edid_3d_data_t *mhl_edid_3d_data, * one by one */ MHL_TX_EDID_INFO( - "p_desc:%p p_next_desc:%p\n", + "p_desc:%pK p_next_desc:%pK\n", p_desc, p_next_desc) *p_desc++ = *p_next_desc++; } @@ -1144,7 +1144,7 @@ static void tx_prune_dtd_list(struct edid_3d_data_t *mhl_edid_3d_data, p_desc = p_holder; } else { p_desc++; - MHL_TX_EDID_INFO("p_desc:%p\n", p_desc) + MHL_TX_EDID_INFO("p_desc:%pK\n", p_desc) } } } @@ -1446,7 +1446,7 @@ static bool si_mhl_tx_parse_detailed_timing_descriptor( * Mark this mode for pruning by setting * horizontal active to zero */ - MHL_TX_DBG_ERR("%smark for pruning%s %p\n", + MHL_TX_DBG_ERR("%smark for pruning%s %pK\n", ANSI_ESC_YELLOW_TEXT, ANSI_ESC_RESET_TEXT, p_desc); @@ -1500,7 +1500,7 @@ static uint8_t si_mhl_tx_parse_861_long_descriptors( ++mhl_edid_3d_data->parse_data. num_cea_861_timing_dtds; } else if (valid) { - MHL_TX_EDID_INFO("stopping at %p\n", + MHL_TX_EDID_INFO("stopping at %pK\n", p_data_u.p_long_descriptors) break; } @@ -1600,7 +1600,7 @@ static void prune_hdmi_vsdb_vic_list( HDMI_VIC_len = inner_loop_limit; p_CEA_extension->byte_offset_to_18_byte_descriptors -= num_HDMI_VICs_pruned; - MHL_TX_EDID_INFO("%p\n", mhl_edid_3d_data->parse_data.p_HDMI_vsdb); + MHL_TX_EDID_INFO("%pK\n", mhl_edid_3d_data->parse_data.p_HDMI_vsdb); if (mhl_edid_3d_data->parse_data.p_HDMI_vsdb) { mhl_edid_3d_data->parse_data.p_HDMI_vsdb-> header.fields.length_following_header -= @@ -1722,8 +1722,8 @@ static void prune_svd_list( ("\n\nInvalid extension size\n\n")); while (pb_src < pb_limit) { MHL_TX_EDID_INFO( - "moving data up %p(0x%02X) " - "<- %p(0x%02X)\n", + "moving data up %pK(0x%02X) " + "<- %pK(0x%02X)\n", pb_dest, (uint16_t)*pb_dest, pb_src, (uint16_t)*pb_src); *pb_dest++ = *pb_src++; @@ -3123,7 +3123,7 @@ void si_mhl_tx_process_hev_vic_burst(struct edid_3d_data_t *mhl_edid_3d_data, ANSI_ESC_RED_TEXT, ANSI_ESC_RESET_TEXT); return; } else { - MHL_TX_DBG_WARN(" %d %p\n", hev_index, + MHL_TX_DBG_WARN(" %d %pK\n", hev_index, mhl_edid_3d_data->hev_vic_list) mhl_edid_3d_data->hev_vic_info. num_items_allocated = @@ -3136,7 +3136,7 @@ void si_mhl_tx_process_hev_vic_burst(struct edid_3d_data_t *mhl_edid_3d_data, MHL_TX_DBG_ERR("bogus write burst, no hev_vic_list\n") return; } - MHL_TX_DBG_WARN(" %d %p\n", hev_index, mhl_edid_3d_data->hev_vic_list) + MHL_TX_DBG_WARN(" %d %pK\n", hev_index, mhl_edid_3d_data->hev_vic_list) if (NULL == mhl_edid_3d_data->hev_vic_list) { MHL_TX_DBG_ERR("%s no place to put HEV_VIC burst%s\n", ANSI_ESC_RED_TEXT, ANSI_ESC_RESET_TEXT); @@ -3155,7 +3155,7 @@ void si_mhl_tx_process_hev_vic_burst(struct edid_3d_data_t *mhl_edid_3d_data, burst_id_HEV_VIC, (union video_burst_descriptor_u *) &p_burst-> video_descriptors[i])) { - MHL_TX_DBG_INFO(" %d %p\n", + MHL_TX_DBG_INFO(" %d %pK\n", hev_index, mhl_edid_3d_data->hev_vic_list) mhl_edid_3d_data->hev_vic_list[hev_index]. mhl3_hev_vic_descriptor = @@ -4036,7 +4036,7 @@ static uint8_t parse_861_block(struct edid_3d_data_t *mhl_edid_3d_data, mhl_edid_3d_data->parse_data.p_HDMI_vsdb = NULL; - MHL_TX_EDID_INFO("tag:place holder EDID block:%p\n", p_EDID_block_data); + MHL_TX_EDID_INFO("tag:place holder EDID block:%pK\n", p_EDID_block_data); if (EDID_EXTENSION_BLOCK_MAP == p_CEA_extension->tag) { struct block_map_t *p_block_map; int i; @@ -4123,7 +4123,7 @@ void si_mhl_tx_handle_atomic_hw_edid_read_complete( mhl_edid_3d_data->parse_data.num_EDID_extensions; ++counter) { MHL_TX_EDID_INFO - (" counter:%d tag:place holder EDID block:%p\n", + (" counter:%d tag:place holder EDID block:%pK\n", counter, &mhl_edid_3d_data-> EDID_block_data[EDID_BLOCK_SIZE * counter]); -- cgit v1.2.3 From 629ed5b4a0e4a2b26e4f5affe2685b3ce71b65f7 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 7 Oct 2016 11:51:15 -0700 Subject: ion: blacklist %p kptr_restrict Bug: 31494725 Change-Id: I10a0c2aae883dfaa6c235c38689a704064557008 --- drivers/staging/android/ion/ion.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index cb4a2f43e4fe..8bbbb38dc7c4 100755 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -802,7 +802,7 @@ static int ion_debug_client_show(struct seq_file *s, void *unused) struct ion_handle *handle = rb_entry(n, struct ion_handle, node); - seq_printf(s, "%16.16s: %16zx : %16d : %12p", + seq_printf(s, "%16.16s: %16zx : %16d : %12pK", handle->buffer->heap->name, handle->buffer->size, atomic_read(&handle->ref.refcount), @@ -1201,7 +1201,7 @@ static void ion_vm_open(struct vm_area_struct *vma) mutex_lock(&buffer->lock); list_add(&vma_list->list, &buffer->vmas); mutex_unlock(&buffer->lock); - pr_debug("%s: adding %p\n", __func__, vma); + pr_debug("%s: adding %pK\n", __func__, vma); } static void ion_vm_close(struct vm_area_struct *vma) @@ -1216,7 +1216,7 @@ static void ion_vm_close(struct vm_area_struct *vma) continue; list_del(&vma_list->list); kfree(vma_list); - pr_debug("%s: deleting %p\n", __func__, vma); + pr_debug("%s: deleting %pK\n", __func__, vma); break; } mutex_unlock(&buffer->lock); -- cgit v1.2.3 From 7e7cd02bc4cdb783bf4d9ca2d2fb33b0f72ee876 Mon Sep 17 00:00:00 2001 From: Nick Desaulniers Date: Fri, 7 Oct 2016 10:56:13 -0700 Subject: binder: blacklist %p kptr_restrict Bug: 31495231 Change-Id: Iebc150f6bc939b56e021424ee44fb30ce8d732fd --- drivers/staging/android/binder.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 192032638f75..ad902dbac8fa 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -535,7 +535,7 @@ static void binder_insert_free_buffer(struct binder_proc *proc, new_buffer_size = binder_buffer_size(proc, new_buffer); binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: add free buffer, size %zd, at %p\n", + "%d: add free buffer, size %zd, at %pK\n", proc->pid, new_buffer_size, new_buffer); while (*p) { @@ -613,7 +613,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, struct mm_struct *mm; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: %s pages %p-%p\n", proc->pid, + "%d: %s pages %pK-%pK\n", proc->pid, allocate ? "allocate" : "free", start, end); if (end <= start) @@ -655,7 +655,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, BUG_ON(*page); *page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); if (*page == NULL) { - pr_err("%d: binder_alloc_buf failed for page at %p\n", + pr_err("%d: binder_alloc_buf failed for page at %pK\n", proc->pid, page_addr); goto err_alloc_page_failed; } @@ -664,7 +664,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, flush_cache_vmap((unsigned long)page_addr, (unsigned long)page_addr + PAGE_SIZE); if (ret != 1) { - pr_err("%d: binder_alloc_buf failed to map page at %p in kernel\n", + pr_err("%d: binder_alloc_buf failed to map page at %pK in kernel\n", proc->pid, page_addr); goto err_map_kernel_failed; } @@ -774,7 +774,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, } binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: binder_alloc_buf size %zd got buffer %p size %zd\n", + "%d: binder_alloc_buf size %zd got buffer %pK size %zd\n", proc->pid, size, buffer, buffer_size); has_page_addr = @@ -804,7 +804,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, binder_insert_free_buffer(proc, new_buffer); } binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: binder_alloc_buf size %zd got %p\n", + "%d: binder_alloc_buf size %zd got %pK\n", proc->pid, size, buffer); buffer->data_size = data_size; buffer->offsets_size = offsets_size; @@ -844,7 +844,7 @@ static void binder_delete_free_buffer(struct binder_proc *proc, if (buffer_end_page(prev) == buffer_end_page(buffer)) free_page_end = 0; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: merge free, buffer %p share page with %p\n", + "%d: merge free, buffer %pK share page with %pK\n", proc->pid, buffer, prev); } @@ -857,14 +857,14 @@ static void binder_delete_free_buffer(struct binder_proc *proc, buffer_start_page(buffer)) free_page_start = 0; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: merge free, buffer %p share page with %p\n", + "%d: merge free, buffer %pK share page with %pK\n", proc->pid, buffer, prev); } } list_del(&buffer->entry); if (free_page_start || free_page_end) { binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: merge free, buffer %p do not share page%s%s with %p or %p\n", + "%d: merge free, buffer %pK do not share page%s%s with %pK or %pK\n", proc->pid, buffer, free_page_start ? "" : " end", free_page_end ? "" : " start", prev, next); binder_update_page_range(proc, 0, free_page_start ? @@ -885,7 +885,7 @@ static void binder_free_buf(struct binder_proc *proc, ALIGN(buffer->offsets_size, sizeof(void *)); binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: binder_free_buf %p size %zd buffer_size %zd\n", + "%d: binder_free_buf %pK size %zd buffer_size %zd\n", proc->pid, buffer, size, buffer_size); BUG_ON(buffer->free); @@ -1315,7 +1315,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, int debug_id = buffer->debug_id; binder_debug(BINDER_DEBUG_TRANSACTION, - "%d buffer release %d, size %zd-%zd, failed at %p\n", + "%d buffer release %d, size %zd-%zd, failed at %pK\n", proc->pid, buffer->debug_id, buffer->data_size, buffer->offsets_size, failed_at); @@ -2170,7 +2170,7 @@ static int binder_thread_write(struct binder_proc *proc, } } binder_debug(BINDER_DEBUG_DEAD_BINDER, - "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n", + "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n", proc->pid, thread->pid, (u64)cookie, death); if (death == NULL) { @@ -2973,7 +2973,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) #ifdef CONFIG_CPU_CACHE_VIPT if (cache_is_vipt_aliasing()) { while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) { - pr_info("binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); + pr_info("binder_mmap: %d %lx-%lx maps %pK bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); vma->vm_start += PAGE_SIZE; } } @@ -3009,7 +3009,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) proc->vma = vma; proc->vma_vm_mm = vma->vm_mm; - /*pr_info("binder_mmap: %d %lx-%lx maps %p\n", + /*pr_info("binder_mmap: %d %lx-%lx maps %pK\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ return 0; @@ -3235,7 +3235,7 @@ static void binder_deferred_release(struct binder_proc *proc) page_addr = proc->buffer + i * PAGE_SIZE; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%s: %d: page %d at %p not freed\n", + "%s: %d: page %d at %pK not freed\n", __func__, proc->pid, i, page_addr); unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); __free_page(proc->pages[i]); @@ -3320,7 +3320,7 @@ static void print_binder_transaction(struct seq_file *m, const char *prefix, struct binder_transaction *t) { seq_printf(m, - "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d", + "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d", prefix, t->debug_id, t, t->from ? t->from->proc->pid : 0, t->from ? t->from->pid : 0, @@ -3334,7 +3334,7 @@ static void print_binder_transaction(struct seq_file *m, const char *prefix, if (t->buffer->target_node) seq_printf(m, " node %d", t->buffer->target_node->debug_id); - seq_printf(m, " size %zd:%zd data %p\n", + seq_printf(m, " size %zd:%zd data %pK\n", t->buffer->data_size, t->buffer->offsets_size, t->buffer->data); } @@ -3342,7 +3342,7 @@ static void print_binder_transaction(struct seq_file *m, const char *prefix, static void print_binder_buffer(struct seq_file *m, const char *prefix, struct binder_buffer *buffer) { - seq_printf(m, "%s %d: %p size %zd:%zd %s\n", + seq_printf(m, "%s %d: %pK size %zd:%zd %s\n", prefix, buffer->debug_id, buffer->data, buffer->data_size, buffer->offsets_size, buffer->transaction ? "active" : "delivered"); -- cgit v1.2.3 From ca9844bf044701e439395b45e462a12b16992486 Mon Sep 17 00:00:00 2001 From: Pat Tjin Date: Tue, 18 Oct 2016 07:39:34 +0000 Subject: Revert "net: ping: Fix stack buffer overflow in ping_common_sendmsg()" This reverts commit 5442a0c99c8a33d22363f40543cbca68b4c8e113. Change-Id: I6b1105014803f1e625ad1b0b22139e6f22ec231e Bug: 31349935 --- net/ipv4/ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index f65379c4d86d..59f8d47bffe4 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -656,7 +656,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, void *user_icmph, size_t icmph_len) { u8 type, code; - if (len > 0xFFFF || len < icmph_len) + if (len > 0xFFFF) return -EMSGSIZE; /* -- cgit v1.2.3 From ca44f392ff035b298e0ffe6f7edd0a408e07a67b Mon Sep 17 00:00:00 2001 From: Qidan He Date: Thu, 13 Oct 2016 16:27:46 -0700 Subject: net: ping: Fix stack buffer overflow in ping_common_sendmsg() In ping_common_sendmsg(), when len < icmph_len, memcpy_fromiovec() will access invalid memory because msg->msg_iov only has 1 element and memcpy_fromiovec() attempts to increment it. KASAN report: BUG: KASAN: stack-out-of-bounds in memcpy_fromiovec+0x60/0x114 at addr ffffffc071077da0 Read of size 8 by task trinity-c2/9623 page:ffffffbe034b9a08 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x0() page dumped because: kasan: bad access detected CPU: 0 PID: 9623 Comm: trinity-c2 Tainted: G BU 3.18.0-dirty #15 Hardware name: Google Tegra210 Smaug Rev 1,3+ (DT) Call trace: [] dump_backtrace+0x0/0x1ac arch/arm64/kernel/traps.c:90 [] show_stack+0x10/0x1c arch/arm64/kernel/traps.c:171 [< inline >] __dump_stack lib/dump_stack.c:15 [] dump_stack+0x7c/0xd0 lib/dump_stack.c:50 [< inline >] print_address_description mm/kasan/report.c:147 [< inline >] kasan_report_error mm/kasan/report.c:236 [] kasan_report+0x380/0x4b8 mm/kasan/report.c:259 [< inline >] check_memory_region mm/kasan/kasan.c:264 [] __asan_load8+0x20/0x70 mm/kasan/kasan.c:507 [] memcpy_fromiovec+0x5c/0x114 lib/iovec.c:15 [< inline >] memcpy_from_msg include/linux/skbuff.h:2667 [] ping_common_sendmsg+0x50/0x108 net/ipv4/ping.c:674 [] ping_v4_sendmsg+0xd8/0x698 net/ipv4/ping.c:714 [] inet_sendmsg+0xe0/0x12c net/ipv4/af_inet.c:749 [< inline >] __sock_sendmsg_nosec net/socket.c:624 [< inline >] __sock_sendmsg net/socket.c:632 [] sock_sendmsg+0x124/0x164 net/socket.c:643 [< inline >] SYSC_sendto net/socket.c:1797 [] SyS_sendto+0x178/0x1d8 net/socket.c:1761 Memory state around the buggy address: ffffffc071077c80: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 f1 f1 ffffffc071077d00: f1 f1 04 f4 f4 f4 f2 f2 f2 f2 04 f4 f4 f4 f2 f2 >ffffffc071077d80: f2 f2 00 00 f4 f4 f2 f2 f2 f2 00 00 00 00 00 00 ^ ffffffc071077e00: 00 f4 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 ffffffc071077e80: 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00 00 00 Bug: 31349935 Change-Id: Ib7385fc26dfe7e07e9bab42a10ff65a37cbaab54 Signed-off-by: Siqi Lin --- net/ipv4/ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 59f8d47bffe4..f65379c4d86d 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -656,7 +656,7 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, void *user_icmph, size_t icmph_len) { u8 type, code; - if (len > 0xFFFF) + if (len > 0xFFFF || len < icmph_len) return -EMSGSIZE; /* -- cgit v1.2.3 From d26bf5f68d503b27eadb5f137a2837eefe175c0c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 13 Oct 2016 13:07:36 -0700 Subject: CHROMIUM: UPSTREAM: mm: remove gup_flags FOLL_WRITE games from __get_user_pages() This is an ancient bug that was actually attempted to be fixed once (badly) by me eleven years ago in commit 4ceb5db9757a ("Fix get_user_pages() race for write access") but that was then undone due to problems on s390 by commit f33ea7f404e5 ("fix get_user_pages bug"). In the meantime, the s390 situation has long been fixed, and we can now fix it by checking the pte_dirty() bit properly (and do it better). The s390 dirty bit was implemented in abf09bed3cce ("s390/mm: implement software dirty bits") which made it into v3.9. Earlier kernels will have to look at the page state itself. Also, the VM has become more scalable, and what used a purely theoretical race back then has become easier to trigger. To fix it, we introduce a new internal FOLL_COW flag to mark the "yes, we already did a COW" rather than play racy games with FOLL_WRITE that is very fundamental, and then use the pte dirty flag to validate that the FOLL_COW flag is still valid. BUG=chromium:657609 TEST=None Change-Id: I42e448ecacad4781b460c4c989026307169ba1b5 Reported-and-tested-by: Phil "not Paul" Oester Acked-by: Hugh Dickins Reviewed-by: Michal Hocko Cc: Andy Lutomirski Cc: Kees Cook Cc: Oleg Nesterov Cc: Willy Tarreau Cc: Nick Piggin Cc: Greg Thelen Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds (cherry picked from commit 19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619) Signed-off-by: Andrey Ulanov Reviewed-on: https://chromium-review.googlesource.com/401142 Reviewed-by: Guenter Roeck Bug: 32141528 --- include/linux/mm.h | 1 + mm/gup.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 4f0afdd74818..f410ba03afd9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2050,6 +2050,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, #define FOLL_NUMA 0x200 /* force NUMA hinting page fault */ #define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */ #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ +#define FOLL_COW 0x4000 /* internal GUP flag */ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); diff --git a/mm/gup.c b/mm/gup.c index 377a5a796242..bef4bb0f7962 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -32,6 +32,16 @@ static struct page *no_page_table(struct vm_area_struct *vma, return NULL; } +/* + * FOLL_FORCE can write to even unwritable pte's, but only + * after we've gone through a COW cycle and they are dirty. + */ +static inline bool can_follow_write_pte(pte_t pte, unsigned int flags) +{ + return pte_write(pte) || + ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte)); +} + static struct page *follow_page_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd, unsigned int flags) { @@ -66,7 +76,7 @@ retry: } if ((flags & FOLL_NUMA) && pte_numa(pte)) goto no_page; - if ((flags & FOLL_WRITE) && !pte_write(pte)) { + if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) { pte_unmap_unlock(ptep, ptl); return NULL; } @@ -315,7 +325,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, * reCOWed by userspace write). */ if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE)) - *flags &= ~FOLL_WRITE; + *flags |= FOLL_COW; return 0; } -- cgit v1.2.3 From d90afe404775f3f98cd00c3784d18406a44ce004 Mon Sep 17 00:00:00 2001 From: Patrick Tjin Date: Fri, 21 Oct 2016 09:23:42 -0700 Subject: Revert "Revert "Revert "msm: kgsl: Clear the interrupt immediately""" This reverts commit a0ce33daf6946ce83de783e09066d0d5a879dabd. Change-Id: I06f0d8cd4bffc3ff506bf63b3d5222fcc8298e2f --- drivers/gpu/msm/adreno.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 886043c91147..471b62d420fb 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -593,15 +593,6 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); - /* - * Clear all the interrupt bits but A5XX_INT_RBBM_AHB_ERROR. Because - * even if we clear it here, it will stay high until it is cleared - * in its respective handler. Otherwise, the interrupt handler will - * fire again. - */ - adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - status & ~BIT(A5XX_INT_RBBM_AHB_ERROR)); - /* Loop through all set interrupts and call respective handlers */ for (tmp = status; tmp != 0;) { i = fls(tmp) - 1; @@ -620,14 +611,9 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) gpudev->irq_trace(adreno_dev, status); - /* - * Clear A5XX_INT_RBBM_AHB_ERROR bit after this interrupt has been - * cleared in its respective handler - */ - if (status & BIT(A5XX_INT_RBBM_AHB_ERROR)) + if (status) adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - BIT(A5XX_INT_RBBM_AHB_ERROR)); - + status); return ret; } -- cgit v1.2.3 From bbaed100bd63575095c62586da9869f009a402d0 Mon Sep 17 00:00:00 2001 From: Patrick Tjin Date: Fri, 21 Oct 2016 09:24:49 -0700 Subject: Revert "Revert "Revert "Revert "msm: kgsl: Clear the interrupt immediately"""" This reverts commit d90afe404775f3f98cd00c3784d18406a44ce004. Change-Id: If7d35969258530727fbe9da59fa2b9c37e1ddb3b --- drivers/gpu/msm/adreno.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 471b62d420fb..886043c91147 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -593,6 +593,15 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) adreno_readreg(adreno_dev, ADRENO_REG_RBBM_INT_0_STATUS, &status); + /* + * Clear all the interrupt bits but A5XX_INT_RBBM_AHB_ERROR. Because + * even if we clear it here, it will stay high until it is cleared + * in its respective handler. Otherwise, the interrupt handler will + * fire again. + */ + adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, + status & ~BIT(A5XX_INT_RBBM_AHB_ERROR)); + /* Loop through all set interrupts and call respective handlers */ for (tmp = status; tmp != 0;) { i = fls(tmp) - 1; @@ -611,9 +620,14 @@ static irqreturn_t adreno_irq_handler(struct kgsl_device *device) gpudev->irq_trace(adreno_dev, status); - if (status) + /* + * Clear A5XX_INT_RBBM_AHB_ERROR bit after this interrupt has been + * cleared in its respective handler + */ + if (status & BIT(A5XX_INT_RBBM_AHB_ERROR)) adreno_writereg(adreno_dev, ADRENO_REG_RBBM_INT_CLEAR_CMD, - status); + BIT(A5XX_INT_RBBM_AHB_ERROR)); + return ret; } -- cgit v1.2.3 From e9fde8664651a566df43c7439e27d59cc5d60460 Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Wed, 2 Nov 2016 17:43:51 -0700 Subject: ion: Fix use after free during ION_IOC_ALLOC If a user happens to call ION_IOC_FREE during an ION_IOC_ALLOC on the just allocated id, and the copy_to_user fails, the cleanup code will attempt to free an already freed handle. This adds a wrapper for ion_alloc that adds an ion_handle_get to avoid this. Bug: 31568617 Change-Id: I476e5bd5372b5178a213f1fea143d270cf9361ed Signed-off-by: Daniel Rosenberg --- drivers/staging/android/ion/ion.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 8bbbb38dc7c4..63e6b7d795f4 100755 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -507,9 +507,9 @@ static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) return 0; } -struct ion_handle *ion_alloc(struct ion_client *client, size_t len, +static struct ion_handle *__ion_alloc(struct ion_client *client, size_t len, size_t align, unsigned int heap_id_mask, - unsigned int flags) + unsigned int flags, bool grab_handle) { struct ion_handle *handle; struct ion_device *dev = client->dev; @@ -604,6 +604,8 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, return handle; mutex_lock(&client->lock); + if (grab_handle) + ion_handle_get(handle); ret = ion_handle_add(client, handle); mutex_unlock(&client->lock); if (ret) { @@ -613,6 +615,13 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len, return handle; } + +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags) +{ + return __ion_alloc(client, len, align, heap_id_mask, flags, false); +} EXPORT_SYMBOL(ion_alloc); static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle) @@ -1488,10 +1497,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct ion_handle *handle; - handle = ion_alloc(client, data.allocation.len, + handle = __ion_alloc(client, data.allocation.len, data.allocation.align, data.allocation.heap_id_mask, - data.allocation.flags); + data.allocation.flags, true); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -1568,11 +1577,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (dir & _IOC_READ) { if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { - if (cleanup_handle) + if (cleanup_handle) { ion_free(client, cleanup_handle); + ion_handle_put(cleanup_handle); + } return -EFAULT; } } + if (cleanup_handle) + ion_handle_put(cleanup_handle); return ret; } -- cgit v1.2.3 From e6f77dc0b17942b56bc0e083652a1b6df01df8c3 Mon Sep 17 00:00:00 2001 From: Biswajit Paul Date: Mon, 3 Oct 2016 04:01:32 -0700 Subject: msm: sensor: Adding mutex for actuator power down operations Protecting operations performed during actuator powerdown from race condition by adding mutex. Bug: 31225246 CRs-Fixed: 1071891 Change-Id: I7d6b2e8878788615c02678a4a28d31dca0ed6bca Signed-off-by: Sureshnaidu Laveti Signed-off-by: Biswajit Paul Signed-off-by: Yueyao Zhu --- drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index bf3973888573..a700f836061c 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -1559,11 +1559,13 @@ static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd, pr_err("a_ctrl->i2c_client.i2c_func_tbl NULL\n"); return -EINVAL; } + mutex_lock(a_ctrl->actuator_mutex); rc = msm_actuator_power_down(a_ctrl); if (rc < 0) { pr_err("%s:%d Actuator Power down failed\n", __func__, __LINE__); } + mutex_unlock(a_ctrl->actuator_mutex); return msm_actuator_close(sd, NULL); default: return -ENOIOCTLCMD; -- cgit v1.2.3 From d906945fc287f9df48b99349fea962b921d4d39e Mon Sep 17 00:00:00 2001 From: matt_huang Date: Mon, 7 Nov 2016 16:22:57 +0800 Subject: input: misc: fix security vulnerability initialize the structure before using Bug: 32591129 Change-Id: I9a3af40175d929009522f6c93005d82535c4ccc3 Signed-off-by: matt_huang --- drivers/input/misc/vl53L0/stmvl53l0_module.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/misc/vl53L0/stmvl53l0_module.c b/drivers/input/misc/vl53L0/stmvl53l0_module.c index 0028e527857f..cc27309fc4e2 100644 --- a/drivers/input/misc/vl53L0/stmvl53l0_module.c +++ b/drivers/input/misc/vl53L0/stmvl53l0_module.c @@ -2483,6 +2483,8 @@ static int stmvl53l0_ioctl_handler(struct file *file, if (!data->enable_ps_sensor) stmvl53l0_start(data, 3, NORMAL_MODE); + memset(&RangingMeasurementData, 0, sizeof(RangingMeasurementData)); + for (i = 0; i < RANGE_MEASUREMENT_TIMES;) { Status = papi_func_tbl->PerformSingleRangingMeasurement(vl53l0_dev, &RangingMeasurementData); -- cgit v1.2.3 From 4faa6d2e9b53546823882d8889820ff9ce3c372f Mon Sep 17 00:00:00 2001 From: Siqi Lin Date: Wed, 2 Nov 2016 16:51:08 -0700 Subject: ALSA: info: Check for integer overflow in snd_info_entry_write() snd_info_entry_write() resizes the buffer with an unsigned long size argument that gets truncated because resize_info_buffer() takes the size parameter as an unsigned int. On 64-bit kernels, this causes the following copy_to_user() to write out-of-bounds if (pos + count) can't be represented by an unsigned int. Bug: 32510733 Change-Id: I9e8b55f93f2bd606b4a73b5a4525b71ee88c7c23 Signed-off-by: Siqi Lin --- sound/core/info.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/core/info.c b/sound/core/info.c index 418b4ec43cad..a4af0ba92d30 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -253,6 +253,7 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer struct snd_info_buffer *buf; ssize_t size = 0; loff_t pos; + unsigned long realloc_size; data = file->private_data; if (snd_BUG_ON(!data)) @@ -261,7 +262,8 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer pos = *offset; if (pos < 0 || (long) pos != pos || (ssize_t) count < 0) return -EIO; - if ((unsigned long) pos + (unsigned long) count < (unsigned long) pos) + realloc_size = (unsigned long) pos + (unsigned long) count; + if (realloc_size < (unsigned long) pos || realloc_size > UINT_MAX) return -EIO; switch (entry->content) { case SNDRV_INFO_CONTENT_TEXT: -- cgit v1.2.3 From 11ab3add6cfb1ef752ac38adf1b4bf15617772e9 Mon Sep 17 00:00:00 2001 From: Andrew Chant Date: Tue, 8 Nov 2016 15:19:32 -0800 Subject: input: synaptics_dsx: add update bounds checks. Firmware updates contain offsets that are parsed by the kernel driver. Ensure all offsets are within the bounds of the firmware update. TESTED: Forced a firmware update by removing same-firmware check. Firmware update succeeded. Bug: 31525965 Bug: 31968442 Change-Id: I287f494d973868f6be28799bc2613ff2201b0717 Signed-off-by: Andrew Chant --- .../synaptics_dsx_fw_update.c | 183 +++++++++++++++++---- 1 file changed, 154 insertions(+), 29 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c index 05f13b427739..f7d5dbdd69b5 100644 --- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c @@ -771,6 +771,21 @@ static struct synaptics_rmi4_fwu_handle *fwu; DECLARE_COMPLETION(fwu_remove_complete); DEFINE_MUTEX(fwu_sysfs_mutex); +/* Check offset + size <= bound. true if in bounds, false otherwise. */ +static bool in_bounds(unsigned long offset, unsigned long size, + unsigned long bound) +{ + if (offset > bound || size > bound) { + pr_err("%s: %lu or %lu > %lu\n", __func__, offset, size, bound); + return false; + } + if (offset > (bound - size)) { + pr_err("%s: %lu > %lu - %lu\n", __func__, offset, size, bound); + return false; + } + return true; +} + #ifdef HTC_FEATURE static uint32_t syn_crc(uint16_t *data, uint32_t len) { @@ -966,8 +981,10 @@ static void fwu_compare_partition_tables(void) return; } -static void fwu_parse_partition_table(const unsigned char *partition_table, - struct block_count *blkcount, struct physical_address *phyaddr) +static int fwu_parse_partition_table(const unsigned char *partition_table, + unsigned long len, + struct block_count *blkcount, + struct physical_address *phyaddr) { unsigned char ii; unsigned char index; @@ -979,6 +996,11 @@ static void fwu_parse_partition_table(const unsigned char *partition_table, for (ii = 0; ii < fwu->partitions; ii++) { index = ii * 8 + 2; + if (!in_bounds(index, sizeof(*ptable), len)) { + pr_err("%s: %d/%d not in bounds\n", __func__, ii, + fwu->partitions); + return -EINVAL; + } ptable = (struct partition_table *)&partition_table[index]; partition_length = ptable->partition_length_15_8 << 8 | ptable->partition_length_7_0; @@ -987,7 +1009,7 @@ static void fwu_parse_partition_table(const unsigned char *partition_table, dev_dbg(rmi4_data->pdev->dev.parent, "%s: Partition entry %d:\n", __func__, ii); - for (offset = 0; offset < 8; offset++) { + for (offset = 0; offset < sizeof(*ptable); offset++) { dev_dbg(rmi4_data->pdev->dev.parent, "%s: 0x%02x\n", __func__, @@ -1077,16 +1099,17 @@ static void fwu_parse_partition_table(const unsigned char *partition_table, }; } - return; + return 0; } -static void fwu_parse_image_header_10_utility(const unsigned char *image) +static int fwu_parse_image_header_10_utility(const unsigned char *image) { unsigned char ii; unsigned char num_of_containers; unsigned int addr; unsigned int container_id; unsigned int length; + unsigned int content_offset; const unsigned char *content; struct container_descriptor *descriptor; @@ -1099,15 +1122,22 @@ static void fwu_parse_image_header_10_utility(const unsigned char *image) if (ii >= MAX_UTILITY_PARAMS) continue; addr = le_to_uint(fwu->img.utility.data + (ii * 4)); + if (!in_bounds(addr, sizeof(*descriptor), fwu->image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + addr); container_id = descriptor->container_id[0] | descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); + content_offset = le_to_uint(descriptor->content_address); length = le_to_uint(descriptor->content_length); + if (!in_bounds(content_offset, length, fwu->image_size)) + return -EINVAL; + content = image + content_offset; switch (container_id) { case UTILITY_PARAMETER_CONTAINER: fwu->img.utility_param[ii].data = content; fwu->img.utility_param[ii].size = length; + if (length < sizeof(content[0])) + return -EINVAL; fwu->img.utility_param_id[ii] = content[0]; break; default: @@ -1115,28 +1145,36 @@ static void fwu_parse_image_header_10_utility(const unsigned char *image) }; } - return; + return 0; } -static void fwu_parse_image_header_10_bootloader(const unsigned char *image) +static int fwu_parse_image_header_10_bootloader(const unsigned char *image) { unsigned char ii; unsigned char num_of_containers; unsigned int addr; unsigned int container_id; unsigned int length; + unsigned int content_offset; const unsigned char *content; struct container_descriptor *descriptor; + if (fwu->img.bootloader.size < 4) + return -EINVAL; num_of_containers = (fwu->img.bootloader.size - 4) / 4; for (ii = 1; ii <= num_of_containers; ii++) { addr = le_to_uint(fwu->img.bootloader.data + (ii * 4)); + if (!in_bounds(addr, sizeof(*descriptor), fwu->image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + addr); container_id = descriptor->container_id[0] | descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); + content_offset = le_to_uint(descriptor->content_address); length = le_to_uint(descriptor->content_length); + if (!in_bounds(content_offset, length, fwu->image_size)) + return -EINVAL; + content = image + content_offset; switch (container_id) { case BL_IMAGE_CONTAINER: fwu->img.bl_image.data = content; @@ -1157,29 +1195,36 @@ static void fwu_parse_image_header_10_bootloader(const unsigned char *image) }; } - return; + return 0; } -static void fwu_parse_image_header_10(void) +static int fwu_parse_image_header_10(void) { unsigned char ii; unsigned char num_of_containers; unsigned int addr; unsigned int offset; + unsigned int content_offset; unsigned int container_id; unsigned int length; + unsigned int image_size; const unsigned char *image; const unsigned char *content; struct container_descriptor *descriptor; struct image_header_10 *header; image = fwu->image; + image_size = fwu->image_size; + if (image_size < sizeof(*header)) + return -EINVAL; header = (struct image_header_10 *)image; fwu->img.checksum = le_to_uint(header->checksum); /* address of top level container */ offset = le_to_uint(header->top_level_container_start_addr); + if (!in_bounds(offset, sizeof(*descriptor), image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + offset); /* address of top level container content */ @@ -1187,13 +1232,20 @@ static void fwu_parse_image_header_10(void) num_of_containers = le_to_uint(descriptor->content_length) / 4; for (ii = 0; ii < num_of_containers; ii++) { + if (!in_bounds(offset, 4, image_size)) + return -EINVAL; addr = le_to_uint(image + offset); offset += 4; + if (!in_bounds(addr, sizeof(*descriptor), image_size)) + return -EINVAL; descriptor = (struct container_descriptor *)(image + addr); container_id = descriptor->container_id[0] | descriptor->container_id[1] << 8; - content = image + le_to_uint(descriptor->content_address); + content_offset = le_to_uint(descriptor->content_address); length = le_to_uint(descriptor->content_length); + if (!in_bounds(content_offset, length, image_size)) + return -EINVAL; + content = image + content_offset; switch (container_id) { case UI_CONTAINER: case CORE_CODE_CONTAINER: @@ -1209,12 +1261,14 @@ static void fwu_parse_image_header_10(void) fwu->img.bl_version = *content; fwu->img.bootloader.data = content; fwu->img.bootloader.size = length; - fwu_parse_image_header_10_bootloader(image); + if (fwu_parse_image_header_10_bootloader(image)) + return -EINVAL; break; case UTILITY_CONTAINER: fwu->img.utility.data = content; fwu->img.utility.size = length; - fwu_parse_image_header_10_utility(image); + if (fwu_parse_image_header_10_utility(image)) + return -EINVAL; break; case GUEST_CODE_CONTAINER: fwu->img.contains_guest_code = true; @@ -1239,6 +1293,8 @@ static void fwu_parse_image_header_10(void) break; case GENERAL_INFORMATION_CONTAINER: fwu->img.contains_firmware_id = true; + if (length < 4 + 4) + return -EINVAL; fwu->img.firmware_id = le_to_uint(content + 4); break; default: @@ -1246,10 +1302,10 @@ static void fwu_parse_image_header_10(void) } } - return; + return 0; } -static void fwu_parse_image_header_05_06(void) +static int fwu_parse_image_header_05_06(void) { int retval; const unsigned char *image; @@ -1257,6 +1313,8 @@ static void fwu_parse_image_header_05_06(void) struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; image = fwu->image; + if (fwu->image_size < sizeof(*header)) + return -EINVAL; header = (struct image_header_05_06 *)image; fwu->img.checksum = le_to_uint(header->checksum); @@ -1269,18 +1327,51 @@ static void fwu_parse_image_header_05_06(void) fwu->img.ui_firmware.size = le_to_uint(header->firmware_size); if (fwu->img.ui_firmware.size) { - fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET; - if (fwu->img.contains_bootloader) - fwu->img.ui_firmware.data += fwu->img.bootloader_size; + unsigned int ui_firmware_offset = IMAGE_AREA_OFFSET; + + if (fwu->img.contains_bootloader) { + if (!in_bounds(ui_firmware_offset, + fwu->img.bootloader_size, + fwu->image_size)) { + return -EINVAL; + } + ui_firmware_offset += fwu->img.bootloader_size; + } + if (!in_bounds(ui_firmware_offset, + fwu->img.ui_firmware.size, + fwu->image_size)) { + return -EINVAL; + } + fwu->img.ui_firmware.data = image + ui_firmware_offset; } - if ((fwu->img.bl_version == BL_V6) && header->options_tddi) + if ((fwu->img.bl_version == BL_V6) && header->options_tddi) { + if (!in_bounds(IMAGE_AREA_OFFSET, + fwu->img.ui_firmware.size, + fwu->image_size)) { + return -EINVAL; + } fwu->img.ui_firmware.data = image + IMAGE_AREA_OFFSET; + } fwu->img.ui_config.size = le_to_uint(header->config_size); if (fwu->img.ui_config.size) { - fwu->img.ui_config.data = fwu->img.ui_firmware.data + + unsigned int ui_firmware_end; + + if (fwu->img.ui_firmware.data < image) + return -EINVAL; + if (!in_bounds(fwu->img.ui_firmware.data - image, + fwu->img.ui_firmware.size, + fwu->image_size)) { + return -EINVAL; + } + ui_firmware_end = fwu->img.ui_firmware.data - image + fwu->img.ui_firmware.size; + if (!in_bounds(ui_firmware_end, fwu->img.ui_config.size, + fwu->image_size)) { + return -EINVAL; + } + fwu->img.ui_config.data = image + ui_firmware_end; } if ((fwu->img.bl_version == BL_V5 && fwu->img.contains_bootloader) || @@ -1292,6 +1383,11 @@ static void fwu_parse_image_header_05_06(void) if (fwu->img.contains_disp_config) { fwu->img.disp_config_offset = le_to_uint(header->dsp_cfg_addr); fwu->img.dp_config.size = le_to_uint(header->dsp_cfg_size); + if (!in_bounds(fwu->img.disp_config_offset, + fwu->img.dp_config.size, + fwu->image_size)) { + return -EINVAL; + } fwu->img.dp_config.data = image + fwu->img.disp_config_offset; } else { retval = secure_memcpy(fwu->img.cstmr_product_id, @@ -1323,28 +1419,41 @@ static void fwu_parse_image_header_05_06(void) } fwu->img.product_id[PRODUCT_ID_SIZE] = 0; + if (LOCKDOWN_SIZE > IMAGE_AREA_OFFSET) + return -EINVAL; + if (fwu->image_size < IMAGE_AREA_OFFSET) + return -EINVAL; fwu->img.lockdown.size = LOCKDOWN_SIZE; fwu->img.lockdown.data = image + IMAGE_AREA_OFFSET - LOCKDOWN_SIZE; - return; + return 0; } static int fwu_parse_image_info(void) { + int parse_retval; struct image_header_10 *header; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; + unsigned int image_size = 0; header = (struct image_header_10 *)fwu->image; - + if (!header) + return -EINVAL; + image_size = fwu->image_size; + if (image_size < sizeof(struct image_header_05_06) && + image_size < sizeof(struct image_header_10)) { + return -EINVAL; + } + /* This is clearing img, not image. */ memset(&fwu->img, 0x00, sizeof(fwu->img)); switch (header->major_header_version) { case IMAGE_HEADER_VERSION_10: - fwu_parse_image_header_10(); + parse_retval = fwu_parse_image_header_10(); break; case IMAGE_HEADER_VERSION_05: case IMAGE_HEADER_VERSION_06: - fwu_parse_image_header_05_06(); + parse_retval = fwu_parse_image_header_05_06(); break; default: dev_err(rmi4_data->pdev->dev.parent, @@ -1353,6 +1462,10 @@ static int fwu_parse_image_info(void) return -EINVAL; } + if (parse_retval != 0) { + return -EINVAL; + } + if (fwu->bl_version == BL_V7 || fwu->bl_version == BL_V8) { if (!fwu->img.contains_flash_config) { dev_err(rmi4_data->pdev->dev.parent, @@ -1361,9 +1474,12 @@ static int fwu_parse_image_info(void) return -EINVAL; } - fwu_parse_partition_table(fwu->img.fl_config.data, - &fwu->img.blkcount, &fwu->img.phyaddr); - + if (fwu_parse_partition_table(fwu->img.fl_config.data, + fwu->img.fl_config.size, + &fwu->img.blkcount, + &fwu->img.phyaddr)) { + return -EINVAL; + } fwu_compare_partition_tables(); } else { fwu->new_partition_table = false; @@ -1980,7 +2096,11 @@ static int fwu_read_f34_v7_queries(void) return retval; } - fwu_parse_partition_table(ptable, &fwu->blkcount, &fwu->phyaddr); + if (fwu_parse_partition_table(ptable, fwu->partition_table_bytes, + &fwu->blkcount, &fwu->phyaddr)) { + kfree(ptable); + return -EINVAL; + } if (fwu->blkcount.dp_config) fwu->flash_properties.has_disp_config = 1; @@ -3209,6 +3329,9 @@ static int fwu_write_utility_parameter(void) struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; utility_param_size = fwu->blkcount.utility_param * fwu->block_size; + /* See remaining_size below for reason for '4' */ + if (utility_param_size < 4) + return -EINVAL; retval = fwu_allocate_read_config_buf(utility_param_size); if (retval < 0) return retval; @@ -4910,6 +5033,7 @@ int synaptics_config_updater(struct synaptics_dsx_board_data *bdata) rmi4_data->stay_awake = true; + memset(config_id, 0, sizeof(config_id)); if (fwu->bl_version == BL_V7) config_id_size = V7_CONFIG_ID_SIZE; else @@ -4928,6 +5052,7 @@ int synaptics_config_updater(struct synaptics_dsx_board_data *bdata) } memset(str_buf, 0, sizeof(str_buf)); + memset(tmp_buf, 0, sizeof(tmp_buf)); for (ii = 0; ii < config_id_size; ii++) { snprintf(tmp_buf, 3, "%02x ", config_id[ii]); strlcat(str_buf, tmp_buf, sizeof(str_buf)); -- cgit v1.2.3 From bc461d914a255c09b22532b09b0c56a0e0c34f47 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 6 Jul 2015 23:18:37 +0300 Subject: BACKPORT: mm: avoid setting up anonymous pages into file mapping (cherry picked from commit 6b7339f4c31ad69c8e9c0b2859276e22cf72176d) Reading page fault handler code I've noticed that under right circumstances kernel would map anonymous pages into file mappings: if the VMA doesn't have vm_ops->fault() and the VMA wasn't fully populated on ->mmap(), kernel would handle page fault to not populated pte with do_anonymous_page(). Let's change page fault handler to use do_anonymous_page() only on anonymous VMA (->vm_ops == NULL) and make sure that the VMA is not shared. For file mappings without vm_ops->fault() or shred VMA without vm_ops, page fault on pte_none() entry would lead to SIGBUS. Signed-off-by: Kirill A. Shutemov Acked-by: Oleg Nesterov Cc: Andrew Morton Cc: Willy Tarreau Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds Change-Id: I451f90075ddf0c3592543e4fe30eed4c38348d49 Bug: 32460277 --- mm/memory.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 62b30f222c09..0abbdd28fe84 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2630,6 +2630,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, pte_unmap(page_table); + /* File mapping without ->vm_ops ? */ + if (vma->vm_flags & VM_SHARED) + return VM_FAULT_SIGBUS; + /* Check if we need to add a guard page to the stack */ if (check_stack_guard_page(vma, address) < 0) return VM_FAULT_SIGSEGV; @@ -3034,6 +3038,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma, - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; pte_unmap(page_table); + /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */ + if (!vma->vm_ops->fault) + return VM_FAULT_SIGBUS; if (!(flags & FAULT_FLAG_WRITE)) return do_read_fault(mm, vma, address, pmd, pgoff, flags, orig_pte); @@ -3199,11 +3206,10 @@ static int handle_pte_fault(struct mm_struct *mm, entry = ACCESS_ONCE(*pte); if (!pte_present(entry)) { if (pte_none(entry)) { - if (vma->vm_ops) { - if (likely(vma->vm_ops->fault)) - return do_linear_fault(mm, vma, address, + if (vma->vm_ops) + return do_linear_fault(mm, vma, address, pte, pmd, flags, entry); - } + return do_anonymous_page(mm, vma, address, pte, pmd, flags); } -- cgit v1.2.3 From 4dfe6e71e75c2c317930a8dc28b5973d8e79b867 Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Fri, 21 Oct 2016 14:17:14 -0700 Subject: qcacld-2.0: Fix hdd_ocb_config_new() signature hdd_ocb_config_new() takes four "length" parameters, currently defined to be of type 'int'. Since these are summed to calculate the size of a dynamic memory allocation they must be non-negative so change them to 'uint32_t'. Change-Id: Ie66bbb7c69aba92d9d846cb90628110b3bea8f74 CRs-Fixed: 1079596 Bug: 31750554 Signed-off-by: Srinivas Girigowda --- drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c index b6494ca47e4b..95fde5eca899 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_ocb.c @@ -406,10 +406,11 @@ static int hdd_ocb_register_sta(hdd_adapter_t *adapter) * * Return: A pointer to the OCB configuration struct, NULL on failure. */ -static struct sir_ocb_config *hdd_ocb_config_new(int num_channels, - int num_schedule, - int ndl_chan_list_len, - int ndl_active_state_list_len) +static +struct sir_ocb_config *hdd_ocb_config_new(uint32_t num_channels, + uint32_t num_schedule, + uint32_t ndl_chan_list_len, + uint32_t ndl_active_state_list_len) { struct sir_ocb_config *ret = 0; uint32_t len; @@ -903,7 +904,7 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy, void *def_tx_param = NULL; uint32_t def_tx_param_size = 0; int i; - int channel_count, schedule_size; + uint32_t channel_count, schedule_size; struct sir_ocb_config *config; int rc = -EINVAL; uint8_t *mac_addr; -- cgit v1.2.3 From 5f152221d508c641d1417f8569a4ade685f8a6e1 Mon Sep 17 00:00:00 2001 From: Ecco Park Date: Wed, 2 Nov 2016 10:12:02 -0700 Subject: qcacld-2.0: Use heap memory for station_info instead of stack From kernel 3.19-rc4, size of struct station_info is around 600 bytes, so stack frame size of such routine use this struct will easily exceed 1024 bytes, the default value of stack frame size. So use heap memory for this struct instead. CRs-Fixed: 1050323 Bug: 32506396 Change-Id: I12bb51839a7cf448e74dc5a6344f2809b808601c Signed-off-by: Ecco Park --- .../staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c | 17 ++++++++++++----- .../staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c index 9d7f5965eb76..f353888ebdef 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_assoc.c @@ -2744,7 +2744,7 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t case eCSR_ROAM_RESULT_IBSS_NEW_PEER: { hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); - struct station_info staInfo; + struct station_info *stainfo; pr_info ( "IBSS New Peer indication from SME " "with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d", @@ -2779,13 +2779,20 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t vosStatus, vosStatus ); } pHddStaCtx->ibss_sta_generation++; - memset(&staInfo, 0, sizeof(staInfo)); - staInfo.filled = 0; - staInfo.generation = pHddStaCtx->ibss_sta_generation; + stainfo = vos_mem_malloc(sizeof(*stainfo)); + if (stainfo == NULL) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "memory allocation for station_info failed"); + return eHAL_STATUS_FAILED_ALLOC; + } + memset(stainfo, 0, sizeof(*stainfo)); + stainfo->filled = 0; + stainfo->generation = pHddStaCtx->ibss_sta_generation; cfg80211_new_sta(pAdapter->dev, (const u8 *)pRoamInfo->peerMac, - &staInfo, GFP_KERNEL); + stainfo, GFP_KERNEL); + vos_mem_free(stainfo); if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType ||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c index 4ac29d461bfa..a1f30c238076 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c @@ -1825,21 +1825,27 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa HDD_SAP_WAKE_LOCK_DURATION, WIFI_POWER_EVENT_WAKELOCK_SAP); { - struct station_info staInfo; v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen; - memset(&staInfo, 0, sizeof(staInfo)); if (iesLen <= MAX_ASSOC_IND_IE_LEN ) { - staInfo.assoc_req_ies = + struct station_info *stainfo; + stainfo = vos_mem_malloc(sizeof(*stainfo)); + if (stainfo == NULL) { + hddLog(LOGE, FL("alloc station_info failed")); + return VOS_STATUS_E_NOMEM; + } + memset(stainfo, 0, sizeof(*stainfo)); + stainfo->assoc_req_ies = (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0]; - staInfo.assoc_req_ies_len = iesLen; + stainfo->assoc_req_ies_len = iesLen; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31)) || defined(WITH_BACKPORTS) - staInfo.filled |= STATION_INFO_ASSOC_REQ_IES; + stainfo->filled |= STATION_INFO_ASSOC_REQ_IES; #endif cfg80211_new_sta(dev, (const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0], - &staInfo, GFP_KERNEL); + stainfo, GFP_KERNEL); + vos_mem_free(stainfo); } else { -- cgit v1.2.3 From 1083ab0d8ffab2207535e20a0e645a332ae67766 Mon Sep 17 00:00:00 2001 From: Ecco Park Date: Fri, 4 Nov 2016 10:42:48 -0700 Subject: qcacld-2.0: Add check to Validate SSID length prima to qcacld-2.0 propagation. Validate ssid length before accessing the ssid if the length exceeds max ssid length then return. CRs-Fixed: 1059205 Bug: 32506333 Change-Id: I5b536863fbff34f3908cd5f462fbd7d9d2d78437 Signed-off-by: Ecco Park --- drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c index d9f4f1d368a8..0387b0dc11d5 100644 --- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -2871,7 +2871,7 @@ __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy, struct hdd_ext_scan_context *context; uint32_t request_id; char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1]; - int ssid_len; + int ssid_len, ssid_length; eHalStatus status; int i, rem, retval; unsigned long rc; @@ -2950,12 +2950,16 @@ __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy, hddLog(LOGE, FL("attr ssid failed")); goto fail; } - nla_memcpy(ssid_string, + ssid_length = nla_strlcpy(ssid_string, tb2[PARAM_SSID], sizeof(ssid_string)); hddLog(LOG1, FL("SSID %s"), ssid_string); ssid_len = strlen(ssid_string); + if (ssid_length > SIR_MAC_MAX_SSID_LENGTH) { + hddLog(LOGE, FL("Invalid ssid length")); + goto fail; + } memcpy(request->ssids[i].ssid.ssId, ssid_string, ssid_len); request->ssids[i].ssid.length = ssid_len; -- cgit v1.2.3 From 2c5c1fd0d2a2a96fab750fa332cb703022c16c04 Mon Sep 17 00:00:00 2001 From: John Dias Date: Wed, 9 Nov 2016 11:03:57 -0800 Subject: perf: don't leave group_entry on sibling list (use-after-free) When perf_group_detach is called on a group leader, it should empty its sibling list. Otherwise, when a sibling is later deallocated, list_del_event() removes the sibling's group_entry from its current list, which can be the now-deallocated group leader's sibling list (use-after-free bug). Bug: 32402548 Change-Id: I99f6bc97c8518df1cb0035814368012ba72ab1f1 Signed-off-by: John Dias --- kernel/events/core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c index 01eab13ec0e7..b7e1e224f07e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -1449,10 +1449,17 @@ static void perf_group_detach(struct perf_event *event) * If this was a group event with sibling events then * upgrade the siblings to singleton events by adding them * to whatever list we are on. + * If this isn't on a list, make sure we still remove the sibling's + * group_entry from this sibling_list; otherwise, when that sibling + * is later deallocated, it will try to remove itself from this + * sibling_list, which may well have been deallocated already, + * resulting in a use-after-free. */ list_for_each_entry_safe(sibling, tmp, &event->sibling_list, group_entry) { if (list) list_move_tail(&sibling->group_entry, list); + else + list_del_init(&sibling->group_entry); sibling->group_leader = sibling; /* Inherit group flags from the previous leader */ -- cgit v1.2.3 From c803e696475443b54006d1268fc1b98ceedbdacf Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 13 May 2016 09:34:12 -0400 Subject: UPSTREAM: ring-buffer: Prevent overflow of size in ring_buffer_resize() (Cherry picked from commit 59643d1535eb220668692a5359de22545af579f6) If the size passed to ring_buffer_resize() is greater than MAX_LONG - BUF_PAGE_SIZE then the DIV_ROUND_UP() will return zero. Here's the details: # echo 18014398509481980 > /sys/kernel/debug/tracing/buffer_size_kb tracing_entries_write() processes this and converts kb to bytes. 18014398509481980 << 10 = 18446744073709547520 and this is passed to ring_buffer_resize() as unsigned long size. size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); Where DIV_ROUND_UP(a, b) is (a + b - 1)/b BUF_PAGE_SIZE is 4080 and here 18446744073709547520 + 4080 - 1 = 18446744073709551599 where 18446744073709551599 is still smaller than 2^64 2^64 - 18446744073709551599 = 17 But now 18446744073709551599 / 4080 = 4521260802379792 and size = size * 4080 = 18446744073709551360 This is checked to make sure its still greater than 2 * 4080, which it is. Then we convert to the number of buffer pages needed. nr_page = DIV_ROUND_UP(size, BUF_PAGE_SIZE) but this time size is 18446744073709551360 and 2^64 - (18446744073709551360 + 4080 - 1) = -3823 Thus it overflows and the resulting number is less than 4080, which makes 3823 / 4080 = 0 an nr_pages is set to this. As we already checked against the minimum that nr_pages may be, this causes the logic to fail as well, and we crash the kernel. There's no reason to have the two DIV_ROUND_UP() (that's just result of historical code changes), clean up the code and fix this bug. Cc: stable@vger.kernel.org # 3.5+ Fixes: 83f40318dab00 ("ring-buffer: Make removal of ring buffer pages atomic") Signed-off-by: Steven Rostedt Signed-off-by: Willy Tarreau Change-Id: I1147672317a3ad0fc995b1f32baaa050a7976ac4 Bug: 32659848 --- kernel/trace/ring_buffer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0fc5cfedcc8c..7d370a6ebf18 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1693,14 +1693,13 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, !cpumask_test_cpu(cpu_id, buffer->cpumask)) return size; - size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); - size *= BUF_PAGE_SIZE; + nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); /* we need a minimum of two pages */ - if (size < BUF_PAGE_SIZE * 2) - size = BUF_PAGE_SIZE * 2; + if (nr_pages < 2) + nr_pages = 2; - nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); + size = nr_pages * BUF_PAGE_SIZE; /* * Don't succeed if resizing is disabled, as a reader might be -- cgit v1.2.3 From 0d37d64f02e18a301867ae7684c3801bd99c5df2 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Tue, 8 Nov 2016 20:12:16 +0100 Subject: Android: binder: check set_context_mgr permission on time. Bug: 32394425 Change-Id: I860c6aab97850bff05a56e96cd3f4b41691bfd96 Signed-off-by: Martijn Coenen --- drivers/staging/android/binder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index ad902dbac8fa..56f9713de523 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -2784,6 +2784,9 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) ret = -EBUSY; goto out; } + ret = security_binder_set_context_mgr(proc->tsk); + if (ret < 0) + goto out; if (uid_valid(binder_context_mgr_uid)) { if (!uid_eq(binder_context_mgr_uid, curr_euid)) { pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", @@ -2849,9 +2852,6 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = binder_ioctl_set_ctx_mgr(filp); if (ret) goto err; - ret = security_binder_set_context_mgr(proc->tsk); - if (ret < 0) - goto err; break; case BINDER_THREAD_EXIT: binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n", -- cgit v1.2.3