Merge branch 'android-msm-marlin-3.18-nyc-mr2' into android-msm-marlin-3.18-oc

November 2017.1

Bug: 65558892
Change-Id: I416cc8f5064539eeb8d39234c009a549aca5945d
Signed-off-by: Andrew Lehmer <alehmer@google.com>
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index f6709fa..64d5b43 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2016, 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
@@ -308,7 +308,12 @@
 	if (!mask_info)
 		return;
 
+	mutex_lock(&driver->msg_mask_lock);
 	mask = (struct diag_msg_mask_t *)mask_info->ptr;
+	if (!mask->ptr) {
+		mutex_unlock(&driver->msg_mask_lock);
+		return;
+	}
 	buf = mask_info->update_buf;
 	mutex_lock(&mask_info->lock);
 	switch (mask_info->status) {
@@ -381,6 +386,7 @@
 	}
 err:
 	mutex_unlock(&mask_info->lock);
+	mutex_unlock(&driver->msg_mask_lock);
 }
 
 static void diag_send_time_sync_update(uint8_t peripheral)
@@ -493,6 +499,7 @@
 	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;
@@ -500,7 +507,6 @@
 	rsp.count = driver->msg_mask_tbl_count;
 	memcpy(dest_buf, &rsp, sizeof(rsp));
 	write_len += sizeof(rsp);
-
 	mask_ptr = (struct diag_msg_mask_t *)mask_info->ptr;
 	for (i = 0; i <  driver->msg_mask_tbl_count; i++, mask_ptr++) {
 		if (write_len + sizeof(ssid_range) > dest_len) {
@@ -513,6 +519,7 @@
 		memcpy(dest_buf + write_len, &ssid_range, sizeof(ssid_range));
 		write_len += sizeof(ssid_range);
 	}
+	mutex_unlock(&driver->msg_mask_lock);
 
 	return write_len;
 }
@@ -538,6 +545,7 @@
 	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;
@@ -545,9 +553,8 @@
 	rsp.ssid_last = req->ssid_last;
 	rsp.status = MSG_STATUS_FAIL;
 	rsp.padding = 0;
-
 	build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
-	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 != req->ssid_first)
 			continue;
 		num_entries = req->ssid_last - req->ssid_first + 1;
@@ -568,6 +575,7 @@
 	}
 	memcpy(dest_buf, &rsp, sizeof(rsp));
 	write_len += sizeof(rsp);
+	mutex_unlock(&driver->msg_mask_lock);
 
 	return write_len;
 }
@@ -596,6 +604,7 @@
 	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;
@@ -603,7 +612,6 @@
 	rsp.ssid_last = req->ssid_last;
 	rsp.status = MSG_STATUS_FAIL;
 	rsp.padding = 0;
-
 	mask = (struct diag_msg_mask_t *)mask_info->ptr;
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
 		if ((req->ssid_first < mask->ssid_first) ||
@@ -621,6 +629,7 @@
 	}
 	memcpy(dest_buf, &rsp, sizeof(rsp));
 	write_len += sizeof(rsp);
+	mutex_unlock(&driver->msg_mask_lock);
 
 	return write_len;
 }
@@ -652,7 +661,7 @@
 	}
 
 	req = (struct diag_msg_build_mask_t *)src_buf;
-
+	mutex_lock(&driver->msg_mask_lock);
 	mutex_lock(&mask_info->lock);
 	mask = (struct diag_msg_mask_t *)mask_info->ptr;
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -712,6 +721,7 @@
 		break;
 	}
 	mutex_unlock(&mask_info->lock);
+	mutex_unlock(&driver->msg_mask_lock);
 
 	if (diag_check_update(APPS_DATA))
 		diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -766,6 +776,7 @@
 
 	req = (struct diag_msg_config_rsp_t *)src_buf;
 
+	mutex_lock(&driver->msg_mask_lock);
 	mask = (struct diag_msg_mask_t *)mask_info->ptr;
 	mutex_lock(&mask_info->lock);
 	mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
@@ -777,6 +788,7 @@
 		mutex_unlock(&mask->lock);
 	}
 	mutex_unlock(&mask_info->lock);
+	mutex_unlock(&driver->msg_mask_lock);
 
 	if (diag_check_update(APPS_DATA))
 		diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -1280,6 +1292,7 @@
 	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++) {
@@ -1290,6 +1303,8 @@
 			break;
 	}
 	mutex_unlock(&msg_mask.lock);
+	mutex_unlock(&driver->msg_mask_lock);
+
 	return err;
 }
 
@@ -1302,9 +1317,11 @@
 	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);
+	driver->bt_msg_mask_tbl_count = MSG_MASK_TBL_CNT;
 	build_mask = (struct diag_msg_mask_t *)msg_bt_mask.ptr;
-	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++) {
 		range.ssid_first = msg_mask_tbl[i].ssid_first;
 		range.ssid_last = msg_mask_tbl[i].ssid_last;
 		err = diag_create_msg_mask_table_entry(build_mask, &range);
@@ -1415,6 +1432,7 @@
 		memcpy(build_mask->ptr, tbl, tbl_size);
 	}
 	mutex_unlock(&msg_bt_mask.lock);
+	mutex_unlock(&driver->msg_mask_lock);
 
 	return err;
 }
@@ -1562,10 +1580,11 @@
 		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_PERIPHERALS; i++)
 		driver->max_ssid_count[i] = 0;
+	mutex_unlock(&driver->msg_mask_lock);
 
 	return 0;
 }
@@ -1584,7 +1603,7 @@
 	err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE);
 	if (err)
 		return err;
