Snap for 5205691 from af4ed0778abdd417c5e5fcb34e0a1dacee4d07bf to oc-mr1-1.5-iot-release

Change-Id: I3f200187c4875657eebe56be5851628837ea007f
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index a3c19c4..41ab338 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -336,12 +336,13 @@
 	int header_len = sizeof(struct diag_ctrl_msg_mask);
 	uint8_t *buf = NULL, *temp = NULL;
 	uint8_t upd = 0;
-	uint8_t msg_mask_tbl_count_local;
+	uint8_t msg_mask_tbl_count_local = 0;
 	uint32_t mask_size = 0, pd_mask = 0;
 	struct diag_mask_info *mask_info = NULL;
 	struct diag_msg_mask_t *mask = NULL;
 	struct diag_ctrl_msg_mask header;
 	struct diagfwd_info *fwd_info = NULL;
+	struct diag_md_session_t *md_session_info = NULL;
 
 	if (peripheral >= NUM_PERIPHERALS)
 		return;
@@ -357,14 +358,19 @@
 
 	if (driver->md_session_mask != 0) {
 		if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
-			if (driver->md_session_map[peripheral])
+			if (driver->md_session_map[peripheral]) {
 				mask_info =
 				driver->md_session_map[peripheral]->msg_mask;
+				md_session_info =
+					driver->md_session_map[peripheral];
+			}
 		} else if (driver->md_session_mask & pd_mask) {
 			upd = diag_mask_to_pd_value(driver->md_session_mask);
-			if (upd && driver->md_session_map[upd])
+			if (upd && driver->md_session_map[upd]) {
 				mask_info =
 				driver->md_session_map[upd]->msg_mask;
+				md_session_info = driver->md_session_map[upd];
+			}
 		} else {
 			DIAG_LOG(DIAG_DEBUG_MASKS,
 			"asking for mask update with unknown session mask\n");
@@ -383,7 +389,10 @@
 		return;
 	}
 	buf = mask_info->update_buf;
-	msg_mask_tbl_count_local = driver->msg_mask_tbl_count;
+	if (md_session_info)
+		msg_mask_tbl_count_local = md_session_info->msg_mask_tbl_count;
+	else
+		msg_mask_tbl_count_local = driver->msg_mask_tbl_count;
 	mutex_unlock(&driver->msg_mask_lock);
 	mutex_lock(&mask_info->lock);
 	switch (mask_info->status) {
@@ -565,6 +574,7 @@
 {
 	int i;
 	int write_len = 0;
+	uint8_t msg_mask_tbl_count = 0;
 	struct diag_msg_mask_t *mask_ptr = NULL;
 	struct diag_msg_ssid_query_t rsp;
 	struct diag_ssid_range_t ssid_range;
@@ -594,15 +604,17 @@
 		return 0;
 	}
 	mutex_lock(&driver->msg_mask_lock);
+	msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+		driver->msg_mask_tbl_count;
 	rsp.cmd_code = DIAG_CMD_MSG_CONFIG;
 	rsp.sub_cmd = DIAG_CMD_OP_GET_SSID_RANGE;
 	rsp.status = MSG_STATUS_SUCCESS;
 	rsp.padding = 0;
-	rsp.count = driver->msg_mask_tbl_count;
+	rsp.count = 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++) {
+	for (i = 0; i < msg_mask_tbl_count; i++, mask_ptr++) {
 		if (write_len + sizeof(ssid_range) > dest_len) {
 			pr_err("diag: In %s, Truncating response due to size limitations of rsp buffer\n",
 			       __func__);
@@ -679,6 +691,7 @@
 	int i;
 	int write_len = 0;
 	uint32_t mask_size = 0;
+	uint8_t msg_mask_tbl_count = 0;
 	struct diag_msg_mask_t *mask = NULL;
 	struct diag_build_mask_req_t *req = NULL;
 	struct diag_msg_build_mask_t rsp;
@@ -709,6 +722,8 @@
 	}
 
 	mutex_lock(&driver->msg_mask_lock);
+	msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+			driver->msg_mask_tbl_count;
 	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;
@@ -724,7 +739,7 @@
 		mutex_unlock(&driver->md_session_lock);
 		return -EINVAL;
 	}
-	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+	for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
 		if (!mask->ptr)
 			continue;
 		if ((req->ssid_first < mask->ssid_first) ||
@@ -760,6 +775,7 @@
 	struct diag_mask_info *mask_info = NULL;
 	struct diag_msg_mask_t *mask_next = NULL;
 	struct diag_md_session_t *info = NULL;
+	uint8_t msg_mask_tbl_count = 0;
 
 	mutex_lock(&driver->md_session_lock);
 	info = diag_md_session_get_pid(pid);
@@ -792,10 +808,13 @@
 		mutex_unlock(&driver->md_session_lock);
 		return -EINVAL;
 	}
-	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+
+	msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+			driver->msg_mask_tbl_count;
+	for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
 		if (!mask->ptr)
 			continue;
-		if (i < (driver->msg_mask_tbl_count - 1)) {
+		if (i < (msg_mask_tbl_count - 1)) {
 			mask_next = mask;
 			mask_next++;
 		} else
@@ -905,6 +924,7 @@
 	struct diag_msg_mask_t *mask = NULL;
 	struct diag_mask_info *mask_info = NULL;
 	struct diag_md_session_t *info = NULL;
+	uint8_t msg_mask_tbl_count = 0;
 
 	mutex_lock(&driver->md_session_lock);
 	info = diag_md_session_get_pid(pid);
@@ -939,9 +959,11 @@
 		mutex_unlock(&driver->md_session_lock);
 		return -EINVAL;
 	}
+	msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+			driver->msg_mask_tbl_count;
 	mask_info->status = (req->rt_mask) ? DIAG_CTRL_MASK_ALL_ENABLED :
 					   DIAG_CTRL_MASK_ALL_DISABLED;
-	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+	for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
 		if (mask && mask->ptr) {
 			mutex_lock(&mask->lock);
 			memset(mask->ptr, req->rt_mask,
@@ -1755,7 +1777,6 @@
 		}
 		kmemleak_not_leak(mask_info->update_buf);
 	}
-	mutex_init(&mask_info->lock);
 	return 0;
 }
 
