summaryrefslogtreecommitdiff
path: root/drivers/char
diff options
context:
space:
mode:
authorManoj Prabhu B <bmanoj@codeaurora.org>2016-06-01 11:36:13 +0530
committerKyle Yan <kyan@codeaurora.org>2016-06-08 15:15:14 -0700
commitc4fcd60d6908b3efa94a514f692d06b6a2d10c56 (patch)
treea0a5bc38e8c5274234373626942b37cc2d791b6f /drivers/char
parent7554589ef639bf28082d192debd8a581cc4633fa (diff)
diag: Fix for corrupted dci log mask
This patch fixes the possible corruption of the dci client entries log mask during deinit of dci entries. CRs-Fixed: 1021816 Change-Id: I7741eca6ac07cd4393fc373e796570066da7cce6 Signed-off-by: Manoj Prabhu B <bmanoj@codeaurora.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/diag/diag_dci.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index ec952974f1d6..1000b2595a83 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -2204,13 +2204,17 @@ struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int tgid)
void update_dci_cumulative_event_mask(int offset, uint8_t byte_mask, int token)
{
- uint8_t *event_mask_ptr;
- uint8_t *update_ptr = dci_ops_tbl[token].event_mask_composite;
+ uint8_t *event_mask_ptr, *update_ptr = NULL;
struct list_head *start, *temp;
struct diag_dci_client_tbl *entry = NULL;
bool is_set = false;
mutex_lock(&dci_event_mask_mutex);
+ update_ptr = dci_ops_tbl[token].event_mask_composite;
+ if (!update_ptr) {
+ mutex_unlock(&dci_event_mask_mutex);
+ return;
+ }
update_ptr += offset;
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
@@ -2236,13 +2240,15 @@ void diag_dci_invalidate_cumulative_event_mask(int token)
int i = 0;
struct list_head *start, *temp;
struct diag_dci_client_tbl *entry = NULL;
- uint8_t *update_ptr, *event_mask_ptr;
- update_ptr = dci_ops_tbl[token].event_mask_composite;
+ uint8_t *event_mask_ptr, *update_ptr = NULL;
- if (!update_ptr)
+ mutex_lock(&dci_event_mask_mutex);
+ update_ptr = dci_ops_tbl[token].event_mask_composite;
+ if (!update_ptr) {
+ mutex_unlock(&dci_event_mask_mutex);
return;
+ }
- mutex_lock(&dci_event_mask_mutex);
create_dci_event_mask_tbl(update_ptr);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
@@ -2264,14 +2270,20 @@ int diag_send_dci_event_mask_remote(int token)
int dci_header_size = sizeof(struct diag_dci_header_t);
int event_header_size = sizeof(struct diag_ctrl_event_mask);
int i, ret = DIAG_DCI_NO_ERROR, err = DIAG_DCI_NO_ERROR;
- unsigned char *event_mask_ptr = dci_ops_tbl[token].
- event_mask_composite;
+ unsigned char *event_mask_ptr = NULL;
uint32_t write_len = 0;
+ mutex_lock(&dci_event_mask_mutex);
+ event_mask_ptr = dci_ops_tbl[token].event_mask_composite;
+ if (!event_mask_ptr) {
+ mutex_unlock(&dci_event_mask_mutex);
+ return -EINVAL;
+ }
buf = dci_get_buffer_from_bridge(token);
if (!buf) {
pr_err("diag: In %s, unable to get dci buffers to write data\n",
__func__);
+ mutex_unlock(&dci_event_mask_mutex);
return -EAGAIN;
}
@@ -2310,7 +2322,7 @@ int diag_send_dci_event_mask_remote(int token)
} else {
ret = DIAG_DCI_NO_ERROR;
}
-
+ mutex_unlock(&dci_event_mask_mutex);
return ret;
}
#endif
@@ -2321,8 +2333,14 @@ int diag_send_dci_event_mask(int token)
struct diag_ctrl_event_mask header;
int header_size = sizeof(struct diag_ctrl_event_mask);
int ret = DIAG_DCI_NO_ERROR, err = DIAG_DCI_NO_ERROR, i;
- unsigned char *event_mask_ptr = dci_ops_tbl[DCI_LOCAL_PROC].
- event_mask_composite;
+ unsigned char *event_mask_ptr = NULL;
+
+ mutex_lock(&dci_event_mask_mutex);
+ event_mask_ptr = dci_ops_tbl[DCI_LOCAL_PROC].event_mask_composite;
+ if (!event_mask_ptr) {
+ mutex_unlock(&dci_event_mask_mutex);
+ return -EINVAL;
+ }
mutex_lock(&event_mask.lock);
/* send event mask update */
@@ -2351,7 +2369,9 @@ int diag_send_dci_event_mask(int token)
if (err != DIAG_DCI_NO_ERROR)
ret = DIAG_DCI_SEND_DATA_FAIL;
}
+
mutex_unlock(&event_mask.lock);
+ mutex_unlock(&dci_event_mask_mutex);
return ret;
}
@@ -2359,13 +2379,18 @@ int diag_send_dci_event_mask(int token)
void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
uint8_t byte_mask, int token)
{
- uint8_t *update_ptr = dci_ops_tbl[token].log_mask_composite;
- uint8_t *log_mask_ptr;
+ uint8_t *log_mask_ptr, *update_ptr = NULL;
bool is_set = false;
struct list_head *start, *temp;
struct diag_dci_client_tbl *entry = NULL;
mutex_lock(&dci_log_mask_mutex);
+ update_ptr = dci_ops_tbl[token].log_mask_composite;
+ if (!update_ptr) {
+ mutex_unlock(&dci_log_mask_mutex);
+ return;
+ }
+
update_ptr += offset;
/* update the dirty bit */
*(update_ptr+1) = 1;
@@ -2395,11 +2420,16 @@ void diag_dci_invalidate_cumulative_log_mask(int token)
int i = 0;
struct list_head *start, *temp;
struct diag_dci_client_tbl *entry = NULL;
- uint8_t *update_ptr, *log_mask_ptr;
- update_ptr = dci_ops_tbl[token].log_mask_composite;
+ uint8_t *log_mask_ptr, *update_ptr = NULL;
/* Clear the composite mask and redo all the masks */
mutex_lock(&dci_log_mask_mutex);
+ update_ptr = dci_ops_tbl[token].log_mask_composite;
+ if (!update_ptr) {
+ mutex_unlock(&dci_log_mask_mutex);
+ return;
+ }
+
create_dci_log_mask_tbl(update_ptr, DCI_LOG_MASK_DIRTY);
list_for_each_safe(start, temp, &driver->dci_client_list) {
entry = list_entry(start, struct diag_dci_client_tbl, track);
@@ -2438,11 +2468,18 @@ int diag_send_dci_log_mask_remote(int token)
struct diag_dci_header_t dci_header;
int dci_header_size = sizeof(struct diag_dci_header_t);
int log_header_size = sizeof(struct diag_ctrl_log_mask);
- uint8_t *log_mask_ptr = dci_ops_tbl[token].log_mask_composite;
+ uint8_t *log_mask_ptr = NULL;
int i, ret = DIAG_DCI_NO_ERROR, err = DIAG_DCI_NO_ERROR;
int updated;
uint32_t write_len = 0;
+ mutex_lock(&dci_log_mask_mutex);
+ log_mask_ptr = dci_ops_tbl[token].log_mask_composite;
+ if (!log_mask_ptr) {
+ mutex_unlock(&dci_log_mask_mutex);
+ return -EINVAL;
+ }
+
/* DCI header is common to all equipment IDs */
dci_header.start = CONTROL_CHAR;
dci_header.version = 1;
@@ -2461,6 +2498,7 @@ int diag_send_dci_log_mask_remote(int token)
if (!buf) {
pr_err("diag: In %s, unable to get dci buffers to write data\n",
__func__);
+ mutex_unlock(&dci_log_mask_mutex);
return -EAGAIN;
}
@@ -2480,7 +2518,7 @@ int diag_send_dci_log_mask_remote(int token)
*(log_mask_ptr + 1) = 0; /* clear dirty byte */
log_mask_ptr += 514;
}
-
+ mutex_unlock(&dci_log_mask_mutex);
return ret;
}
#endif
@@ -2489,10 +2527,18 @@ int diag_send_dci_log_mask(int token)
{
void *buf = log_mask.update_buf;
int write_len = 0;
- uint8_t *log_mask_ptr = dci_ops_tbl[DCI_LOCAL_PROC].log_mask_composite;
+ uint8_t *log_mask_ptr = NULL;
int i, j, ret = DIAG_DCI_NO_ERROR, err = DIAG_DCI_NO_ERROR;
int updated;
+
+ mutex_lock(&dci_log_mask_mutex);
+ log_mask_ptr = dci_ops_tbl[DCI_LOCAL_PROC].log_mask_composite;
+ if (!log_mask_ptr) {
+ mutex_unlock(&dci_log_mask_mutex);
+ return -EINVAL;
+ }
+
mutex_lock(&log_mask.lock);
for (i = 0; i < 16; i++) {
updated = 1;
@@ -2515,7 +2561,7 @@ int diag_send_dci_log_mask(int token)
log_mask_ptr += 514;
}
mutex_unlock(&log_mask.lock);
-
+ mutex_unlock(&dci_log_mask_mutex);
return ret;
}