-
+	mutex_lock(&driver->msg_mask_lock);
 	mutex_lock(&dest->lock);
 	src_mask = (struct diag_msg_mask_t *)src->ptr;
 	dest_mask = (struct diag_msg_mask_t *)dest->ptr;
@@ -1603,6 +1622,7 @@
 		dest_mask++;
 	}
 	mutex_unlock(&dest->lock);
+	mutex_unlock(&driver->msg_mask_lock);
 
 	return err;
 }
@@ -1614,7 +1634,7 @@
 
 	if (!mask_info)
 		return;
-
+	mutex_lock(&driver->msg_mask_lock);
 	mutex_lock(&mask_info->lock);
 	mask = (struct diag_msg_mask_t *)mask_info->ptr;
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1622,7 +1642,7 @@
 		mask->ptr = NULL;
 	}
 	mutex_unlock(&mask_info->lock);
-
+	mutex_unlock(&driver->msg_mask_lock);
 	__diag_mask_exit(mask_info);
 }
 
@@ -1630,15 +1650,17 @@
 {
 	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)
@@ -1663,13 +1685,15 @@
 {
 	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)
@@ -1787,7 +1811,7 @@
 		return -EIO;
 	}
 	mutex_unlock(&driver->diag_maskclear_mutex);
-
+	mutex_lock(&driver->msg_mask_lock);
 	mutex_lock(&mask_info->lock);
 	mask = (struct diag_msg_mask_t *)(mask_info->ptr);
 	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1826,6 +1850,7 @@
 		total_len += len;
 	}
 	mutex_unlock(&mask_info->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 4333119..c1749d3 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -537,6 +537,7 @@
 	unsigned char *buf_feature_mask_update;
 	uint8_t hdlc_disabled;
 	struct mutex hdlc_disable_mutex;
+	struct mutex hdlc_recovery_mutex;
 	struct timer_list hdlc_reset_timer;
 	struct mutex diag_hdlc_mutex;
 	unsigned char *hdlc_buf;
@@ -582,8 +583,10 @@
 	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_PERIPHERALS];
 	uint32_t num_equip_id[NUM_PERIPHERALS];
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 10a38dc..048e1fd 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -3390,7 +3390,9 @@
 	mutex_init(&driver->diag_file_mutex);
 	mutex_init(&driver->delayed_rsp_mutex);
 	mutex_init(&apps_data_mutex);
+	mutex_init(&driver->msg_mask_lock);
 	mutex_init(&driver->diagfwd_channel_mutex);
+	mutex_init(&driver->hdlc_recovery_mutex);
 	init_waitqueue_head(&driver->wait_q);
 	INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn);
 	INIT_WORK(&(driver->update_user_clients),
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 65bbe7c..60d126a 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2016, 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
@@ -1348,7 +1348,9 @@
 
 	if (start_ptr) {
 		/* Discard any partial packet reads */
+		mutex_lock(&driver->hdlc_recovery_mutex);
 		driver->incoming_pkt.processing = 0;
+		mutex_unlock(&driver->hdlc_recovery_mutex);
 		diag_process_non_hdlc_pkt(start_ptr, len - i, info);
 	}
 }
@@ -1362,18 +1364,24 @@
 	const uint32_t header_len = sizeof(struct diag_pkt_frame_t);
 	struct diag_pkt_frame_t *actual_pkt = NULL;
 	unsigned char *data_ptr = NULL;
-	struct diag_partial_pkt_t *partial_pkt = &driver->incoming_pkt;
+	struct diag_partial_pkt_t *partial_pkt = NULL;
 
-	if (!buf || len <= 0)
+	mutex_lock(&driver->hdlc_recovery_mutex);
+	if (!buf || len <= 0) {
+		mutex_unlock(&driver->hdlc_recovery_mutex);
 		return;
-
-	if (!partial_pkt->processing)
+	}
+	partial_pkt = &driver->incoming_pkt;
+	if (!partial_pkt->processing) {
+		mutex_unlock(&driver->hdlc_recovery_mutex);
 		goto start;
+	}
 
 	if (partial_pkt->remaining > len) {
 		if ((partial_pkt->read_len + len) > partial_pkt->capacity) {
 			pr_err("diag: Invalid length %d, %d received in %s\n",
 			       partial_pkt->read_len, len, __func__);
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			goto end;
 		}
 		memcpy(partial_pkt->data + partial_pkt->read_len, buf, len);
@@ -1387,6 +1395,7 @@
 			pr_err("diag: Invalid length during partial read %d, %d received in %s\n",
 			       partial_pkt->read_len,
 			       partial_pkt->remaining, __func__);
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			goto end;
 		}
 		memcpy(partial_pkt->data + partial_pkt->read_len, buf,
@@ -1400,20 +1409,27 @@
 	if (partial_pkt->remaining == 0) {
 		actual_pkt = (struct diag_pkt_frame_t *)(partial_pkt->data);
 		data_ptr = partial_pkt->data + header_len;
-		if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR)
+		if (*(uint8_t *)(data_ptr + actual_pkt->length) !=
+						CONTROL_CHAR) {
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			diag_hdlc_start_recovery(buf, len, info);
+			mutex_lock(&driver->hdlc_recovery_mutex);
+		}
 		err = diag_process_apps_pkt(data_ptr,
 					    actual_pkt->length, info);
 		if (err) {
 			pr_err("diag: In %s, unable to process incoming data packet, err: %d\n",
 			       __func__, err);
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			goto end;
 		}
 		partial_pkt->read_len = 0;
 		partial_pkt->total_len = 0;
 		partial_pkt->processing = 0;
+		mutex_unlock(&driver->hdlc_recovery_mutex);
 		goto start;
 	}