@@ -1778,9 +1799,10 @@
 	struct diag_log_mask_t *src_mask = NULL;
 	struct diag_log_mask_t *dest_mask = NULL;
 
-	if (!src)
+	if (!src || !dest)
 		return -EINVAL;
 
+	mutex_init(&dest->lock);
 	err = __diag_mask_init(dest, LOG_MASK_SIZE, APPS_BUF_SIZE);
 	if (err)
 		return err;
@@ -1842,9 +1864,11 @@
 {
 	int err = 0, i;
 
+	mutex_init(&msg_mask.lock);
 	err = __diag_mask_init(&msg_mask, MSG_MASK_SIZE, APPS_BUF_SIZE);
 	if (err)
 		return err;
+
 	err = diag_create_msg_mask_table();
 	if (err) {
 		pr_err("diag: Unable to create msg masks, err: %d\n", err);
@@ -1859,7 +1883,8 @@
 	return 0;
 }
 
-int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
+int diag_msg_mask_copy(struct diag_md_session_t *new_session,
+	struct diag_mask_info *dest, struct diag_mask_info *src)
 {
 	int i, err = 0, mask_size = 0;
 	struct diag_msg_mask_t *src_mask = NULL;
@@ -1869,17 +1894,25 @@
 	if (!src || !dest)
 		return -EINVAL;
 
-	err = __diag_mask_init(dest, MSG_MASK_SIZE, APPS_BUF_SIZE);
-	if (err)
-		return err;
+	mutex_init(&dest->lock);
 	mutex_lock(&dest->lock);
 	mutex_lock(&driver->msg_mask_lock);
+	new_session->msg_mask_tbl_count =
+		driver->msg_mask_tbl_count;
+	err = __diag_mask_init(dest,
+		(new_session->msg_mask_tbl_count *
+		sizeof(struct diag_msg_mask_t)), APPS_BUF_SIZE);
+	if (err) {
+		mutex_unlock(&driver->msg_mask_lock);
+		mutex_unlock(&dest->lock);
+		return err;
+	}
 	src_mask = (struct diag_msg_mask_t *)src->ptr;
 	dest_mask = (struct diag_msg_mask_t *)dest->ptr;
 
 	dest->mask_len = src->mask_len;
 	dest->status = src->status;
-	for (i = 0; i < driver->msg_mask_tbl_count; i++) {
+	for (i = 0; i < new_session->msg_mask_tbl_count; i++) {
 		range.ssid_first = src_mask->ssid_first;
 		range.ssid_last = src_mask->ssid_last;
 		err = diag_create_msg_mask_table_entry(dest_mask, &range);
@@ -1898,10 +1931,12 @@
 	return err;
 }
 
-void diag_msg_mask_free(struct diag_mask_info *mask_info)
+void diag_msg_mask_free(struct diag_mask_info *mask_info,
+	struct diag_md_session_t *session_info)
 {
 	int i;
 	struct diag_msg_mask_t *mask = NULL;
+	uint8_t msg_mask_tbl_count = 0;
 
 	if (!mask_info || !mask_info->ptr)
 		return;
@@ -1915,7 +1950,10 @@
 		mutex_unlock(&mask_info->lock);
 		return;
 	}
-	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+	msg_mask_tbl_count = (session_info) ?
+		session_info->msg_mask_tbl_count :
+		driver->msg_mask_tbl_count;
+	for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
 		kfree(mask->ptr);
 		mask->ptr = NULL;
 	}
@@ -1946,6 +1984,7 @@
 	int err = 0;
 
 	/* There is no need for update buffer for Build Time masks */
+	mutex_init(&msg_bt_mask.lock);
 	err = __diag_mask_init(&msg_bt_mask, MSG_MASK_SIZE, 0);
 	if (err)
 		return err;
@@ -1978,6 +2017,7 @@
 {
 	int err = 0, i;
 
+	mutex_init(&log_mask.lock);
 	err = __diag_mask_init(&log_mask, LOG_MASK_SIZE, APPS_BUF_SIZE);
 	if (err)
 		return err;
@@ -2011,6 +2051,7 @@
 {
 	int err = 0, i;
 
+	mutex_init(&event_mask.lock);
 	err = __diag_mask_init(&event_mask, EVENT_MASK_SIZE, APPS_BUF_SIZE);
 	if (err)
 		return err;
@@ -2032,6 +2073,7 @@
 	if (!src || !dest)
 		return -EINVAL;
 
+	mutex_init(&dest->lock);
 	err = __diag_mask_init(dest, EVENT_MASK_SIZE, APPS_BUF_SIZE);
 	if (err)
 		return err;
@@ -2068,6 +2110,7 @@
 	struct diag_mask_info *mask_info = NULL;
 	struct diag_msg_mask_t *mask = NULL;
 	unsigned char *ptr = NULL;
+	uint8_t msg_mask_tbl_count = 0;
 
 	if (!buf || count == 0)
 		return -EINVAL;
@@ -2092,7 +2135,10 @@
 		mutex_unlock(&mask_info->lock);
 		return -EINVAL;
 	}
-	for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
+
+	msg_mask_tbl_count = (info) ? info->msg_mask_tbl_count :
+			driver->msg_mask_tbl_count;
+	for (i = 0; i < msg_mask_tbl_count; i++, mask++) {
 		if (!mask->ptr)
 			continue;
 		ptr = mask_info->update_buf;
diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h
index 6edeee9..a736ff2 100644
--- a/drivers/char/diag/diag_masks.h
+++ b/drivers/char/diag/diag_masks.h
@@ -160,12 +160,13 @@
 void diag_masks_exit(void);
 int diag_log_mask_copy(struct diag_mask_info *dest,
 		       struct diag_mask_info *src);
-int diag_msg_mask_copy(struct diag_mask_info *dest,
-		       struct diag_mask_info *src);
+int diag_msg_mask_copy(struct diag_md_session_t *new_session,
+	struct diag_mask_info *dest, struct diag_mask_info *src);
 int diag_event_mask_copy(struct diag_mask_info *dest,
 			 struct diag_mask_info *src);
 void diag_log_mask_free(struct diag_mask_info *mask_info);
-void diag_msg_mask_free(struct diag_mask_info *mask_info);
+void diag_msg_mask_free(struct diag_mask_info *mask_info,
+	struct diag_md_session_t *session_info);
 void diag_event_mask_free(struct diag_mask_info *mask_info);
 int diag_process_apps_masks(unsigned char *buf, int len, int pid);
 void diag_send_updates_peripheral(uint8_t peripheral);
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 9bbfb82..f63d78c 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -483,6 +483,7 @@
 	int pid;
 	int peripheral_mask;
 	uint8_t hdlc_disabled;
+	uint8_t msg_mask_tbl_count;
 	struct timer_list hdlc_reset_timer;
 	struct diag_mask_info *msg_mask;
 	struct diag_mask_info *log_mask;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 8b089eb..131a050 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1264,7 +1264,8 @@
 			diag_log_mask_free(session_info->log_mask);
 			kfree(session_info->log_mask);
 			session_info->log_mask = NULL;
-			diag_msg_mask_free(session_info->msg_mask);
+			diag_msg_mask_free(session_info->msg_mask,
+				session_info);
 			kfree(session_info->msg_mask);
 			session_info->msg_mask = NULL;
 			diag_event_mask_free(session_info->event_mask);
@@ -1335,7 +1336,9 @@
 			 "return value of event copy. err %d\n", err);
 		goto fail_peripheral;
 	}
-	err = diag_msg_mask_copy(new_session->msg_mask, &msg_mask);
+	new_session->msg_mask_tbl_count = 0;
+	err = diag_msg_mask_copy(new_session, new_session->msg_mask,
+		&msg_mask);
 	if (err) {
 		DIAG_LOG(DIAG_DEBUG_USERSPACE,
 			 "return value of msg copy. err %d\n", err);
@@ -1371,7 +1374,8 @@
 	diag_event_mask_free(new_session->event_mask);
 	kfree(new_session->event_mask);
 	new_session->event_mask = NULL;
-	diag_msg_mask_free(new_session->msg_mask);
+	diag_msg_mask_free(new_session->msg_mask,
+		new_session);
 	kfree(new_session->msg_mask);
 	new_session->msg_mask = NULL;
 	kfree(new_session);
@@ -1399,7 +1403,8 @@
 	diag_log_mask_free(session_info->log_mask);
 	kfree(session_info->log_mask);
 	session_info->log_mask = NULL;
-	diag_msg_mask_free(session_info->msg_mask);
+	diag_msg_mask_free(session_info->msg_mask,
+		session_info);
 	kfree(session_info->msg_mask);
 	session_info->msg_mask = NULL;
 	diag_event_mask_free(session_info->event_mask);
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 6975c13..7c01a18 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1175,7 +1175,7 @@
 	__strict_check(device);
 
 	if (!__core_in_valid_state(device)) {
-		dprintk(VIDC_DBG, "%s - fw not in init state\n", __func__);
+		dprintk(VIDC_ERR, "%s - fw not in init state\n", __func__);
 		result = -EINVAL;
 		goto err_q_null;
 	}
@@ -2904,8 +2904,6 @@
 {
 	struct hfi_sfr_struct *vsfr = NULL;
 
-	__set_state(device, VENUS_STATE_DEINIT);
-
 	if (__halt_axi(device))
 		dprintk(VIDC_WARN, "Failed to halt AXI after SYS_ERROR\n");
 
@@ -3163,6 +3161,10 @@
 					"Too many packets in message queue to handle at once, deferring read\n");
 			break;
 		}
+
+		/* do not read packets after sys error packet */
+		if (info->response_type == HAL_SYS_ERROR)
+			break;
 	}
 
 	if (requeue_pm_work && device->res->sw_power_collapsible) {
@@ -3227,6 +3229,12 @@
 		struct msm_vidc_cb_info *r = &device->response_pkt[i];
 		dprintk(VIDC_DBG, "Processing response %d of %d, type %d\n",
 			(i + 1), num_responses, r->response_type);
+		if (!__core_in_valid_state(device)) {
+			dprintk(VIDC_ERR,
+				"Ignore responses from %d to %d as device is in invalid state",
+				(i + 1), num_responses);
+			break;
+		}
 		device->callback(r->response_type, &r->response);
 	}
 
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 2212b00..57dfa79 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -1047,13 +1047,12 @@
 		goto error;
 	}
 	/*
-	 * do not allow any rules to be added at end of the "default" routing
-	 * tables
+	 * do not allow any rule to be added at "default" routing
+	 * table
 	 */
 	if (!strcmp(tbl->name, IPA_DFLT_RT_TBL_NAME) &&
-	    (tbl->rule_cnt > 0) && (at_rear != 0)) {
-		IPAERR_RL("cannot add rule at end of tbl rule_cnt=%d at_rear=%d"
-				, tbl->rule_cnt, at_rear);
+	    (tbl->rule_cnt > 0)) {
+		IPAERR_RL("cannot add rules to default rt table\n");
 		goto error;
 	}
 
@@ -1276,13 +1275,12 @@
 	}
 
 	/*
-	 * do not allow any rules to be added at end of the "default" routing
-	 * tables
+	 * do not allow any rule to be added at "default" routing
+	 * table
 	 */
 	if (!strcmp(tbl->name, IPA_DFLT_RT_TBL_NAME) &&
-			(&entry->link == tbl->head_rt_rule_list.prev)) {
-		IPAERR_RL("cannot add rule at end of tbl rule_cnt=%d\n",
-			tbl->rule_cnt);
+		(tbl->rule_cnt > 0)) {
+		IPAERR_RL("cannot add rules to default rt table\n");
 		ret = -EINVAL;
 		goto bail;
 	}
@@ -1742,6 +1740,10 @@
 		goto error;
 	}
 
+	if (!strcmp(entry->tbl->name, IPA_DFLT_RT_TBL_NAME)) {
+		IPAERR_RL("Default tbl rule cannot be modified\n");
+		return -EINVAL;
+	}
 	/* Adding check to confirm still
 	 * header entry present in header table or not
 	 */