diff options
author | Steve Pfetsch <spfetsch@google.com> | 2017-09-14 04:39:40 -0700 |
---|---|---|
committer | Steve Pfetsch <spfetsch@google.com> | 2017-09-14 04:41:03 -0700 |
commit | 79df07b459c8364def0f57d711b05ca0d5d822b4 (patch) | |
tree | e4e30696f03e65ad863f25d779a10248b4d3a841 | |
parent | ad82c6620de6a51272076e3a8eec28f7173ffae5 (diff) | |
parent | 4b39d42e9b31b3cded28ba71d1d979a8ea70de37 (diff) |
Merge branch 'android-msm-angler-3.10-nyc-mr2' into android-msm-angler-3.10-ocandroid-8.0.0_r0.26
November 2017.1
Bug: 65558908
Change-Id: I1e61ece3bb2a4b7f88517b0ccfb00c0392c44d48
Signed-off-by: Steve Pfetsch <spfetsch@google.com>
22 files changed, 308 insertions, 129 deletions
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c index d2309c198864..2004e0ee3637 100644 --- a/drivers/char/diag/diag_masks.c +++ b/drivers/char/diag/diag_masks.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2014, 2017 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 @@ -248,7 +248,7 @@ static void diag_send_msg_mask_update(struct diag_smd_info *smd_info, uint8_t *buf = msg_mask.update_buf; uint8_t *temp = NULL; uint32_t mask_size = 0; - struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr; + struct diag_msg_mask_t *mask; struct diag_ctrl_msg_mask header; if (!smd_info) @@ -259,7 +259,8 @@ static void diag_send_msg_mask_update(struct diag_smd_info *smd_info, __func__, smd_info->peripheral); return; } - + mutex_lock(&driver->msg_mask_lock); + mask = (struct diag_msg_mask_t *)msg_mask.ptr; mutex_lock(&msg_mask.lock); switch (msg_mask.status) { case DIAG_CTRL_MASK_ALL_DISABLED: @@ -328,6 +329,7 @@ proceed: } err: mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); } static void diag_send_feature_mask_update(struct diag_smd_info *smd_info) @@ -394,7 +396,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, if (!diag_apps_responds()) return 0; - + mutex_lock(&driver->msg_mask_lock); rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE; rsp.status = MSG_STATUS_SUCCESS; @@ -415,6 +417,7 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len, memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range)); write_len += sizeof(ssid_range); } + mutex_unlock(&driver->msg_mask_lock); return write_len; } @@ -439,6 +442,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, if (!diag_apps_responds()) return 0; + mutex_lock(&driver->msg_mask_lock); req = (struct diag_build_mask_req_t *)src_buf; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_BUILD_MASK; @@ -469,6 +473,7 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len, } memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); + mutex_unlock(&driver->msg_mask_lock); return write_len; } @@ -491,7 +496,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, if (!diag_apps_responds()) return 0; - + mutex_lock(&driver->msg_mask_lock); req = (struct diag_build_mask_req_t *)src_buf; rsp.cmd_code = DIAG_CMD_MSG_CONFIG; rsp.sub_cmd = DIAG_CMD_OP_GET_MSG_MASK; @@ -517,6 +522,7 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len, } memcpy(dest_buf, &rsp, sizeof(rsp)); write_len += sizeof(rsp); + mutex_unlock(&driver->msg_mask_lock); return write_len; } @@ -541,7 +547,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, } req = (struct diag_msg_build_mask_t *)src_buf; - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_mask.lock); mask = (struct diag_msg_mask_t *)msg_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -574,6 +580,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len, break; } mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); diag_update_userspace_clients(MSG_MASKS_TYPE); @@ -620,7 +627,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, } req = (struct diag_msg_config_rsp_t *)src_buf; - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_mask.lock); msg_mask.status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED : DIAG_CTRL_MASK_ALL_DISABLED; @@ -629,6 +636,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len, mask->range * sizeof(uint32_t)); } mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); diag_update_userspace_clients(MSG_MASKS_TYPE); @@ -1037,6 +1045,7 @@ static int diag_create_msg_mask_table(void) struct diag_msg_mask_t *mask = (struct diag_msg_mask_t *)msg_mask.ptr; struct diag_ssid_range_t range; + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_mask.lock); driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT; for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -1047,6 +1056,8 @@ static int diag_create_msg_mask_table(void) break; } mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); + return err; } @@ -1059,6 +1070,7 @@ static int diag_create_build_time_mask(void) struct diag_msg_mask_t *build_mask = NULL; struct diag_ssid_range_t range; + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_bt_mask.lock); build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr; for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) { @@ -1172,6 +1184,7 @@ static int diag_create_build_time_mask(void) memcpy(build_mask->ptr, tbl, tbl_size); } mutex_unlock(&msg_bt_mask.lock); + mutex_unlock(&driver->msg_mask_lock); return err; } @@ -1242,10 +1255,12 @@ static int diag_msg_mask_init(void) pr_err("diag: Unable to create msg masks, err: %d\n", err); return err; } + mutex_lock(&driver->msg_mask_lock); driver->msg_mask = &msg_mask; for (i = 0; i < NUM_SMD_CONTROL_CHANNELS; i++) driver->max_ssid_count[i] = 0; + mutex_unlock(&driver->msg_mask_lock); return 0; } @@ -1255,14 +1270,17 @@ static void diag_msg_mask_exit(void) int i; struct diag_msg_mask_t *mask = NULL; + mutex_lock(&driver->msg_mask_lock); mask = (struct diag_msg_mask_t *)(msg_mask.ptr); if (mask) { for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) kfree(mask->ptr); kfree(msg_mask.ptr); + msg_mask.ptr = NULL; } - kfree(msg_mask.update_buf); + msg_mask.update_buf = NULL; + mutex_unlock(&driver->msg_mask_lock); } static int diag_build_time_mask_init(void) @@ -1287,13 +1305,15 @@ static void diag_build_time_mask_exit(void) { int i; struct diag_msg_mask_t *mask = NULL; - + mutex_lock(&driver->msg_mask_lock); mask = (struct diag_msg_mask_t *)(msg_bt_mask.ptr); if (mask) { - for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) + for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, mask++) kfree(mask->ptr); - kfree(msg_mask.ptr); + kfree(msg_bt_mask.ptr); + msg_bt_mask.ptr = NULL; } + mutex_unlock(&driver->msg_mask_lock); } static int diag_log_mask_init(void) @@ -1367,7 +1387,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count) if (!buf || count == 0) return -EINVAL; - + mutex_lock(&driver->msg_mask_lock); mutex_lock(&msg_mask.lock); mask = (struct diag_msg_mask_t *)(msg_mask.ptr); for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) { @@ -1402,6 +1422,7 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count) total_len += len; } mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); return err ? err : total_len; } diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h index df3d92a90568..a0a0546b006d 100644 --- a/drivers/char/diag/diagchar.h +++ b/drivers/char/diag/diagchar.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2017, 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 @@ -470,8 +470,10 @@ struct diagchar_dev { struct diag_mask_info *event_mask; struct diag_mask_info *build_time_mask; uint8_t msg_mask_tbl_count; + uint8_t bt_msg_mask_tbl_count; uint16_t event_mask_size; uint16_t last_event_id; + struct mutex msg_mask_lock; /* Variables for Mask Centralization */ uint16_t num_event_id[NUM_SMD_CONTROL_CHANNELS]; uint32_t num_equip_id[NUM_SMD_CONTROL_CHANNELS]; diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c index cbd6f0ec851e..d510af49f503 100644 --- a/drivers/char/diag/diagchar_core.c +++ b/drivers/char/diag/diagchar_core.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2015, 2017 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 @@ -2324,6 +2324,7 @@ static int __init diagchar_init(void) buf_hdlc_ctxt = SET_BUF_CTXT(APPS_DATA, SMD_DATA_TYPE, 1); mutex_init(&driver->diagchar_mutex); mutex_init(&driver->delayed_rsp_mutex); + mutex_init(&driver->msg_mask_lock); init_waitqueue_head(&driver->wait_q); init_waitqueue_head(&driver->smd_wait_q); INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn); diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c index 5f0ec31facf9..f60b9a9dc0e9 100644 --- a/drivers/char/diag/diagfwd_cntl.c +++ b/drivers/char/diag/diagfwd_cntl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017 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 @@ -396,8 +396,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len, ptr += header_len; /* Don't account for pkt_id and length */ read_len += header_len - (2 * sizeof(uint32_t)); - - mutex_lock(&msg_mask.lock); + mutex_lock(&driver->msg_mask_lock); driver->max_ssid_count[smd_info->peripheral] = header->count; for (i = 0; i < header->count && read_len < len; i++) { ssid_range = (struct diag_ssid_range_t *)ptr; @@ -439,7 +438,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len, } driver->msg_mask_tbl_count += 1; } - mutex_unlock(&msg_mask.lock); + mutex_unlock(&driver->msg_mask_lock); } static void diag_build_time_mask_update(uint8_t *buf, @@ -464,12 +463,11 @@ static void diag_build_time_mask_update(uint8_t *buf, __func__, range->ssid_first, range->ssid_last); return; } - + mutex_lock(&driver->msg_mask_lock); build_mask = (struct diag_msg_mask_t *)(driver->build_time_mask->ptr); num_items = range->ssid_last - range->ssid_first + 1; - mutex_lock(&driver->build_time_mask->lock); - for (i = 0; i < driver->msg_mask_tbl_count; i++, build_mask++) { + for (i = 0; i < driver->bt_msg_mask_tbl_count; i++, build_mask++) { if (build_mask->ssid_first != range->ssid_first) continue; found = 1; @@ -486,7 +484,7 @@ static void diag_build_time_mask_update(uint8_t *buf, if (found) goto end; - new_size = (driver->msg_mask_tbl_count + 1) * + new_size = (driver->bt_msg_mask_tbl_count + 1) * sizeof(struct diag_msg_mask_t); temp = krealloc(driver->build_time_mask->ptr, new_size, GFP_KERNEL); if (!temp) { @@ -501,9 +499,10 @@ static void diag_build_time_mask_update(uint8_t *buf, __func__, err); goto end; } - driver->msg_mask_tbl_count += 1; + driver->bt_msg_mask_tbl_count += 1; end: - mutex_unlock(&driver->build_time_mask->lock); + mutex_unlock(&driver->msg_mask_lock); + return; } static void process_build_mask_report(uint8_t *buf, uint32_t len, diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 85975052f035..87a6b9e39918 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1609,6 +1609,7 @@ static void _kgsl_cmdbatch_timer(unsigned long data) struct kgsl_device *device; struct kgsl_cmdbatch *cmdbatch = (struct kgsl_cmdbatch *) data; struct kgsl_cmdbatch_sync_event *event; + unsigned long flags; if (cmdbatch == NULL || cmdbatch->context == NULL) return; @@ -1623,14 +1624,14 @@ static void _kgsl_cmdbatch_timer(unsigned long data) kgsl_context_dump(cmdbatch->context); clear_bit(CMDBATCH_FLAG_FENCE_LOG, &cmdbatch->priv); - spin_lock(&cmdbatch->lock); + spin_lock_irqsave(&cmdbatch->lock, flags); /* Print all the fences */ list_for_each_entry(event, &cmdbatch->synclist, node) { if (KGSL_CMD_SYNCPOINT_TYPE_FENCE == event->type && event->handle && event->handle->fence) kgsl_sync_fence_log(event->handle->fence); } - spin_unlock(&cmdbatch->lock); + spin_unlock_irqrestore(&cmdbatch->lock, flags); dev_err(device->dev, "--gpu syncpoint deadlock print end--\n"); } /** @@ -1685,15 +1686,16 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device, struct kgsl_cmdbatch_sync_event *event) { struct kgsl_cmdbatch_sync_event *e, *tmp; + unsigned long flags; int sched = 0; int removed = 0; /* - * We may have cmdbatch timer running, which also uses same lock, - * take a lock with software interrupt disabled (bh) to avoid - * spin lock recursion. + * cmdbatch timer or event callback might run at + * this time in interrupt context and uses same lock. + * So use irq-save version of spin lock. */ - spin_lock_bh(&event->cmdbatch->lock); + spin_lock_irqsave(&event->cmdbatch->lock, flags); /* * sync events that are contained by a cmdbatch which has been @@ -1708,8 +1710,9 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device, } } + event->handle = NULL; sched = list_empty(&event->cmdbatch->synclist) ? 1 : 0; - spin_unlock_bh(&event->cmdbatch->lock); + spin_unlock_irqrestore(&event->cmdbatch->lock, flags); /* If the list is empty delete the canary timer */ if (sched) @@ -1771,16 +1774,20 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch) struct kgsl_cmdbatch_sync_event *event, *tmpsync; LIST_HEAD(cancel_synclist); int sched = 0; + unsigned long flags; /* Zap the canary timer */ del_timer_sync(&cmdbatch->timer); - /* non-bh because we just destroyed timer */ - spin_lock(&cmdbatch->lock); + /* + * callback might run in interrupt context + * so need to use irqsave version of spinlocks. + */ + spin_lock_irqsave(&cmdbatch->lock, flags); /* Empty the synclist before canceling events */ list_splice_init(&cmdbatch->synclist, &cancel_synclist); - spin_unlock(&cmdbatch->lock); + spin_unlock_irqrestore(&cmdbatch->lock, flags); /* * Finish canceling events outside the cmdbatch spinlock and @@ -1802,8 +1809,15 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch) kgsl_cmdbatch_sync_func, event); } else if (event->type == KGSL_CMD_SYNCPOINT_TYPE_FENCE) { /* Put events that are successfully canceled */ - if (kgsl_sync_fence_async_cancel(event->handle)) + spin_lock_irqsave(&cmdbatch->lock, flags); + + if (kgsl_sync_fence_async_cancel(event->handle)) { + event->handle = NULL; + spin_unlock_irqrestore(&cmdbatch->lock, flags); kgsl_cmdbatch_sync_event_put(event); + } else { + spin_unlock_irqrestore(&cmdbatch->lock, flags); + } } /* Put events that have been removed from the synclist */ @@ -1864,6 +1878,7 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device, { struct kgsl_cmd_syncpoint_fence *sync = priv; struct kgsl_cmdbatch_sync_event *event; + unsigned long flags; event = kzalloc(sizeof(*event), GFP_KERNEL); @@ -1892,11 +1907,6 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device, kref_get(&event->refcount); - /* non-bh because, we haven't started cmdbatch timer yet */ - spin_lock(&cmdbatch->lock); - list_add(&event->node, &cmdbatch->synclist); - spin_unlock(&cmdbatch->lock); - /* * Increment the reference count for the async callback. * Decrement when the callback is successfully canceled, when @@ -1904,6 +1914,10 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device, */ kref_get(&event->refcount); + + spin_lock_irqsave(&cmdbatch->lock, flags); + list_add(&event->node, &cmdbatch->synclist); + event->handle = kgsl_sync_fence_async_wait(sync->fd, kgsl_cmdbatch_sync_fence_func, event); @@ -1911,17 +1925,14 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device, int ret = PTR_ERR(event->handle); event->handle = NULL; - - /* Failed to add the event to the async callback */ - kgsl_cmdbatch_sync_event_put(event); - /* Remove event from the synclist */ - spin_lock(&cmdbatch->lock); list_del(&event->node); - spin_unlock(&cmdbatch->lock); + spin_unlock_irqrestore(&cmdbatch->lock, flags); + /* Put for event removal from the synclist */ kgsl_cmdbatch_sync_event_put(event); - - /* Event no longer needed by this function */ + /* Unable to add event to the async callback so a put */ + kgsl_cmdbatch_sync_event_put(event); + /* Put since event no longer needed by this function */ kgsl_cmdbatch_sync_event_put(event); /* @@ -1935,6 +1946,7 @@ static int kgsl_cmdbatch_add_sync_fence(struct kgsl_device *device, } trace_syncpoint_fence(cmdbatch, event->handle->name); + spin_unlock_irqrestore(&cmdbatch->lock, flags); /* * Event was successfully added to the synclist, the async diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c index a5ea27ad0e16..f580edf1c87c 100644 --- a/drivers/input/misc/keychord.c +++ b/drivers/input/misc/keychord.c @@ -300,8 +300,10 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer, ret = input_register_handler(&kdev->input_handler); if (ret) { - kfree(keychords); + spin_lock_irqsave(&kdev->lock, flags); + kfree(kdev->keychords); kdev->keychords = 0; + spin_unlock_irqrestore(&kdev->lock, flags); return ret; } kdev->registered = 1; 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 43a2c77dcc8d..490ab13e4e60 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 @@ -817,6 +817,12 @@ int msm_isp_update_stats_stream(struct vfe_device *vfe_dev, void *arg) struct msm_vfe_axi_stream_cfg_update_info *update_info = NULL; struct msm_isp_sw_framskip *sw_skip_info = NULL; + if (update_cmd->num_streams > MSM_ISP_STATS_MAX) { + pr_err("%s: Invalid num_streams %d\n", + __func__, update_cmd->num_streams); + return -EINVAL; + } + /*validate request*/ for (i = 0; i < update_cmd->num_streams; i++) { update_info = &update_cmd->update_info[i]; diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c index e517f0f589ce..47ba2f99dd00 100644 --- a/drivers/media/platform/msm/camera_v2/msm.c +++ b/drivers/media/platform/msm/camera_v2/msm.c @@ -334,6 +334,11 @@ static void msm_add_sd_in_position(struct msm_sd_subdev *msm_subdev, struct msm_sd_subdev *temp_sd; list_for_each_entry(temp_sd, sd_list, list) { + if (temp_sd == msm_subdev) { + pr_err("%s :Fail to add the same sd %d\n", + __func__, __LINE__); + return; + } if (msm_subdev->close_seq < temp_sd->close_seq) { list_add_tail(&msm_subdev->list, &temp_sd->list); return; 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 1dfe7f6abc31..9d7e51c37f48 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 @@ -2288,11 +2288,13 @@ static void msm_cpp_fw_version(struct cpp_device *cpp_dev) msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER); } -static int msm_cpp_validate_input(unsigned int cmd, void *arg, +static int msm_cpp_validate_ioctl_input(unsigned int cmd, void *arg, struct msm_camera_v4l2_ioctl_t **ioctl_ptr) { switch (cmd) { case MSM_SD_SHUTDOWN: + case VIDIOC_MSM_CPP_IOMMU_ATTACH: + case VIDIOC_MSM_CPP_IOMMU_DETACH: break; default: { if (ioctl_ptr == NULL) { @@ -2301,8 +2303,9 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg, } *ioctl_ptr = arg; - if ((*ioctl_ptr == NULL) || - (*ioctl_ptr)->ioctl_ptr == NULL) { + if (((*ioctl_ptr) == NULL) || + ((*ioctl_ptr)->ioctl_ptr == NULL) || + ((*ioctl_ptr)->len == 0)) { pr_err("Error invalid ioctl argument cmd %u", cmd); return -EINVAL; } @@ -2334,7 +2337,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, return -EINVAL; } - rc = msm_cpp_validate_input(cmd, arg, &ioctl_ptr); + rc = msm_cpp_validate_ioctl_input(cmd, arg, &ioctl_ptr); if (rc != 0) { pr_err("input validation failed\n"); return rc; @@ -2799,6 +2802,7 @@ STREAM_BUFF_END: pr_err("%s:%dError iommu_attach_device failed\n", __func__, __LINE__); rc = -EINVAL; + break; } cpp_dev->iommu_state = CPP_IOMMU_STATE_ATTACHED; } else { @@ -2813,10 +2817,17 @@ STREAM_BUFF_END: (cpp_dev->stream_cnt == 0)) { iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx); + if (rc < 0) { + pr_err("%s:%dError iommu detach failed\n", + __func__, __LINE__); + rc = -EINVAL; + break; + } cpp_dev->iommu_state = CPP_IOMMU_STATE_DETACHED; } else { pr_err("%s:%d IOMMMU attach triggered in invalid state\n", __func__, __LINE__); + rc = -EINVAL; } break; } @@ -3422,7 +3433,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file, default: pr_err_ratelimited("%s: unsupported compat type :%x LOAD %lu\n", __func__, cmd, VIDIOC_MSM_CPP_LOAD_FIRMWARE); - break; + return -EINVAL; } switch (cmd) { @@ -3448,7 +3459,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file, default: pr_err_ratelimited("%s: unsupported compat type :%d\n", __func__, cmd); - break; + return -EINVAL; } up32_ioctl.id = kp_ioctl.id; 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 877021edc776..4243005beff5 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 @@ -17,7 +17,8 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) #define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args) - +#define MAX_I2C_ADDR_TYPE_SIZE (MSM_CAMERA_I2C_3B_ADDR + 1) +#define MAX_I2C_DATA_TYPE_SIZE (MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA + 1) #define I2C_COMPARE_MATCH 0 #define I2C_COMPARE_MISMATCH 1 #define I2C_POLL_MAX_ITERATION 20 @@ -27,7 +28,7 @@ int32_t msm_camera_cci_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[MAX_I2C_ADDR_TYPE_SIZE + MAX_I2C_DATA_TYPE_SIZE]; struct msm_camera_cci_ctrl cci_ctrl; if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c index 5d3c56191e0d..bd376ffa28c1 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2015,2017 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 @@ -103,7 +103,11 @@ static int32_t msm_sensor_driver_create_i2c_v4l_subdev s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; s_ctrl->sensordata->sensor_info->session_id = session_id; s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; - msm_sd_register(&s_ctrl->msm_sd); + rc = msm_sd_register(&s_ctrl->msm_sd); + if (rc < 0) { + pr_err("failed: msm_sd_register rc %d", rc); + return rc; + } CDBG("%s:%d\n", __func__, __LINE__); return rc; } @@ -133,7 +137,11 @@ static int32_t msm_sensor_driver_create_v4l_subdev s_ctrl->msm_sd.sd.entity.group_id = MSM_CAMERA_SUBDEV_SENSOR; s_ctrl->msm_sd.sd.entity.name = s_ctrl->msm_sd.sd.name; s_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x3; - msm_sd_register(&s_ctrl->msm_sd); + rc = msm_sd_register(&s_ctrl->msm_sd); + if (rc < 0) { + pr_err("failed: msm_sd_register rc %d", rc); + return rc; + } msm_sensor_v4l2_subdev_fops = v4l2_subdev_fops; #ifdef CONFIG_COMPAT msm_sensor_v4l2_subdev_fops.compat_ioctl32 = @@ -886,12 +894,6 @@ int32_t msm_sensor_driver_probe(void *setting, pr_err("%s probe succeeded", slave_info->sensor_name); /* - Set probe succeeded flag to 1 so that no other camera shall - * probed on this slot - */ - s_ctrl->is_probe_succeed = 1; - - /* * Update the subdevice id of flash-src based on availability in kernel. */ if (slave_info->is_flash_supported == 0) { @@ -940,6 +942,11 @@ int32_t msm_sensor_driver_probe(void *setting, msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name); + /* + * Set probe succeeded flag to 1 so that no other camera shall + * probed on this slot + */ + s_ctrl->is_probe_succeed = 1; return rc; camera_power_down: diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c index 3f7819694dca..abda82a7f8c0 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c +++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c @@ -148,6 +148,8 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, case AUDIO_START: { pr_debug("%s: AUDIO_START\n", __func__); + mutex_lock(&effects->lock); + rc = q6asm_open_read_write_v2(effects->ac, FORMAT_LINEAR_PCM, FORMAT_MULTI_CHANNEL_LINEAR_PCM, @@ -159,6 +161,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, pr_err("%s: Open failed for hw accelerated effects:rc=%d\n", __func__, rc); rc = -EINVAL; + mutex_unlock(&effects->lock); goto ioctl_fail; } effects->opened = 1; @@ -175,6 +178,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, pr_err("%s: Write buffer Allocation failed rc = %d\n", __func__, rc); rc = -ENOMEM; + mutex_unlock(&effects->lock); goto ioctl_fail; } atomic_set(&effects->in_count, effects->config.input.num_buf); @@ -185,6 +189,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, pr_err("%s: Read buffer Allocation failed rc = %d\n", __func__, rc); rc = -ENOMEM; + mutex_unlock(&effects->lock); goto readbuf_fail; } atomic_set(&effects->out_count, effects->config.output.num_buf); @@ -199,6 +204,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, if (rc < 0) { pr_err("%s: pcm read block config failed\n", __func__); rc = -EINVAL; + mutex_unlock(&effects->lock); goto cfg_fail; } pr_debug("%s: dec: sample_rate: %d, num_channels: %d, bit_width: %d\n", @@ -213,6 +219,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, pr_err("%s: pcm write format block config failed\n", __func__); rc = -EINVAL; + mutex_unlock(&effects->lock); goto cfg_fail; } @@ -225,6 +232,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, effects->started = 0; pr_err("%s: ASM run state failed\n", __func__); } + mutex_unlock(&effects->lock); break; } case AUDIO_EFFECTS_WRITE: { @@ -286,8 +294,11 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, uint32_t idx = 0; uint32_t size = 0; + mutex_lock(&effects->lock); + if (!effects->started) { rc = -EFAULT; + mutex_unlock(&effects->lock); goto ioctl_fail; } @@ -304,11 +315,13 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, if (!rc) { pr_err("%s: read wait_event_timeout\n", __func__); rc = -EFAULT; + mutex_unlock(&effects->lock); goto ioctl_fail; } if (!atomic_read(&effects->in_count)) { pr_err("%s: pcm stopped in_count 0\n", __func__); rc = -EFAULT; + mutex_unlock(&effects->lock); goto ioctl_fail; } @@ -316,15 +329,18 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd, if (bufptr) { if (!((void *)arg)) { rc = -EFAULT; + mutex_unlock(&effects->lock); goto ioctl_fail; } if ((effects->config.buf_cfg.input_len > size) || copy_to_user((void *)arg, bufptr, effects->config.buf_cfg.input_len)) { rc = -EFAULT; + mutex_unlock(&effects->lock); goto ioctl_fail; } } + mutex_unlock(&effects->lock); break; } default: @@ -447,6 +463,7 @@ static long audio_effects_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case AUDIO_SET_EFFECTS_CONFIG: { pr_debug("%s: AUDIO_SET_EFFECTS_CONFIG\n", __func__); + mutex_lock(&effects->lock); memset(&effects->config, 0, sizeof(effects->config)); if (copy_from_user(&effects->config, (void *)arg, sizeof(effects->config))) { @@ -464,6 +481,7 @@ static long audio_effects_ioctl(struct file *file, unsigned int cmd, effects->config.input.num_buf, effects->config.input.sample_rate, effects->config.input.num_channels); + mutex_unlock(&effects->lock); break; } case AUDIO_EFFECTS_SET_BUF_LEN: { @@ -485,6 +503,7 @@ static long audio_effects_ioctl(struct file *file, unsigned int cmd, buf_avail.input_num_avail = atomic_read(&effects->in_count); buf_avail.output_num_avail = atomic_read(&effects->out_count); + mutex_lock(&effects->lock); pr_debug("%s: write buf avail: %d, read buf avail: %d\n", __func__, buf_avail.output_num_avail, buf_avail.input_num_avail); @@ -494,16 +513,20 @@ static long audio_effects_ioctl(struct file *file, unsigned int cmd, __func__); rc = -EFAULT; } + mutex_unlock(&effects->lock); break; } case AUDIO_EFFECTS_SET_PP_PARAMS: { + mutex_lock(&effects->lock); if (copy_from_user(argvalues, (void *)arg, MAX_PP_PARAMS_SZ*sizeof(long))) { pr_err("%s: copy from user for pp params failed\n", __func__); + mutex_unlock(&effects->lock); return -EFAULT; } rc = audio_effects_set_pp_param(effects, argvalues); + mutex_unlock(&effects->lock); break; } default: @@ -569,12 +592,14 @@ static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, case AUDIO_SET_EFFECTS_CONFIG32: { struct msm_hwacc_effects_config32 config32; struct msm_hwacc_effects_config *config = &effects->config; + mutex_lock(&effects->lock); memset(&effects->config, 0, sizeof(effects->config)); if (copy_from_user(&config32, (void *)arg, sizeof(config32))) { pr_err("%s: copy to user for AUDIO_SET_EFFECTS_CONFIG failed\n", __func__); rc = -EFAULT; + mutex_unlock(&effects->lock); break; } config->input.buf_size = config32.input.buf_size; @@ -611,16 +636,19 @@ static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, effects->config.input.num_buf, effects->config.input.sample_rate, effects->config.input.num_channels); + mutex_unlock(&effects->lock); break; } case AUDIO_EFFECTS_SET_BUF_LEN32: { struct msm_hwacc_buf_cfg32 buf_cfg32; struct msm_hwacc_effects_config *config = &effects->config; + mutex_lock(&effects->lock); if (copy_from_user(&buf_cfg32, (void *)arg, sizeof(buf_cfg32))) { pr_err("%s: copy from user for AUDIO_EFFECTS_SET_BUF_LEN failed\n", __func__); rc = -EFAULT; + mutex_unlock(&effects->lock); break; } config->buf_cfg.input_len = buf_cfg32.input_len; @@ -628,6 +656,7 @@ static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, pr_debug("%s: write buf len: %d, read buf len: %d\n", __func__, effects->config.buf_cfg.output_len, effects->config.buf_cfg.input_len); + mutex_unlock(&effects->lock); break; } case AUDIO_EFFECTS_GET_BUF_AVAIL32: { @@ -635,6 +664,7 @@ static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, memset(&buf_avail, 0, sizeof(buf_avail)); + mutex_lock(&effects->lock); 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", @@ -646,22 +676,26 @@ static long audio_effects_compat_ioctl(struct file *file, unsigned int cmd, __func__); rc = -EFAULT; } + mutex_unlock(&effects->lock); break; } case AUDIO_EFFECTS_SET_PP_PARAMS32: { long argvalues[MAX_PP_PARAMS_SZ] = {0}; int argvalues32[MAX_PP_PARAMS_SZ] = {0}; + mutex_lock(&effects->lock); if (copy_from_user(argvalues32, (void *)arg, MAX_PP_PARAMS_SZ*sizeof(int))) { pr_err("%s: copy from user failed for pp params\n", __func__); + mutex_unlock(&effects->lock); return -EFAULT; } for (i = 0; i < MAX_PP_PARAMS_SZ; i++) argvalues[i] = argvalues32[i]; rc = audio_effects_set_pp_param(effects, argvalues); + mutex_unlock(&effects->lock); break; } case AUDIO_START32: { diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c index f44d4dcb9075..826b508d0799 100644 --- a/drivers/net/usb/rmnet_usb_ctrl.c +++ b/drivers/net/usb/rmnet_usb_ctrl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2014, 2017, 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 @@ -514,8 +514,13 @@ static int rmnet_ctl_open(struct inode *inode, struct file *file) if (!dev) return -ENODEV; - if (test_bit(RMNET_CTRL_DEV_OPEN, &dev->status)) + mutex_lock(&dev->dev_lock); + if (test_bit(RMNET_CTRL_DEV_OPEN, &dev->status)) { + mutex_unlock(&dev->dev_lock); goto already_opened; + } + set_bit(RMNET_CTRL_DEV_OPEN, &dev->status); + mutex_unlock(&dev->dev_lock); if (dev->mdm_wait_timeout && !test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) { @@ -527,10 +532,15 @@ static int rmnet_ctl_open(struct inode *inode, struct file *file) if (retval == 0) { dev_err(dev->devicep, "%s: Timeout opening %s\n", __func__, dev->name); - return -ETIMEDOUT; - } else if (retval < 0) { + retval = -ETIMEDOUT; + } else if (retval < 0) dev_err(dev->devicep, "%s: Error waiting for %s\n", __func__, dev->name); + + if (retval < 0) { + mutex_lock(&dev->dev_lock); + clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status); + mutex_unlock(&dev->dev_lock); return retval; } } @@ -538,14 +548,15 @@ static int rmnet_ctl_open(struct inode *inode, struct file *file) if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) { dev_dbg(dev->devicep, "%s: Connection timedout opening %s\n", __func__, dev->name); + mutex_lock(&dev->dev_lock); + clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status); + mutex_unlock(&dev->dev_lock); return -ETIMEDOUT; } /* clear stale data if device close called but channel was ready */ rmnet_usb_ctrl_free_rx_list(dev); - set_bit(RMNET_CTRL_DEV_OPEN, &dev->status); - file->private_data = dev; already_opened: @@ -564,7 +575,9 @@ static int rmnet_ctl_release(struct inode *inode, struct file *file) DBG("%s Called on %s device\n", __func__, dev->name); + mutex_lock(&dev->dev_lock); clear_bit(RMNET_CTRL_DEV_OPEN, &dev->status); + mutex_unlock(&dev->dev_lock); file->private_data = NULL; @@ -638,6 +651,7 @@ ctrl_read: list_elem = list_first_entry(&dev->rx_list, struct ctrl_pkt_list_elem, list); + list_del(&list_elem->list); bytes_to_read = (uint32_t)(list_elem->cpkt.data_size); if (bytes_to_read > count) { spin_unlock_irqrestore(&dev->rx_lock, flags); @@ -654,11 +668,11 @@ ctrl_read: dev_err(dev->devicep, "%s: copy_to_user failed for %s\n", __func__, dev->name); + spin_lock_irqsave(&dev->rx_lock, flags); + list_add(&list_elem->list, &dev->rx_list); + spin_unlock_irqrestore(&dev->rx_lock, flags); return -EFAULT; } - spin_lock_irqsave(&dev->rx_lock, flags); - list_del(&list_elem->list); - spin_unlock_irqrestore(&dev->rx_lock, flags); kfree(list_elem->cpkt.data); kfree(list_elem); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 301e572e8923..3bc0413eca5a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4019,6 +4019,11 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_KERNEL); } else if (ieee80211_is_action(mgmt->frame_control)) { + if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) { + brcmf_err("invalid action frame length\n"); + err = -EINVAL; + goto exit; + } af_params = kzalloc(sizeof(*af_params), GFP_KERNEL); if (af_params == NULL) { brcmf_err("unable to allocate frame\n"); diff --git a/drivers/video/msm/mdss/mdss_hdmi_cec.c b/drivers/video/msm/mdss/mdss_hdmi_cec.c index e31602d77375..1be8c42cfe79 100644 --- a/drivers/video/msm/mdss/mdss_hdmi_cec.c +++ b/drivers/video/msm/mdss/mdss_hdmi_cec.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2017, 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 @@ -25,8 +25,9 @@ /* Reference: HDMI 1.4a Specification section 7.1 */ #define RETRANSMIT_MAX_NUM 5 -#define MAX_OPERAND_SIZE 15 - +#define MAX_OPERAND_SIZE 14 +/* total size: HEADER block (1) + opcode block (1) + operands (14) */ +#define MAX_CEC_FRAME_SIZE (MAX_OPERAND_SIZE + 2) /* * Ref. HDMI 1.4a: Supplement-1 CEC Section 6, 7 */ @@ -422,7 +423,8 @@ static void hdmi_cec_msg_recv(struct work_struct *work) msg_node->msg.sender_id, msg_node->msg.recvr_id, msg_node->msg.frame_size); - if (msg_node->msg.frame_size < 1) { + if (msg_node->msg.frame_size < 1 + || msg_node->msg.frame_size > MAX_CEC_FRAME_SIZE) { DEV_ERR("%s: invalid message (frame length = %d)", __func__, msg_node->msg.frame_size); kfree(msg_node); @@ -444,7 +446,7 @@ static void hdmi_cec_msg_recv(struct work_struct *work) msg_node->msg.operand[i] = data & 0xFF; } - for (; i < 14; i++) + for (; i < MAX_OPERAND_SIZE; i++) msg_node->msg.operand[i] = 0; DEV_DBG("%s: CEC read frame done\n", __func__); diff --git a/include/linux/pid.h b/include/linux/pid.h index a089a3c447fc..ed7b1f731923 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -8,7 +8,9 @@ enum pid_type PIDTYPE_PID, PIDTYPE_PGID, PIDTYPE_SID, - PIDTYPE_MAX + PIDTYPE_MAX, + /* only valid to __task_pid_nr_ns() */ + __PIDTYPE_TGID }; /* diff --git a/include/linux/sched.h b/include/linux/sched.h index d5b92dfa84ba..edf89a981c7e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1665,13 +1665,6 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) return tsk->tgid; } -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - -static inline pid_t task_tgid_vnr(struct task_struct *tsk) -{ - return pid_vnr(task_tgid(tsk)); -} - static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) @@ -1696,6 +1689,16 @@ static inline pid_t task_session_vnr(struct task_struct *tsk) return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); } +static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) +{ + return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns); +} + +static inline pid_t task_tgid_vnr(struct task_struct *tsk) +{ + return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL); +} + /* obsolete, do not use */ static inline pid_t task_pgrp_nr(struct task_struct *tsk) { diff --git a/kernel/events/core.c b/kernel/events/core.c index f3208e2c2a75..fbe06b9e1b9e 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6942,6 +6942,37 @@ static void mutex_lock_double(struct mutex *a, struct mutex *b) mutex_lock_nested(b, SINGLE_DEPTH_NESTING); } +/* + * Variation on perf_event_ctx_lock_nested(), except we take two context + * mutexes. + */ +static struct perf_event_context * +__perf_event_ctx_lock_double(struct perf_event *group_leader, + struct perf_event_context *ctx) +{ + struct perf_event_context *gctx; + +again: + rcu_read_lock(); + gctx = READ_ONCE(group_leader->ctx); + if (!atomic_inc_not_zero(&gctx->refcount)) { + rcu_read_unlock(); + goto again; + } + rcu_read_unlock(); + + mutex_lock_double(&gctx->mutex, &ctx->mutex); + + if (group_leader->ctx != gctx) { + mutex_unlock(&ctx->mutex); + mutex_unlock(&gctx->mutex); + put_ctx(gctx); + goto again; + } + + return gctx; +} + /** * sys_perf_event_open - open a performance event, associate it to a task/cpu * @@ -7156,14 +7187,31 @@ SYSCALL_DEFINE5(perf_event_open, } if (move_group) { - gctx = group_leader->ctx; + gctx = __perf_event_ctx_lock_double(group_leader, ctx); + + /* + * Check if we raced against another sys_perf_event_open() call + * moving the software group underneath us. + */ + if (!(group_leader->group_flags & PERF_GROUP_SOFTWARE)) { + /* + * If someone moved the group out from under us, check + * if this new event wound up on the same ctx, if so + * its the regular !move_group case, otherwise fail. + */ + if (gctx != ctx) { + err = -EINVAL; + goto err_locked; + } else { + perf_event_ctx_unlock(group_leader, gctx); + move_group = 0; + } + } /* * See perf_event_ctx_lock() for comments on the details * of swizzling perf_event::ctx. */ - mutex_lock_double(&gctx->mutex, &ctx->mutex); - perf_remove_from_context(group_leader, false); /* @@ -7205,7 +7253,7 @@ SYSCALL_DEFINE5(perf_event_open, perf_unpin_context(ctx); if (move_group) { - mutex_unlock(&gctx->mutex); + perf_event_ctx_unlock(group_leader, gctx); put_ctx(gctx); } mutex_unlock(&ctx->mutex); @@ -7236,6 +7284,11 @@ SYSCALL_DEFINE5(perf_event_open, fd_install(event_fd, event_file); return event_fd; +err_locked: + if (move_group) + perf_event_ctx_unlock(group_leader, gctx); + mutex_unlock(&ctx->mutex); + fput(event_file); err_context: perf_unpin_context(ctx); put_ctx(ctx); diff --git a/kernel/pid.c b/kernel/pid.c index 43f22f451bd5..054389f18fbe 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -522,8 +522,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, if (!ns) ns = task_active_pid_ns(current); if (likely(pid_alive(task))) { - if (type != PIDTYPE_PID) + if (type != PIDTYPE_PID) { + if (type == __PIDTYPE_TGID) + type = PIDTYPE_PID; task = task->group_leader; + } nr = pid_nr_ns(task->pids[type].pid, ns); } rcu_read_unlock(); @@ -532,12 +535,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, } EXPORT_SYMBOL(__task_pid_nr_ns); -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return pid_nr_ns(task_tgid(tsk), ns); -} -EXPORT_SYMBOL(task_tgid_nr_ns); - struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) { return ns_of_pid(task_pid(tsk)); diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8485de2bd1da..4cca5fd91f33 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -310,8 +310,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, [NL80211_ATTR_PID] = { .type = NLA_U32 }, [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, - [NL80211_ATTR_PMKID] = { .type = NLA_BINARY, - .len = WLAN_PMKID_LEN }, + [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN }, [NL80211_ATTR_DURATION] = { .type = NLA_U32 }, [NL80211_ATTR_COOKIE] = { .type = NLA_U64 }, [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED }, @@ -366,6 +365,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 }, [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, + [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 }, [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 }, [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 }, diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 0ad1231c1537..6548b3af383f 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -150,7 +150,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card, err = -ENXIO; goto _error; } + mutex_lock(&pcm->open_mutex); err = snd_pcm_info_user(substream, info); + mutex_unlock(&pcm->open_mutex); _error: mutex_unlock(®ister_mutex); return err; diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c index 2bcd339f1ff5..95c382ddb77b 100644 --- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c @@ -175,7 +175,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -203,7 +203,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT STRENGTH", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -231,7 +231,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT OUT_TYPE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -259,7 +259,7 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "VIRT GAIN_ADJUST", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_VIRTUALIZER; *updt_params++ = @@ -338,7 +338,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -366,7 +366,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_MODE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -394,7 +394,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_PRESET", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -422,7 +422,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_WET_MIX", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -450,7 +450,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_GAIN_ADJUST", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -478,7 +478,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ROOM_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -506,7 +506,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_ROOM_HF_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -534,7 +534,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DECAY_TIME", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -562,7 +562,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DECAY_HF_RATIO", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -590,7 +590,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_REFLECTIONS_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -618,7 +618,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_REFLECTIONS_DELAY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -646,7 +646,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_LEVEL", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -674,7 +674,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DELAY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -702,7 +702,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DIFFUSION", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -730,7 +730,7 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "REVERB_DENSITY", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_REVERB; *updt_params++ = @@ -810,7 +810,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -838,7 +838,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_MODE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -866,7 +866,7 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "BASS_BOOST_STRENGTH", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_BASS_BOOST; *updt_params++ = @@ -947,7 +947,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_ENABLE", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1015,7 +1015,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_CONFIG", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1066,7 +1066,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_BAND_INDEX", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1098,7 +1098,7 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, MAX_INBAND_PARAM_SZ, "EQ_SINGLE_BAND_FREQ", rc); if (rc != 0) - break; + goto invalid_config; *updt_params++ = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; *updt_params++ = @@ -1188,7 +1188,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_2CH", rc); if (rc != 0) - break; + goto invalid_config; if (instance == SOFT_VOLUME_INSTANCE_2) *updt_params++ = ASM_MODULE_ID_VOL_CTRL2; @@ -1237,7 +1237,7 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, "VOLUME/VOLUME2_GAIN_MASTER", rc); if (rc != 0) - break; + goto invalid_config; if (instance == SOFT_VOLUME_INSTANCE_2) *updt_params++ = ASM_MODULE_ID_VOL_CTRL2; |