+	mutex_unlock(&driver->hdlc_recovery_mutex);
 	goto end;
 
 start:
@@ -1426,14 +1442,14 @@
 			diag_send_error_rsp(buf, len);
 			goto end;
 		}
-
+		mutex_lock(&driver->hdlc_recovery_mutex);
 		if (pkt_len + header_len > partial_pkt->capacity) {
 			pr_err("diag: In %s, incoming data is too large for the request buffer %d\n",
 			       __func__, pkt_len);
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			diag_hdlc_start_recovery(buf, len, info);
 			break;
 		}
-
 		if ((pkt_len + header_len) > (len - read_bytes)) {
 			partial_pkt->read_len = len - read_bytes;
 			partial_pkt->total_len = pkt_len + header_len;
@@ -1441,19 +1457,27 @@
 						 partial_pkt->read_len;
 			partial_pkt->processing = 1;
 			memcpy(partial_pkt->data, buf, partial_pkt->read_len);
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			break;
 		}
 		data_ptr = buf + header_len;
-		if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR)
+		if (*(uint8_t *)(data_ptr + actual_pkt->length) !=
+						CONTROL_CHAR) {
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			diag_hdlc_start_recovery(buf, len, info);
+			mutex_lock(&driver->hdlc_recovery_mutex);
+		}
 		else
 			hdlc_reset = 0;
 		err = diag_process_apps_pkt(data_ptr,
 					    actual_pkt->length, info);
-		if (err)
+		if (err) {
+			mutex_unlock(&driver->hdlc_recovery_mutex);
 			break;
+		}
 		read_bytes += header_len + pkt_len + 1;
 		buf += header_len + pkt_len + 1; /* advance to next pkt */
+		mutex_unlock(&driver->hdlc_recovery_mutex);
 	}
 end:
 	return;
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 594d3b1..410790e 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -508,6 +508,7 @@
 	/* Don't account for pkt_id and length */
 	read_len += header_len - (2 * sizeof(uint32_t));
 
+	mutex_lock(&driver->msg_mask_lock);
 	driver->max_ssid_count[peripheral] = header->count;
 	for (i = 0; i < header->count && read_len < len; i++) {
 		ssid_range = (struct diag_ssid_range_t *)ptr;
@@ -551,6 +552,7 @@
 		}
 		driver->msg_mask_tbl_count += 1;
 	}
+	mutex_unlock(&driver->msg_mask_lock);
 }
 
 static void diag_build_time_mask_update(uint8_t *buf,
@@ -575,11 +577,11 @@
 		       __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;
 
-	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;
@@ -598,7 +600,7 @@
 
 	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) {
@@ -613,8 +615,10 @@
 		       __func__, err);
 		goto end;
 	}
-	driver->msg_mask_tbl_count += 1;
+	driver->bt_msg_mask_tbl_count += 1;
 end:
+	mutex_unlock(&driver->msg_mask_lock);
+
 	return;
 }
 
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index 680827e..28e8e8f 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,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
@@ -131,6 +131,8 @@
 static void sync_event_print(struct seq_file *s,
 		struct kgsl_cmdbatch_sync_event *sync_event)
 {
+	unsigned long flags;
+
 	switch (sync_event->type) {
 	case KGSL_CMD_SYNCPOINT_TYPE_TIMESTAMP: {
 		seq_printf(s, "sync: ctx: %d ts: %d",
@@ -138,9 +140,13 @@
 		break;
 	}
 	case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
+		spin_lock_irqsave(&sync_event->handle_lock, flags);
+
 		seq_printf(s, "sync: [%pK] %s", sync_event->handle,
 		(sync_event->handle && sync_event->handle->fence)
 				? sync_event->handle->fence->name : "NULL");
+
+		spin_unlock_irqrestore(&sync_event->handle_lock, flags);
 		break;
 	default:
 		seq_printf(s, "sync: type: %d", sync_event->type);
diff --git a/drivers/gpu/msm/kgsl_cmdbatch.c b/drivers/gpu/msm/kgsl_cmdbatch.c
index 6272410..c2683d0 100644
--- a/drivers/gpu/msm/kgsl_cmdbatch.c
+++ b/drivers/gpu/msm/kgsl_cmdbatch.c
@@ -57,6 +57,7 @@
 {
 	struct kgsl_cmdbatch_sync_event *event;
 	unsigned int i;
+	unsigned long flags;
 
 	for (i = 0; i < cmdbatch->numsyncs; i++) {
 		event = &cmdbatch->synclist[i];
@@ -79,12 +80,16 @@
 			break;
 		}
 		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
+			spin_lock_irqsave(&event->handle_lock, flags);
+
 			if (event->handle)
 				dev_err(device->dev, "  fence: [%pK] %s\n",
 					event->handle->fence,
 					event->handle->name);
 			else
 				dev_err(device->dev, "  fence: invalid\n");
+
+			spin_unlock_irqrestore(&event->handle_lock, flags);
 			break;
 		}
 	}
@@ -96,6 +101,7 @@
 	struct kgsl_cmdbatch *cmdbatch = (struct kgsl_cmdbatch *) data;
 	struct kgsl_cmdbatch_sync_event *event;
 	unsigned int i;
+	unsigned long flags;
 
 	if (cmdbatch == NULL || cmdbatch->context == NULL)
 		return;
@@ -124,12 +130,16 @@
 				i, event->context->id, event->timestamp);
 			break;
 		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
+			spin_lock_irqsave(&event->handle_lock, flags);
+
 			if (event->handle != NULL) {
 				dev_err(device->dev, "       [%d] FENCE %s\n",
 				i, event->handle->fence ?
 					event->handle->fence->name : "NULL");
 				kgsl_sync_fence_log(event->handle->fence);
 			}
+
+			spin_unlock_irqrestore(&event->handle_lock, flags);
 			break;
 		}
 	}
