summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-05-16 06:49:26 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-05-16 06:49:26 -0700
commit40e4c19332cca1a2c7eb86cf498ab17c4a024204 (patch)
tree962d59f93452f735c39ce02e125e3dffd140534d
parent3715a9458a427ffd8289d01f7be155f65002ff98 (diff)
parentf09aee50c2ee6b79d94cb42eafc82413968b15cb (diff)
Merge "diag: Add proper synchronization checks to msg mask table"
-rw-r--r--drivers/char/diag/diag_masks.c65
-rw-r--r--drivers/char/diag/diagchar.h2
-rw-r--r--drivers/char/diag/diagchar_core.c1
-rw-r--r--drivers/char/diag/diagfwd_cntl.c11
4 files changed, 49 insertions, 30 deletions
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 3c10462c2274..382717bad828 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -309,10 +309,12 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
return;
-
+ mutex_lock(&driver->msg_mask_lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
- if (!mask->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) {
@@ -385,6 +387,7 @@ proceed:
}
err:
mutex_unlock(&mask_info->lock);
+ mutex_unlock(&driver->msg_mask_lock);
}
static void diag_send_time_sync_update(uint8_t peripheral)
@@ -506,7 +509,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;
@@ -514,7 +517,6 @@ static int diag_cmd_get_ssid_range(unsigned char *src_buf, int src_len,
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) {
@@ -527,7 +529,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;
}
@@ -551,7 +553,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;
@@ -559,9 +561,8 @@ static int diag_cmd_get_build_mask(unsigned char *src_buf, int src_len,
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;
@@ -582,7 +583,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;
}
@@ -610,6 +611,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;
@@ -617,7 +619,6 @@ static int diag_cmd_get_msg_mask(unsigned char *src_buf, int src_len,
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) ||
@@ -635,7 +636,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;
}
@@ -666,7 +667,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(&mask_info->lock);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -726,7 +727,7 @@ static int diag_cmd_set_msg_mask(unsigned char *src_buf, int src_len,
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);
@@ -779,7 +780,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);
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 :
@@ -791,6 +792,7 @@ static int diag_cmd_set_all_msg_mask(unsigned char *src_buf, int src_len,
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);
@@ -1294,6 +1296,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++) {
@@ -1304,6 +1307,7 @@ static int diag_create_msg_mask_table(void)
break;
}
mutex_unlock(&msg_mask.lock);
+ mutex_unlock(&driver->msg_mask_lock);
return err;
}
@@ -1316,9 +1320,11 @@ 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);
+ 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);
@@ -1429,6 +1435,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;
}
@@ -1576,10 +1583,11 @@ 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_PERIPHERALS; i++)
driver->max_ssid_count[i] = 0;
+ mutex_unlock(&driver->msg_mask_lock);
return 0;
}
@@ -1598,7 +1606,7 @@ 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);
src_mask = (struct diag_msg_mask_t *)src->ptr;
dest_mask = (struct diag_msg_mask_t *)dest->ptr;
@@ -1617,6 +1625,7 @@ int diag_msg_mask_copy(struct diag_mask_info *dest, struct diag_mask_info *src)
dest_mask++;
}
mutex_unlock(&dest->lock);
+ mutex_unlock(&driver->msg_mask_lock);
return err;
}
@@ -1628,7 +1637,7 @@ 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);
mask = (struct diag_msg_mask_t *)mask_info->ptr;
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1636,7 +1645,7 @@ void diag_msg_mask_free(struct diag_mask_info *mask_info)
mask->ptr = NULL;
}
mutex_unlock(&mask_info->lock);
-
+ mutex_unlock(&driver->msg_mask_lock);
__diag_mask_exit(mask_info);
}
@@ -1644,15 +1653,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)
@@ -1677,13 +1688,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)
@@ -1801,7 +1814,7 @@ 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);
mask = (struct diag_msg_mask_t *)(mask_info->ptr);
for (i = 0; i < driver->msg_mask_tbl_count; i++, mask++) {
@@ -1840,7 +1853,7 @@ 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);
return err ? err : total_len;
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index b17538a10ea9..4047a2c42bb7 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -627,8 +627,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_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 dc2d9fc4282c..60bfb2af49d0 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -3570,6 +3570,7 @@ static int __init diagchar_init(void)
mutex_init(&driver->diag_file_mutex);
mutex_init(&driver->delayed_rsp_mutex);
mutex_init(&apps_data_mutex);
+ mutex_init(&driver->msg_mask_lock);
for (i = 0; i < NUM_PERIPHERALS; i++)
mutex_init(&driver->diagfwd_channel_mutex[i]);
mutex_init(&driver->diagfwd_untag_mutex);
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index 82a67f1f6f47..729fbf4fc145 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -548,6 +548,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len,
/* 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;
@@ -591,6 +592,7 @@ static void process_ssid_range_report(uint8_t *buf, uint32_t len,
}
driver->msg_mask_tbl_count += 1;
}
+ mutex_unlock(&driver->msg_mask_lock);
}
static void diag_build_time_mask_update(uint8_t *buf,
@@ -615,11 +617,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;
- 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;
@@ -638,7 +640,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) {
@@ -653,8 +655,9 @@ 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->msg_mask_lock);
return;
}