summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Prabhu B <bmanoj@codeaurora.org>2017-07-14 16:52:45 +0530
committerManoj Prabhu B <bmanoj@codeaurora.org>2017-07-19 20:51:10 +0530
commit6e6b233c47168e3df2e7aa2b6c6d9379f6d3441b (patch)
tree693f452cac2ea4ac0335d319e83aa2cd5adfc4fb
parent502914e130709bfaf33ab1411b712290ccef19ca (diff)
diag: Synchronize msg mask read and write on a peripheral
The patch synchronizes msg mask read and write on a peripheral by proper protection of mask_info and msg_mask_table_count. CRs-Fixed: 2042362, 2055291 Change-Id: If136012855834b0b8cba91eb66bf711750e8f372 Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
-rw-r--r--drivers/char/diag/diag_masks.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index e37609abf7bf..e206d9db4d7d 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -320,6 +320,7 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
struct diag_mask_info *mask_info = NULL;
struct diag_msg_mask_t *mask = NULL;
struct diag_ctrl_msg_mask header;
+ uint8_t msg_mask_tbl_count_local;
if (peripheral >= NUM_PERIPHERALS)
return;
@@ -360,6 +361,8 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
return;
}
buf = mask_info->update_buf;
+ 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) {
case DIAG_CTRL_MASK_ALL_DISABLED:
@@ -376,9 +379,11 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
goto err;
}
- for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
- if (((first < mask->ssid_first) ||
- (last > mask->ssid_last_tools)) && first != ALL_SSID) {
+ for (i = 0; i < msg_mask_tbl_count_local; i++, mask++) {
+ mutex_lock(&driver->msg_mask_lock);
+ if (((mask->ssid_first > first) ||
+ (mask->ssid_last_tools < last)) && first != ALL_SSID) {
+ mutex_unlock(&driver->msg_mask_lock);
continue;
}
@@ -419,19 +424,19 @@ proceed:
if (mask_size > 0)
memcpy(buf + header_len, mask->ptr, mask_size);
mutex_unlock(&mask->lock);
+ mutex_unlock(&driver->msg_mask_lock);
err = diagfwd_write(peripheral, TYPE_CNTL, buf,
header_len + mask_size);
if (err && err != -ENODEV)
- pr_err_ratelimited("diag: Unable to send msg masks to peripheral %d\n",
- peripheral);
+ pr_err_ratelimited("diag: Unable to send msg masks to peripheral %d, error = %d\n",
+ peripheral, err);
if (first != ALL_SSID)
break;
}
err:
mutex_unlock(&mask_info->lock);
- mutex_unlock(&driver->msg_mask_lock);
}
static void diag_send_time_sync_update(uint8_t peripheral)
@@ -711,8 +716,8 @@ 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(&mask_info->lock);
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
if (i < (driver->msg_mask_tbl_count - 1)) {
@@ -752,6 +757,8 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
pr_err_ratelimited("diag: In %s, unable to allocate memory for msg mask ptr, mask_size: %d\n",
__func__, mask_size);
mutex_unlock(&mask->lock);
+ mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&mask_info->lock);
return -ENOMEM;
}
mask->ptr = temp;
@@ -770,8 +777,8 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
mask_info->status = DIAG_CTRL_MASK_VALID;
break;
}
- mutex_unlock(&mask_info->lock);
mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&mask_info->lock);
if (diag_check_update(APPS_DATA))
diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -826,9 +833,11 @@ 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(&mask_info->lock);
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 :
DIAG_CTRL_MASK_ALL_DISABLED;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -837,8 +846,8 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
mask->range * sizeof(uint32_t));
mutex_unlock(&mask->lock);
}
- mutex_unlock(&mask_info->lock);
mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&mask_info->lock);
if (diag_check_update(APPS_DATA))
diag_update_userspace_clients(MSG_MASKS_TYPE);
@@ -1352,8 +1361,8 @@ 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);
+ mutex_lock(&driver->msg_mask_lock);
driver->msg_mask_tbl_count = MSG_MASK_TBL_CNT;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
range.ssid_first = msg_mask_tbl[i].ssid_first;
@@ -1362,8 +1371,8 @@ static int diag_create_msg_mask_table(void)
if (err)
break;
}
- mutex_unlock(&msg_mask.lock);
mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&msg_mask.lock);
return err;
}
@@ -1376,8 +1385,8 @@ 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);
+ mutex_lock(&driver->msg_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->bt_msg_mask_tbl_count; i++, build_mask++) {
@@ -1490,9 +1499,8 @@ 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);
-
+ mutex_unlock(&msg_bt_mask.lock);
return err;
}
@@ -1662,8 +1670,8 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
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);
+ mutex_lock(&driver->msg_mask_lock);
src_mask = (struct diag_msg_mask_t *)src->ptr;
dest_mask = (struct diag_msg_mask_t *)dest->ptr;
@@ -1680,9 +1688,8 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
src_mask++;
dest_mask++;
}
- mutex_unlock(&dest->lock);
mutex_unlock(&driver->msg_mask_lock);
-
+ mutex_unlock(&dest->lock);
return err;
}
@@ -1693,15 +1700,15 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info)
if (!mask_info)
return;
- mutex_lock(&driver->msg_mask_lock);
mutex_lock(&mask_info->lock);
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
kfree(mask->ptr);
mask->ptr = NULL;
}
- mutex_unlock(&mask_info->lock);
mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&mask_info->lock);
__diag_mask_exit(mask_info);
}
@@ -1870,8 +1877,9 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
return -EIO;
}
mutex_unlock(&driver->diag_maskclear_mutex);
- mutex_lock(&driver->msg_mask_lock);
mutex_lock(&mask_info->lock);
+ mutex_lock(&driver->msg_mask_lock);
+
mask = (struct diag_msg_mask_t *)(mask_info->ptr);
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
ptr = mask_info->update_buf;
@@ -1908,8 +1916,8 @@ int diag_copy_to_user_msg_mask(char __user *buf, size_t count,
}
total_len += len;
}
- mutex_unlock(&mask_info->lock);
mutex_unlock(&driver->msg_mask_lock);
+ mutex_unlock(&mask_info->lock);
return err ? err : total_len;
}