@@ -221,7 +231,7 @@
 void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch)
 {
 	unsigned int i;
-	unsigned long pending;
+	unsigned long pending, flags;
 
 	if (IS_ERR_OR_NULL(cmdbatch))
 		return;
@@ -255,8 +265,17 @@
 				kgsl_cmdbatch_sync_func, event);
 			break;
 		case KGSL_CMD_SYNCPOINT_TYPE_FENCE:
-			if (kgsl_sync_fence_async_cancel(event->handle))
+			spin_lock_irqsave(&event->handle_lock, flags);
+
+			if (kgsl_sync_fence_async_cancel(event->handle)) {
+				event->handle = NULL;
+				spin_unlock_irqrestore(
+						&event->handle_lock, flags);
 				kgsl_cmdbatch_put(cmdbatch);
+			} else {
+				spin_unlock_irqrestore(
+						&event->handle_lock, flags);
+			}
 			break;
 		}
 	}
@@ -293,12 +312,23 @@
  */
 static void kgsl_cmdbatch_sync_fence_func(void *priv)
 {
+	unsigned long flags;
 	struct kgsl_cmdbatch_sync_event *event = priv;
 
+	kgsl_cmdbatch_sync_expire(event->device, event);
+
 	trace_syncpoint_fence_expire(event->cmdbatch,
 		event->handle ? event->handle->name : "unknown");
 
-	kgsl_cmdbatch_sync_expire(event->device, event);
+	spin_lock_irqsave(&event->handle_lock, flags);
+
+	/*
+	 * Setting the event->handle to NULL here make sure that
+	 * other function does not dereference a invalid pointer.
+	 */
+	event->handle = NULL;
+
+	spin_unlock_irqrestore(&event->handle_lock, flags);
 
 	kgsl_cmdbatch_put(event->cmdbatch);
 }
@@ -316,6 +346,7 @@
 	struct kgsl_cmd_syncpoint_fence *sync = priv;
 	struct kgsl_cmdbatch_sync_event *event;
 	unsigned int id;
+	unsigned long flags;
 
 	kref_get(&cmdbatch->refcount);
 
@@ -329,7 +360,9 @@
 	event->device = device;
 	event->context = NULL;
 
+	spin_lock_init(&event->handle_lock);
 	set_bit(event->id, &cmdbatch->pending);
+	spin_lock_irqsave(&event->handle_lock, flags);
 
 	event->handle = kgsl_sync_fence_async_wait(sync->fd,
 		kgsl_cmdbatch_sync_fence_func, event);
