diff options
| author | Manoj Prabhu B <bmanoj@codeaurora.org> | 2016-06-01 11:36:13 +0530 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-08 15:15:14 -0700 |
| commit | c4fcd60d6908b3efa94a514f692d06b6a2d10c56 (patch) | |
| tree | a0a5bc38e8c5274234373626942b37cc2d791b6f /drivers/char | |
| parent | 7554589ef639bf28082d192debd8a581cc4633fa (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.c | 84 |
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; } |
