qcacmn: Fix for read and write operations in wmi_recording
With linux4.4 definition of seq_printf is changed. New definition updated in driver applies va_start twice which causes incorrect output hence definition is updated to make sure va_start is applied only once. For write operations using copy_from_user to avoid crash due to accessing user space area. CRs-Fixed: 2042210 IRs-Fixed: 201729 Change-Id: I4043ab027411d42e15adaf53e6e92ae57aa987c7
This commit is contained in:
@@ -98,18 +98,18 @@ typedef PREPACK struct {
|
|||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
|
||||||
/* TODO Cleanup this backported function */
|
/* TODO Cleanup this backported function */
|
||||||
static int qcacld_bp_seq_printf(struct seq_file *m, const char *f, ...)
|
static int wmi_bp_seq_printf(struct seq_file *m, const char *f, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, f);
|
va_start(args, f);
|
||||||
seq_printf(m, f, args);
|
seq_vprintf(m, f, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
return m->count;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
#define seq_printf(m, fmt, ...) qcacld_bp_seq_printf((m), fmt, ##__VA_ARGS__)
|
#define wmi_bp_seq_printf(m, fmt, ...) seq_printf((m), fmt, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WMI_MIN_HEAD_ROOM 64
|
#define WMI_MIN_HEAD_ROOM 64
|
||||||
@@ -758,7 +758,7 @@ const int8_t * const debugfs_dir[MAX_WMI_INSTANCES] = {"WMI0", "WMI1", "WMI2"};
|
|||||||
qdf_spin_lock(&wmi_handle->log_info.wmi_record_lock); \
|
qdf_spin_lock(&wmi_handle->log_info.wmi_record_lock); \
|
||||||
if (!wmi_log->length) { \
|
if (!wmi_log->length) { \
|
||||||
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock);\
|
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock);\
|
||||||
return seq_printf(m, \
|
return wmi_bp_seq_printf(m, \
|
||||||
"no elements to read from ring buffer!\n"); \
|
"no elements to read from ring buffer!\n"); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -773,28 +773,27 @@ const int8_t * const debugfs_dir[MAX_WMI_INSTANCES] = {"WMI0", "WMI1", "WMI2"};
|
|||||||
else \
|
else \
|
||||||
pos = *(wmi_log->p_buf_tail_idx) - 1; \
|
pos = *(wmi_log->p_buf_tail_idx) - 1; \
|
||||||
\
|
\
|
||||||
outlen = seq_printf(m, "Length = %d\n", wmi_log->length);\
|
outlen = wmi_bp_seq_printf(m, "Length = %d\n", wmi_log->length);\
|
||||||
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock); \
|
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock); \
|
||||||
while (nread--) { \
|
while (nread--) { \
|
||||||
struct wmi_command_debug *wmi_record; \
|
struct wmi_command_debug *wmi_record; \
|
||||||
\
|
\
|
||||||
wmi_record = (struct wmi_command_debug *) \
|
wmi_record = (struct wmi_command_debug *) \
|
||||||
&(((struct wmi_command_debug *)wmi_log->buf)[pos]);\
|
&(((struct wmi_command_debug *)wmi_log->buf)[pos]);\
|
||||||
outlen += seq_printf(m, "CMD ID = %x\n", \
|
outlen += wmi_bp_seq_printf(m, "CMD ID = %x\n", \
|
||||||
(wmi_record->command)); \
|
(wmi_record->command)); \
|
||||||
outlen += seq_printf(m, "CMD = "); \
|
outlen += wmi_bp_seq_printf(m, "CMD = "); \
|
||||||
for (i = 0; i < (wmi_record_max_length/ \
|
for (i = 0; i < (wmi_record_max_length/ \
|
||||||
sizeof(uint32_t)); i++) \
|
sizeof(uint32_t)); i++) \
|
||||||
outlen += seq_printf(m, "%x ", \
|
outlen += wmi_bp_seq_printf(m, "%x ", \
|
||||||
wmi_record->data[i]); \
|
wmi_record->data[i]); \
|
||||||
outlen += seq_printf(m, "\n"); \
|
outlen += wmi_bp_seq_printf(m, "\n"); \
|
||||||
\
|
\
|
||||||
if (pos == 0) \
|
if (pos == 0) \
|
||||||
pos = wmi_ring_size - 1; \
|
pos = wmi_ring_size - 1; \
|
||||||
else \
|
else \
|
||||||
pos--; \
|
pos--; \
|
||||||
} \
|
} \
|
||||||
\
|
|
||||||
return outlen; \
|
return outlen; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
@@ -811,7 +810,7 @@ const int8_t * const debugfs_dir[MAX_WMI_INSTANCES] = {"WMI0", "WMI1", "WMI2"};
|
|||||||
qdf_spin_lock(&wmi_handle->log_info.wmi_record_lock); \
|
qdf_spin_lock(&wmi_handle->log_info.wmi_record_lock); \
|
||||||
if (!wmi_log->length) { \
|
if (!wmi_log->length) { \
|
||||||
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock);\
|
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock);\
|
||||||
return seq_printf(m, \
|
return wmi_bp_seq_printf(m, \
|
||||||
"no elements to read from ring buffer!\n"); \
|
"no elements to read from ring buffer!\n"); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -826,28 +825,27 @@ const int8_t * const debugfs_dir[MAX_WMI_INSTANCES] = {"WMI0", "WMI1", "WMI2"};
|
|||||||
else \
|
else \
|
||||||
pos = *(wmi_log->p_buf_tail_idx) - 1; \
|
pos = *(wmi_log->p_buf_tail_idx) - 1; \
|
||||||
\
|
\
|
||||||
outlen = seq_printf(m, "Length = %d\n", wmi_log->length);\
|
outlen = wmi_bp_seq_printf(m, "Length = %d\n", wmi_log->length);\
|
||||||
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock); \
|
qdf_spin_unlock(&wmi_handle->log_info.wmi_record_lock); \
|
||||||
while (nread--) { \
|
while (nread--) { \
|
||||||
struct wmi_event_debug *wmi_record; \
|
struct wmi_event_debug *wmi_record; \
|
||||||
\
|
\
|
||||||
wmi_record = (struct wmi_event_debug *) \
|
wmi_record = (struct wmi_event_debug *) \
|
||||||
&(((struct wmi_event_debug *)wmi_log->buf)[pos]);\
|
&(((struct wmi_event_debug *)wmi_log->buf)[pos]);\
|
||||||
outlen += seq_printf(m, "Event ID = %x\n", \
|
outlen += wmi_bp_seq_printf(m, "Event ID = %x\n",\
|
||||||
(wmi_record->event)); \
|
(wmi_record->event)); \
|
||||||
outlen += seq_printf(m, "CMD = "); \
|
outlen += wmi_bp_seq_printf(m, "CMD = "); \
|
||||||
for (i = 0; i < (wmi_record_max_length/ \
|
for (i = 0; i < (wmi_record_max_length/ \
|
||||||
sizeof(uint32_t)); i++) \
|
sizeof(uint32_t)); i++) \
|
||||||
outlen += seq_printf(m, "%x ", \
|
outlen += wmi_bp_seq_printf(m, "%x ", \
|
||||||
wmi_record->data[i]); \
|
wmi_record->data[i]); \
|
||||||
outlen += seq_printf(m, "\n"); \
|
outlen += wmi_bp_seq_printf(m, "\n"); \
|
||||||
\
|
\
|
||||||
if (pos == 0) \
|
if (pos == 0) \
|
||||||
pos = wmi_ring_size - 1; \
|
pos = wmi_ring_size - 1; \
|
||||||
else \
|
else \
|
||||||
pos--; \
|
pos--; \
|
||||||
} \
|
} \
|
||||||
\
|
|
||||||
return outlen; \
|
return outlen; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,8 +871,8 @@ static int debug_wmi_enable_show(struct seq_file *m, void *v)
|
|||||||
{
|
{
|
||||||
wmi_unified_t wmi_handle = (wmi_unified_t) m->private;
|
wmi_unified_t wmi_handle = (wmi_unified_t) m->private;
|
||||||
|
|
||||||
return seq_printf(m, "%d\n", wmi_handle->log_info.wmi_logging_enable);
|
return wmi_bp_seq_printf(m, "%d\n",
|
||||||
|
wmi_handle->log_info.wmi_logging_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -889,8 +887,10 @@ static int debug_wmi_enable_show(struct seq_file *m, void *v)
|
|||||||
static int debug_wmi_log_size_show(struct seq_file *m, void *v)
|
static int debug_wmi_log_size_show(struct seq_file *m, void *v)
|
||||||
{
|
{
|
||||||
|
|
||||||
seq_printf(m, "WMI command/event log max size:%d\n", wmi_log_max_entry);
|
wmi_bp_seq_printf(m, "WMI command/event log max size:%d\n",
|
||||||
return seq_printf(m, "WMI management command/events log max size:%d\n",
|
wmi_log_max_entry);
|
||||||
|
return wmi_bp_seq_printf(m,
|
||||||
|
"WMI management command/events log max size:%d\n",
|
||||||
wmi_mgmt_log_max_entry);
|
wmi_mgmt_log_max_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,8 +915,15 @@ static int debug_wmi_log_size_show(struct seq_file *m, void *v)
|
|||||||
((struct seq_file *)file->private_data)->private;\
|
((struct seq_file *)file->private_data)->private;\
|
||||||
struct wmi_log_buf_t *wmi_log = &wmi_handle->log_info. \
|
struct wmi_log_buf_t *wmi_log = &wmi_handle->log_info. \
|
||||||
wmi_##func_base##_buf_info; \
|
wmi_##func_base##_buf_info; \
|
||||||
|
char locbuf[50]; \
|
||||||
\
|
\
|
||||||
ret = sscanf(buf, "%d", &k); \
|
if ((!buf) || (count > 50)) \
|
||||||
|
return -EFAULT; \
|
||||||
|
\
|
||||||
|
if (copy_from_user(locbuf, buf, count)) \
|
||||||
|
return -EFAULT; \
|
||||||
|
\
|
||||||
|
ret = sscanf(locbuf, "%d", &k); \
|
||||||
if ((ret != 1) || (k != 0)) { \
|
if ((ret != 1) || (k != 0)) { \
|
||||||
qdf_print("Wrong input, echo 0 to clear the wmi buffer\n");\
|
qdf_print("Wrong input, echo 0 to clear the wmi buffer\n");\
|
||||||
return -EINVAL; \
|
return -EINVAL; \
|
||||||
@@ -964,8 +971,15 @@ static ssize_t debug_wmi_enable_write(struct file *file, const char __user *buf,
|
|||||||
wmi_unified_t wmi_handle =
|
wmi_unified_t wmi_handle =
|
||||||
((struct seq_file *)file->private_data)->private;
|
((struct seq_file *)file->private_data)->private;
|
||||||
int k, ret;
|
int k, ret;
|
||||||
|
char locbuf[50];
|
||||||
|
|
||||||
ret = sscanf(buf, "%d", &k);
|
if ((!buf) || (count > 50))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (copy_from_user(locbuf, buf, count))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
ret = sscanf(locbuf, "%d", &k);
|
||||||
if ((ret != 1) || ((k != 0) && (k != 1)))
|
if ((ret != 1) || ((k != 0) && (k != 1)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user