@@ -337,9 +370,10 @@
 	if (IS_ERR_OR_NULL(event->handle)) {
 		int ret = PTR_ERR(event->handle);
 
-		clear_bit(event->id, &cmdbatch->pending);
 		event->handle = NULL;
+		spin_unlock_irqrestore(&event->handle_lock, flags);
 
+		clear_bit(event->id, &cmdbatch->pending);
 		kgsl_cmdbatch_put(cmdbatch);
 
 		/*
@@ -350,6 +384,8 @@
 			trace_syncpoint_fence_expire(cmdbatch, "signaled");
 
 		return ret;
+	} else {
+		spin_unlock_irqrestore(&event->handle_lock, flags);
 	}
 
 	trace_syncpoint_fence(cmdbatch, event->handle->name);
diff --git a/drivers/gpu/msm/kgsl_cmdbatch.h b/drivers/gpu/msm/kgsl_cmdbatch.h
index d5cbf37..b37f432 100644
--- a/drivers/gpu/msm/kgsl_cmdbatch.h
+++ b/drivers/gpu/msm/kgsl_cmdbatch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2016, 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
@@ -84,6 +84,7 @@
  * @context: Pointer to the KGSL context that owns the cmdbatch
  * @timestamp: Pending timestamp for the event
  * @handle: Pointer to a sync fence handle
+ * @handle_lock: Spin lock to protect handle
  * @device: Pointer to the KGSL device
  */
 struct kgsl_cmdbatch_sync_event {
@@ -93,6 +94,7 @@
 	struct kgsl_context *context;
 	unsigned int timestamp;
 	struct kgsl_sync_fence_waiter *handle;
+	spinlock_t handle_lock;
 	struct kgsl_device *device;
 };
 
diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c
index a5ea27a..f580edf 100644
--- a/drivers/input/misc/keychord.c
+++ b/drivers/input/misc/keychord.c
@@ -300,8 +300,10 @@
 
 	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_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 739bcbc..d01e829 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -3488,6 +3488,14 @@
 	case UPDATE_STREAM_REQUEST_FRAMES_VER2: {
 		struct msm_vfe_axi_stream_cfg_update_info_req_frm *req_frm =
 			&update_cmd->req_frm_ver2;
+		if (HANDLE_TO_IDX(req_frm->stream_handle) >= VFE_AXI_SRC_MAX) {
+			pr_err("%s: Invalid stream handle \n", __func__);
+			rc = -EINVAL;
+			break;
+		}
+		stream_info = &axi_data->stream_info[HANDLE_TO_IDX(
+			req_frm->stream_handle)];
+
 		rc = msm_isp_request_frame(vfe_dev, stream_info,
 			req_frm->user_stream_id,
 			req_frm->frame_id,
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 697b3f7..ca37cc8 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
@@ -886,6 +886,12 @@
 	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 = (struct msm_vfe_axi_stream_cfg_update_info *)
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index 6747cec..715898c 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -383,6 +383,11 @@
 	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 4bf05de..7f7a5ce 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
@@ -2696,13 +2696,15 @@
 	return rc;
 }
 
-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 MSM_SD_NOTIFY_FREEZE:
 	case MSM_SD_UNNOTIFY_FREEZE:
+	case VIDIOC_MSM_CPP_IOMMU_ATTACH:
+	case VIDIOC_MSM_CPP_IOMMU_DETACH:
 		break;
 	default: {
 		if (ioctl_ptr == NULL) {
@@ -2711,8 +2713,9 @@
 		}
 
 		*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;
 		}
@@ -2744,7 +2747,7 @@
 		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;
@@ -3234,7 +3237,7 @@
 			(cpp_dev->stream_cnt == 0)) {
 			rc = cam_smmu_ops(cpp_dev->iommu_hdl, CAM_SMMU_DETACH);
 			if (rc < 0) {
-				pr_err("%s:%dError iommu atach failed\n",
+				pr_err("%s:%dError iommu detach failed\n",
 					__func__, __LINE__);
 				rc = -EINVAL;
 				break;
@@ -3243,6 +3246,7 @@
 		} else {
 			pr_err("%s:%d IOMMMU attach triggered in invalid state\n",
 				__func__, __LINE__);
+			rc = -EINVAL;
 		}
 		break;
 	}
@@ -3869,7 +3873,8 @@
 	default:
 		pr_err_ratelimited("%s: unsupported compat type :%x LOAD %lu\n",
 				__func__, cmd, VIDIOC_MSM_CPP_LOAD_FIRMWARE);
-		break;
+		mutex_unlock(&cpp_dev->mutex);
+		return -EINVAL;
 	}
 
 	mutex_unlock(&cpp_dev->mutex);
@@ -3900,7 +3905,7 @@
 	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 be7954c..260c8a3 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
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -17,13 +17,15 @@
 #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)
 
 int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
 	uint32_t addr, uint16_t *data,
 	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 a9a8682..da8cd4f 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
@@ -105,7 +105,11 @@
 	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;
+	}
 	msm_sensor_v4l2_subdev_fops = v4l2_subdev_fops;
 #ifdef CONFIG_COMPAT
 	msm_sensor_v4l2_subdev_fops.compat_ioctl32 =
@@ -142,7 +146,11 @@
 	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_cam_copy_v4l2_subdev_fops(&msm_sensor_v4l2_subdev_fops);
 #ifdef CONFIG_COMPAT
 	msm_sensor_v4l2_subdev_fops.compat_ioctl32 =
@@ -891,12 +899,6 @@
 	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 (strlen(slave_info->flash_name) == 0) {
@@ -948,6 +950,11 @@
 
 	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 bb4d710..6e8e00e 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
@@ -148,6 +148,8 @@
 	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 @@
 			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 @@
 			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 @@
 			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 @@
 		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 @@
 			pr_err("%s: pcm write format block config failed\n",
 				__func__);
 			rc = -EINVAL;
+			mutex_unlock(&effects->lock);
 			goto cfg_fail;
 		}
 
@@ -225,6 +232,7 @@
 			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 @@
 		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 @@
 		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 @@
 		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:
