aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Pfetsch <spfetsch@google.com>2017-09-14 04:39:40 -0700
committerSteve Pfetsch <spfetsch@google.com>2017-09-14 04:41:03 -0700
commit79df07b459c8364def0f57d711b05ca0d5d822b4 (patch)
treee4e30696f03e65ad863f25d779a10248b4d3a841
parentad82c6620de6a51272076e3a8eec28f7173ffae5 (diff)
parent4b39d42e9b31b3cded28ba71d1d979a8ea70de37 (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>
-rw-r--r--drivers/char/diag/diag_masks.c45
-rw-r--r--drivers/char/diag/diagchar.h4
-rw-r--r--drivers/char/diag/diagchar_core.c3
-rw-r--r--drivers/char/diag/diagfwd_cntl.c19
-rw-r--r--drivers/gpu/msm/kgsl.c60
-rw-r--r--drivers/input/misc/keychord.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c6
-rw-r--r--drivers/media/platform/msm/camera_v2/msm.c5
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c23
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c5
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c25
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c34
-rw-r--r--drivers/net/usb/rmnet_usb_ctrl.c32
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c5
-rw-r--r--drivers/video/msm/mdss/mdss_hdmi_cec.c12
-rw-r--r--include/linux/pid.h4
-rw-r--r--include/linux/sched.h17
-rw-r--r--kernel/events/core.c61
-rw-r--r--kernel/pid.c11
-rw-r--r--net/wireless/nl80211.c4
-rw-r--r--sound/core/pcm.c2
-rw-r--r--sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c56
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(&register_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;