@@ -456,6 +472,7 @@
 	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))) {
@@ -473,6 +490,7 @@
 			 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: {
@@ -494,6 +512,7 @@
 
 		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);
@@ -503,16 +522,20 @@
 				__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:
@@ -578,12 +601,14 @@
 	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;
@@ -620,16 +645,19 @@
 			 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;
@@ -637,6 +665,7 @@
 		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: {
@@ -644,6 +673,7 @@
 
 		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",
@@ -655,22 +685,26 @@
 				__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/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 8a69d00..b471fa37 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4109,6 +4109,11 @@
 		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/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c
index 17695ce..56fed65 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_wext.c
@@ -12143,6 +12143,10 @@
     {   WE_DUMP_DP_TRACE_LEVEL,
         IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
         0, "dump_dp_trace"},
+    {
+        WLAN_PRIV_SET_FTIES,
+        IW_PRIV_TYPE_CHAR | MAX_FTIE_SIZE,
+        0, "set_ft_ies"},
 };
 
 
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
index 5e0a6d0..834cfe2 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
@@ -585,7 +585,7 @@
 #define SIR_MAC_MAX_NUMBER_OF_RATES          12
 #define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS      4
 #define SIR_MAC_KEY_LENGTH                   13   // WEP Maximum key length size
-#define SIR_MAC_AUTH_CHALLENGE_LENGTH        128
+#define SIR_MAC_AUTH_CHALLENGE_LENGTH        253
 #define SIR_MAC_WEP_IV_LENGTH                4
 #define SIR_MAC_WEP_ICV_LENGTH               4
 
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
index 1b07c3a..686786f 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
@@ -24,7 +24,6 @@
  * under proprietary terms before Copyright ownership was assigned
  * to the Linux Foundation.
  */
-
 #ifndef DOT11F_H
 #define DOT11F_H
 /**
@@ -37,7 +36,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Thu Oct  8 17:27:11 2015 from the following file(s):
+  * Tue Jul  4 11:07:27 2017 from the following file(s):
   *
   * dot11f.frms
   *
@@ -91,8 +90,8 @@
 #define DOT11F_BUFFER_OVERFLOW       ( 0x10000005 )
 #define DOT11F_MANDATORY_TLV_MISSING ( 0x00001000 )
 #define DOT11F_FAILED(code)          ( (code) & 0x10000000 )
-#define DOT11F_WARNED(code)          ( ( ( 0 == (code) ) & 0x10000000 ) && code)
 #define DOT11F_SUCCEEDED(code)       ( (code) == 0 )
+#define DOT11F_WARNED(code)          (!DOT11F_SUCCEEDED(code) && !DOT11F_FAILED(code))
 
 /*********************************************************************
  * Fixed Fields                                                      *
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
index 0241dc0..049c86a 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
@@ -647,7 +647,7 @@
  */
 
 void
-limComputeCrc32(tANI_U8 *pDest, tANI_U8 * pSrc, tANI_U8 len)
+limComputeCrc32(tANI_U8 *pDest, tANI_U8 * pSrc, tANI_U16 len)
 {
     tANI_U32 crc;
     int i;
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
index 4ede500..9139ce2 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -59,7 +59,7 @@
 
 // Encryption/Decryption related functions
 tCfgWepKeyEntry    *limLookUpKeyMappings(tSirMacAddr);
-void               limComputeCrc32(tANI_U8 *, tANI_U8 *, tANI_U8);
+void               limComputeCrc32(tANI_U8 *, tANI_U8 *, tANI_U16);
 void               limRC4(tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16);
 void               limEncryptAuthFrame(tpAniSirGlobal, tANI_U8, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32);
 tANI_U8                 limDecryptAuthFrame(tpAniSirGlobal, tANI_U8 *, tANI_U8 *, tANI_U8 *, tANI_U32, tANI_U16);
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c
index d42ceda..904e2b6 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/rrm/rrmApi.c
@@ -628,14 +628,21 @@
    pSmeBcnReportReq->channelList.numChannels = num_channels;
    if( pBeaconReq->measurement_request.Beacon.num_APChannelReport )
    {
-      tANI_U8 *pChanList = pSmeBcnReportReq->channelList.channelNumber;
+      tANI_U8 *ch_lst = pSmeBcnReportReq->channelList.channelNumber;
+      uint8_t len;
+      uint16_t ch_ctr = 0;
       for( num_APChanReport = 0 ; num_APChanReport < pBeaconReq->measurement_request.Beacon.num_APChannelReport ; num_APChanReport++ )
       {
-         vos_mem_copy(pChanList,
-          pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].channelList,
-          pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList);
+         len = pBeaconReq->measurement_request.Beacon.
+                            APChannelReport[num_APChanReport].num_channelList;
+         if(ch_ctr + len > sizeof(pSmeBcnReportReq->channelList.channelNumber))
+            break;
 
-         pChanList += pBeaconReq->measurement_request.Beacon.APChannelReport[num_APChanReport].num_channelList;
+         vos_mem_copy(&ch_lst[ch_ctr],
+                      pBeaconReq->measurement_request.Beacon.
+                      APChannelReport[num_APChanReport].channelList, len);
+
+         ch_ctr += len;
       }
    }
 
diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c
index 3947b83a..e413672 100644
--- a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c
+++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_FTApi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -163,6 +163,9 @@
    {
       case eFT_START_READY:
       case eFT_AUTH_REQ_READY:
+#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
+         smsLog( pMac, LOG1, FL("ft_ies_length: %d"), ft_ies_length);
+#endif
          if ((pSession->ftSmeContext.auth_ft_ies) &&
                (pSession->ftSmeContext.auth_ft_ies_length))
          {
@@ -171,7 +174,7 @@
             pSession->ftSmeContext.auth_ft_ies_length = 0;
             pSession->ftSmeContext.auth_ft_ies = NULL;
          }
-
+         ft_ies_length = VOS_MIN(ft_ies_length, MAX_FTIE_SIZE);
          // Save the FT IEs
          pSession->ftSmeContext.auth_ft_ies =
             vos_mem_malloc(ft_ies_length);
@@ -187,9 +190,6 @@
                ft_ies,ft_ies_length);
          pSession->ftSmeContext.FTState = eFT_AUTH_REQ_READY;
 
-#if defined WLAN_FEATURE_VOWIFI_11R_DEBUG
-         smsLog( pMac, LOG1, "ft_ies_length=%d", ft_ies_length);
-#endif
          break;
 
       case eFT_AUTH_COMPLETE:
diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
index 2580c43..ae53ece 100644
--- a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -35,7 +35,7 @@
   *
   *
   * This file was automatically generated by 'framesc'
-  * Thu Oct  8 17:27:11 2015 from the following file(s):
+  * Tue Jul  4 11:07:27 2017 from the following file(s):
   *
   * dot11f.frms
   *
@@ -19269,6 +19269,10 @@
                 }
 
         countOffset = ( (0 != pIe->arraybound) * ( *(tANI_U16* )(pFrm + pIe->countOffset)));
+        if (0 != pIe->arraybound && countOffset >= pIe->arraybound) {
+            status |= DOT11F_DUPLICATE_IE;
+            goto skip_dup_ie;
+        }
                 switch (pIe->sig)
                 {
                 case SigIeCondensedCountryStr:
@@ -19706,6 +19710,7 @@
             status |= DOT11F_UNKNOWN_IES;
         }
 
+skip_dup_ie:
         pBufRemaining += len;
 
          if (len > nBufRemaining)
diff --git a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c
index 173ed4e..ec61b77 100644
--- a/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c
+++ b/drivers/staging/qcacld-2.0/CORE/UTILS/PKTLOG/linux_ac.c
@@ -82,14 +82,12 @@
 static void pktlog_detach(struct ol_softc *sc);
 static int pktlog_open(struct inode *i, struct file *f);
 static int pktlog_release(struct inode *i, struct file *f);
-static int pktlog_mmap(struct file *f, struct vm_area_struct *vma);
 static ssize_t pktlog_read(struct file *file, char *buf, size_t nbytes,
 			   loff_t * ppos);
 
 static struct file_operations pktlog_fops = {
 	open:pktlog_open,
 	release:pktlog_release,
-	mmap:pktlog_mmap,
 	read:pktlog_read,
 };
 
@@ -921,106 +919,6 @@
 }
 #endif
 
-/* vma operations for mapping vmalloced area to user space */
-static void pktlog_vopen(struct vm_area_struct *vma)
-{
-	PKTLOG_MOD_INC_USE_COUNT;
-}
-
-static void pktlog_vclose(struct vm_area_struct *vma)
-{
-	PKTLOG_MOD_DEC_USE_COUNT;
-}
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
-int pktlog_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
-	unsigned long address = (unsigned long)vmf->virtual_address;
-
-	if (address == 0UL)
-		return VM_FAULT_NOPAGE;
-
-	if (vmf->pgoff > vma->vm_end)
-		return VM_FAULT_SIGBUS;
-
-	get_page(virt_to_page((void *)address));
-	vmf->page = virt_to_page((void *)address);
-	return VM_FAULT_MINOR;
-}
-#else
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-struct page *pktlog_vmmap(struct vm_area_struct *vma, unsigned long addr,
-			  int *type)
-#else
-struct page *pktlog_vmmap(struct vm_area_struct *vma, unsigned long addr,
-			  int write_access)
-#endif
-{
-	unsigned long offset, vaddr;
-	struct proc_dir_entry *proc_entry;
-	struct ath_pktlog_info *pl_info =
-
-	proc_entry = PDE(vma->vm_file->f_dentry->d_inode);
-	pl_info = (struct ath_pktlog_info *)proc_entry->data;
-
-	offset = addr - vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT);
-	vaddr = (unsigned long) pktlog_virt_to_logical(
-					(void *)(pl_info->buf) + offset);
-
-	if (vaddr == 0UL) {
-		printk(PKTLOG_TAG "%s: page fault out of range\n", __func__);
-		return ((struct page *) 0UL);
-	}
-
-	/* increment the usage count of the page */
-	get_page(virt_to_page((void*)vaddr));
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-	if (type)
-		*type = VM_FAULT_MINOR;
-#endif
-
-	return virt_to_page((void *)vaddr);
-}
-#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) */
-
-static struct vm_operations_struct pktlog_vmops = {
-	open:pktlog_vopen,
-	close:pktlog_vclose,
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)
-	fault:pktlog_fault,
-#else
-	nopage:pktlog_vmmap,
-#endif
-};
-
-static int pktlog_mmap(struct file *file, struct vm_area_struct *vma)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
-	struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *)
-					  PDE_DATA(file->f_path.dentry->d_inode);
-#else
-	struct proc_dir_entry *proc_entry = PDE(file->f_dentry->d_inode);
-	struct ath_pktlog_info *pl_info = (struct ath_pktlog_info *)
-					  proc_entry->data;
-#endif
-
-	if (vma->vm_pgoff != 0) {
-		/* Entire buffer should be mapped */
-		return -EINVAL;
-	}
-
-	if (!pl_info->buf) {
-		printk(PKTLOG_TAG "%s: Log buffer unavailable\n", __func__);
-		return -ENOMEM;
-	}
-
-	vma->vm_flags |= VM_LOCKED;
-	vma->vm_ops = &pktlog_vmops;
-	pktlog_vopen(vma);
-	return 0;
-}
-
 int pktlogmod_init(void *context)
 {
 	int ret;
diff --git a/drivers/video/msm/mdss/mdss_hdmi_cec.c b/drivers/video/msm/mdss/mdss_hdmi_cec.c
index a424d98..a4ed012 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-2016, 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
@@ -196,7 +196,7 @@
 		msg.sender_id, msg.recvr_id,
 		msg.frame_size);
 
-	if (msg.frame_size < 1) {
+	if (msg.frame_size < 1 || msg.frame_size > MAX_CEC_FRAME_SIZE) {
 		DEV_ERR("%s: invalid message (frame length = %d)\n",
 			__func__, msg.frame_size);
 		return;
@@ -216,7 +216,7 @@
 		msg.operand[i] = data & 0xFF;
 	}
 
-	for (; i < 14; i++)
+	for (; i < MAX_OPERAND_SIZE; i++)
 		msg.operand[i] = 0;
 
 	DEV_DBG("%s: opcode 0x%x, wakup_en %d, device_suspend %d\n", __func__,
diff --git a/drivers/video/msm/mdss/mdss_hdmi_edid.c b/drivers/video/msm/mdss/mdss_hdmi_edid.c
index 36c2430..5c8f52c 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_edid.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_edid.c
@@ -2180,6 +2180,13 @@
 		goto bail;
 	}
 
+	/* Find out if CEA extension blocks exceeding max limit */
+	if (num_of_cea_blocks >= MAX_EDID_BLOCKS) {
+		DEV_WARN("%s: HDMI EDID exceeded max CEA blocks limit\n",
+				__func__);
+		num_of_cea_blocks = MAX_EDID_BLOCKS - 1;
+	}
+
 	/* check for valid CEA block */
 	if (edid_buf[EDID_BLOCK_SIZE] != 2) {
 		DEV_ERR("%s: Invalid CEA block\n", __func__);
diff --git a/drivers/video/msm/mdss/mdss_rotator.c b/drivers/video/msm/mdss/mdss_rotator.c
index ddbdf5a..0f2d285 100644
--- a/drivers/video/msm/mdss/mdss_rotator.c
+++ b/drivers/video/msm/mdss/mdss_rotator.c
@@ -375,6 +375,15 @@
 	return false;
 }
 
+static void mdss_rotator_install_fence_fd(struct mdss_rot_entry_container *req)
+{
+	int i = 0;
+
+	for (i = 0; i < req->count; i++)
+		sync_fence_install(req->entries[i].output_fence,
+				req->entries[i].output_fence_fd);
+}
+
 static int mdss_rotator_create_fence(struct mdss_rot_entry *entry)
 {
 	int ret = 0, fd;
@@ -413,7 +422,6 @@
 		goto get_fd_err;
 	}
 
-	sync_fence_install(fence, fd);
 	rot_timeline->next_value++;
 	mutex_unlock(&rot_timeline->lock);
 
@@ -2250,6 +2258,7 @@
 		goto handle_request_err1;
 	}
 
+	mdss_rotator_install_fence_fd(req);
 	mdss_rotator_queue_request(mgr, private, req);
 
 	mutex_unlock(&mgr->lock);
@@ -2410,6 +2419,7 @@
 		goto handle_request32_err1;
 	}
 
+	mdss_rotator_install_fence_fd(req);
 	mdss_rotator_queue_request(mgr, private, req);
 
 	mutex_unlock(&mgr->lock);
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 23705a5..97b745d 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -8,7 +8,9 @@
 	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 32ca79f..03951bc1 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1914,14 +1914,16 @@
 	return tsk->tgid;
 }
 
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+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 pid_vnr(task_tgid(tsk));
+	return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
 }
 
-
 static inline int pid_alive(const struct task_struct *p);
 static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
 {
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2bf9ebc..b25fcc7 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7414,6 +7414,37 @@
 	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 = ACCESS_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
  *
@@ -7643,14 +7674,31 @@
 	}
 
 	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);
 
 		/*
@@ -7691,7 +7739,7 @@
 	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);
@@ -7722,6 +7770,11 @@
 	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 82430c8..65a386e 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -523,8 +523,11 @@
 	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();
@@ -533,12 +536,6 @@
 }
 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 cb860a5..86e8031 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -301,8 +301,7 @@
 	[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 },
@@ -358,6 +357,7 @@
 	[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 4ea4e6f..f8049ad 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -150,7 +150,9 @@
 				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 8c250f6..f72c15a 100644
--- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c
@@ -177,7 +177,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"VIRT ENABLE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 				AUDPROC_MODULE_ID_VIRTUALIZER;
 				*updt_params++ =
@@ -205,7 +205,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"VIRT STRENGTH", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_VIRTUALIZER;
 				*updt_params++ =
@@ -233,7 +233,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"VIRT OUT_TYPE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_VIRTUALIZER;
 				*updt_params++ =
@@ -261,7 +261,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"VIRT GAIN_ADJUST", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 				AUDPROC_MODULE_ID_VIRTUALIZER;
 				*updt_params++ =
@@ -340,7 +340,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_ENABLE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -368,7 +368,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_MODE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -396,7 +396,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_PRESET", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -424,7 +424,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_WET_MIX", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -452,7 +452,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_GAIN_ADJUST", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -480,7 +480,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_ROOM_LEVEL", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -508,7 +508,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_ROOM_HF_LEVEL", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -536,7 +536,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_DECAY_TIME", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -564,7 +564,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_DECAY_HF_RATIO", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -592,7 +592,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_REFLECTIONS_LEVEL", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 				AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -620,7 +620,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_REFLECTIONS_DELAY", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 				AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -648,7 +648,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_LEVEL", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -676,7 +676,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_DELAY", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -704,7 +704,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_DIFFUSION", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -732,7 +732,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"REVERB_DENSITY", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_REVERB;
 				*updt_params++ =
@@ -812,7 +812,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"BASS_BOOST_ENABLE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_BASS_BOOST;
 				*updt_params++ =
@@ -840,7 +840,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"BASS_BOOST_MODE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_BASS_BOOST;
 				*updt_params++ =
@@ -868,7 +868,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"BASS_BOOST_STRENGTH", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_BASS_BOOST;
 				*updt_params++ =
@@ -946,7 +946,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"PBE_ENABLE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_PBE;
 				*updt_params++ =
@@ -972,7 +972,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"PBE_PARAM", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_PBE;
 				*updt_params++ =
@@ -1057,7 +1057,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"EQ_ENABLE", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
 				*updt_params++ =
@@ -1125,7 +1125,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"EQ_CONFIG", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
 				*updt_params++ =
@@ -1176,7 +1176,7 @@
 						MAX_INBAND_PARAM_SZ,
 						"EQ_BAND_INDEX", rc);
 				if (rc != 0)
-					break;
+					goto invalid_config;
 				*updt_params++ =
 					AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
 				*updt_params++ =
@@ -1208,7 +1208,7 @@
 						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++ =
@@ -1298,7 +1298,7 @@
 						"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;
@@ -1347,7 +1347,7 @@
 						"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;