Merge commit '803b2f4ca7a08e658026815f5cd328d795ef3eeb' into HEAD

Change-Id: I1a9c35735dca0aff1da4b728e39a482d7679ff64
Signed-off-by: Pradosh Das <prados@codeaurora.org>
This commit is contained in:
Pradosh Das 2019-05-05 01:44:16 +05:30
commit 6fbccbec21
17 changed files with 187 additions and 42 deletions

View file

@ -542,7 +542,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv,
*/ */
spin_lock(&proc_priv->ctxt_count_lock); spin_lock(&proc_priv->ctxt_count_lock);
if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) {
KGSL_DRV_ERR(device, KGSL_DRV_ERR_RATELIMIT(device,
"Per process context limit reached for pid %u", "Per process context limit reached for pid %u",
dev_priv->process_priv->pid); dev_priv->process_priv->pid);
spin_unlock(&proc_priv->ctxt_count_lock); spin_unlock(&proc_priv->ctxt_count_lock);

View file

@ -3717,7 +3717,12 @@ err_no_work:
for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) && for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) &&
i < num_responses; ++i) { i < num_responses; ++i) {
struct msm_vidc_cb_info *r = &device->response_pkt[i]; struct msm_vidc_cb_info *r = &device->response_pkt[i];
if (!__core_in_valid_state(device)) {
dprintk(VIDC_ERR,
"Ignore responses from %d to %d as device is in invalid state",
(i + 1), num_responses);
break;
}
device->callback(r->response_type, &r->response); device->callback(r->response_type, &r->response);
} }

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2016, 2019, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -507,6 +507,12 @@ static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv)
uint32_t token; uint32_t token;
uint32_t *payload = data->payload; uint32_t *payload = data->payload;
if (data->payload_size < (2 * sizeof(uint32_t))) {
pr_err("%s: payload has invalid size[%d]\n", __func__,
data->payload_size);
return -EINVAL;
}
pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n", pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n",
__func__, payload[0], payload[1], data->opcode); __func__, payload[0], payload[1], data->opcode);
pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n", pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n",
@ -567,6 +573,11 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
} }
if (data->opcode == APR_BASIC_RSP_RESULT) { if (data->opcode == APR_BASIC_RSP_RESULT) {
if (data->payload_size < (2 * sizeof(uint32_t))) {
pr_err("%s: payload has invalid size[%d]\n", __func__,
data->payload_size);
return -EINVAL;
}
/* status field check */ /* status field check */
if (payload[1]) { if (payload[1]) {
pr_err("%s: wrong response[%d] on cmd [%d]\n", pr_err("%s: wrong response[%d] on cmd [%d]\n",
@ -630,6 +641,14 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
opcode = Q6USM_EVENT_READ_DONE; opcode = Q6USM_EVENT_READ_DONE;
spin_lock_irqsave(&port->dsp_lock, dsp_flags); spin_lock_irqsave(&port->dsp_lock, dsp_flags);
if (data->payload_size <
(sizeof(uint32_t)*(READDONE_IDX_STATUS + 1))) {
pr_err("%s: Invalid payload size for READDONE[%d]\n",
__func__, data->payload_size);
spin_unlock_irqrestore(&port->dsp_lock,
dsp_flags);
return -EINVAL;
}
if (payload[READDONE_IDX_STATUS]) { if (payload[READDONE_IDX_STATUS]) {
pr_err("%s: wrong READDONE[%d]; token[%d]\n", pr_err("%s: wrong READDONE[%d]; token[%d]\n",
__func__, __func__,
@ -675,6 +694,12 @@ static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
struct us_port_data *port = &usc->port[IN]; struct us_port_data *port = &usc->port[IN];
opcode = Q6USM_EVENT_WRITE_DONE; opcode = Q6USM_EVENT_WRITE_DONE;
if (data->payload_size <
(sizeof(uint32_t)*(WRITEDONE_IDX_STATUS + 1))) {
pr_err("%s: Invalid payload size for WRITEDONE[%d]\n",
__func__, data->payload_size);
return -EINVAL;
}
if (payload[WRITEDONE_IDX_STATUS]) { if (payload[WRITEDONE_IDX_STATUS]) {
pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n", pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n",
__func__, __func__,

View file

@ -75,6 +75,8 @@ module_param(qmi_timeout, ulong, 0600);
#define ICNSS_MAX_PROBE_CNT 2 #define ICNSS_MAX_PROBE_CNT 2
#define PROBE_TIMEOUT 5000
#define icnss_ipc_log_string(_x...) do { \ #define icnss_ipc_log_string(_x...) do { \
if (icnss_ipc_log_context) \ if (icnss_ipc_log_context) \
ipc_log_string(icnss_ipc_log_context, _x); \ ipc_log_string(icnss_ipc_log_context, _x); \
@ -299,6 +301,7 @@ enum icnss_driver_state {
ICNSS_FW_DOWN, ICNSS_FW_DOWN,
ICNSS_DRIVER_UNLOADING, ICNSS_DRIVER_UNLOADING,
ICNSS_REJUVENATE, ICNSS_REJUVENATE,
ICNSS_BLOCK_SHUTDOWN,
}; };
struct ce_irq_list { struct ce_irq_list {
@ -491,6 +494,7 @@ static struct icnss_priv {
u8 requesting_sub_system; u8 requesting_sub_system;
u16 line_number; u16 line_number;
char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1]; char function_name[QMI_WLFW_FUNCTION_NAME_LEN_V01 + 1];
struct completion unblock_shutdown;
} *penv; } *penv;
#ifdef CONFIG_ICNSS_DEBUG #ifdef CONFIG_ICNSS_DEBUG
@ -1178,6 +1182,21 @@ bool icnss_is_fw_ready(void)
} }
EXPORT_SYMBOL(icnss_is_fw_ready); EXPORT_SYMBOL(icnss_is_fw_ready);
void icnss_block_shutdown(bool status)
{
if (!penv)
return;
if (status) {
set_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state);
reinit_completion(&penv->unblock_shutdown);
} else {
clear_bit(ICNSS_BLOCK_SHUTDOWN, &penv->state);
complete(&penv->unblock_shutdown);
}
}
EXPORT_SYMBOL(icnss_block_shutdown);
bool icnss_is_fw_down(void) bool icnss_is_fw_down(void)
{ {
if (!penv) if (!penv)
@ -2203,6 +2222,7 @@ static int icnss_call_driver_probe(struct icnss_priv *priv)
icnss_hw_power_on(priv); icnss_hw_power_on(priv);
icnss_block_shutdown(true);
while (probe_cnt < ICNSS_MAX_PROBE_CNT) { while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
ret = priv->ops->probe(&priv->pdev->dev); ret = priv->ops->probe(&priv->pdev->dev);
probe_cnt++; probe_cnt++;
@ -2212,9 +2232,11 @@ static int icnss_call_driver_probe(struct icnss_priv *priv)
if (ret < 0) { if (ret < 0) {
icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n",
ret, priv->state, probe_cnt); ret, priv->state, probe_cnt);
icnss_block_shutdown(false);
goto out; goto out;
} }
icnss_block_shutdown(false);
set_bit(ICNSS_DRIVER_PROBED, &priv->state); set_bit(ICNSS_DRIVER_PROBED, &priv->state);
return 0; return 0;
@ -2350,6 +2372,7 @@ static int icnss_driver_event_register_driver(void *data)
if (ret) if (ret)
goto out; goto out;
icnss_block_shutdown(true);
while (probe_cnt < ICNSS_MAX_PROBE_CNT) { while (probe_cnt < ICNSS_MAX_PROBE_CNT) {
ret = penv->ops->probe(&penv->pdev->dev); ret = penv->ops->probe(&penv->pdev->dev);
probe_cnt++; probe_cnt++;
@ -2359,9 +2382,11 @@ static int icnss_driver_event_register_driver(void *data)
if (ret) { if (ret) {
icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n", icnss_pr_err("Driver probe failed: %d, state: 0x%lx, probe_cnt: %d\n",
ret, penv->state, probe_cnt); ret, penv->state, probe_cnt);
icnss_block_shutdown(false);
goto power_off; goto power_off;
} }
icnss_block_shutdown(false);
set_bit(ICNSS_DRIVER_PROBED, &penv->state); set_bit(ICNSS_DRIVER_PROBED, &penv->state);
return 0; return 0;
@ -2584,6 +2609,13 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
if (code != SUBSYS_BEFORE_SHUTDOWN) if (code != SUBSYS_BEFORE_SHUTDOWN)
return NOTIFY_OK; return NOTIFY_OK;
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed &&
test_bit(ICNSS_BLOCK_SHUTDOWN, &priv->state)) {
if (!wait_for_completion_timeout(&priv->unblock_shutdown,
PROBE_TIMEOUT))
icnss_pr_err("wlan driver probe timeout\n");
}
if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) { if (code == SUBSYS_BEFORE_SHUTDOWN && !notif->crashed) {
ret = wlfw_send_modem_shutdown_msg(); ret = wlfw_send_modem_shutdown_msg();
if (ret) if (ret)
@ -3980,6 +4012,9 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
continue; continue;
case ICNSS_DRIVER_UNLOADING: case ICNSS_DRIVER_UNLOADING:
seq_puts(s, "DRIVER UNLOADING"); seq_puts(s, "DRIVER UNLOADING");
continue;
case ICNSS_BLOCK_SHUTDOWN:
seq_puts(s, "BLOCK SHUTDOWN");
} }
seq_printf(s, "UNKNOWN-%d", i); seq_printf(s, "UNKNOWN-%d", i);
@ -4651,6 +4686,8 @@ static int icnss_probe(struct platform_device *pdev)
penv = priv; penv = priv;
init_completion(&priv->unblock_shutdown);
icnss_pr_info("Platform driver probed successfully\n"); icnss_pr_info("Platform driver probed successfully\n");
return 0; return 0;
@ -4673,6 +4710,8 @@ static int icnss_remove(struct platform_device *pdev)
icnss_debugfs_destroy(penv); icnss_debugfs_destroy(penv);
complete_all(&penv->unblock_shutdown);
icnss_modem_ssr_unregister_notifier(penv); icnss_modem_ssr_unregister_notifier(penv);
destroy_ramdump_device(penv->msa0_dump_dev); destroy_ramdump_device(penv->msa0_dump_dev);

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -68,8 +68,9 @@ static void *dummy_q6_mvm;
static void *dummy_q6_cvs; static void *dummy_q6_cvs;
dev_t device_num; dev_t device_num;
static struct mutex session_lock;
static spinlock_t voicesvc_lock; static spinlock_t voicesvc_lock;
static bool is_released; static bool is_released = 1;
static int voice_svc_dummy_reg(void); static int voice_svc_dummy_reg(void);
static int voice_svc_dummy_dereg(void); static int voice_svc_dummy_dereg(void);
@ -645,14 +646,23 @@ static int voice_svc_dummy_dereg(void)
static int voice_svc_open(struct inode *inode, struct file *file) static int voice_svc_open(struct inode *inode, struct file *file)
{ {
struct voice_svc_prvt *prtd = NULL; struct voice_svc_prvt *prtd = NULL;
int ret = 0;
pr_debug("%s\n", __func__); pr_debug("%s\n", __func__);
mutex_lock(&session_lock);
if (is_released == 0) {
pr_err("%s: Access denied to device\n", __func__);
ret = -EBUSY;
goto done;
}
prtd = kmalloc(sizeof(struct voice_svc_prvt), GFP_KERNEL); prtd = kmalloc(sizeof(struct voice_svc_prvt), GFP_KERNEL);
if (prtd == NULL) { if (prtd == NULL) {
pr_err("%s: kmalloc failed\n", __func__); pr_err("%s: kmalloc failed\n", __func__);
return -ENOMEM; ret = -ENOMEM;
goto done;
} }
memset(prtd, 0, sizeof(struct voice_svc_prvt)); memset(prtd, 0, sizeof(struct voice_svc_prvt));
@ -676,7 +686,9 @@ static int voice_svc_open(struct inode *inode, struct file *file)
voice_svc_dummy_reg(); voice_svc_dummy_reg();
reg_dummy_sess = 1; reg_dummy_sess = 1;
} }
return 0; done:
mutex_unlock(&session_lock);
return ret;
} }
static int voice_svc_release(struct inode *inode, struct file *file) static int voice_svc_release(struct inode *inode, struct file *file)
@ -810,6 +822,7 @@ static int voice_svc_probe(struct platform_device *pdev)
} }
pr_debug("%s: Device created\n", __func__); pr_debug("%s: Device created\n", __func__);
spin_lock_init(&voicesvc_lock); spin_lock_init(&voicesvc_lock);
mutex_init(&session_lock);
goto done; goto done;
add_err: add_err:
@ -832,6 +845,7 @@ static int voice_svc_remove(struct platform_device *pdev)
kfree(voice_svc_dev->cdev); kfree(voice_svc_dev->cdev);
device_destroy(voice_svc_class, device_num); device_destroy(voice_svc_class, device_num);
class_destroy(voice_svc_class); class_destroy(voice_svc_class);
mutex_destroy(&session_lock);
unregister_chrdev_region(0, MINOR_NUMBER); unregister_chrdev_region(0, MINOR_NUMBER);
return 0; return 0;

View file

@ -231,7 +231,7 @@ struct pmu {
int capabilities; int capabilities;
int * __percpu pmu_disable_count; int * __percpu pmu_disable_count;
struct perf_cpu_context * __percpu pmu_cpu_context; struct perf_cpu_context __percpu *pmu_cpu_context;
atomic_t exclusive_cnt; /* < 0: cpu; > 0: tsk */ atomic_t exclusive_cnt; /* < 0: cpu; > 0: tsk */
int task_ctx_nr; int task_ctx_nr;
int hrtimer_interval_ms; int hrtimer_interval_ms;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -157,10 +157,5 @@ extern bool icnss_is_rejuvenate(void);
extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len); extern int icnss_set_wlan_mac_address(const u8 *in, const uint32_t len);
extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num); extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
extern int icnss_trigger_recovery(struct device *dev); extern int icnss_trigger_recovery(struct device *dev);
extern void cnss_set_cc_source(enum cnss_cc_src cc_source); extern void icnss_block_shutdown(bool status);
extern enum cnss_cc_src cnss_get_cc_source(void);
extern int icnss_get_driver_load_cnt(void);
extern void icnss_increment_driver_load_cnt(void);
extern void icnss_set_cc_source(enum cnss_cc_src cc_source);
extern enum cnss_cc_src icnss_get_cc_source(void);
#endif /* _ICNSS_WLAN_H_ */ #endif /* _ICNSS_WLAN_H_ */

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -26,7 +26,7 @@
#define LSM_MAX_NUM_CHANNELS 8 #define LSM_MAX_NUM_CHANNELS 8
typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token, typedef void (*lsm_app_cb)(uint32_t opcode, uint32_t token,
uint32_t *payload, void *priv); uint32_t *payload, uint16_t client_size, void *priv);
struct lsm_sound_model { struct lsm_sound_model {
dma_addr_t phys; dma_addr_t phys;

View file

@ -9654,13 +9654,26 @@ static void __perf_event_stop_swclock(void *__info)
static void perf_event_exit_cpu_context(int cpu) static void perf_event_exit_cpu_context(int cpu)
{ {
struct perf_cpu_context *cpuctx;
struct perf_event_context *ctx; struct perf_event_context *ctx;
unsigned long flags;
struct pmu *pmu; struct pmu *pmu;
int idx; int idx;
idx = srcu_read_lock(&pmus_srcu); idx = srcu_read_lock(&pmus_srcu);
list_for_each_entry_rcu(pmu, &pmus, entry) { list_for_each_entry_rcu(pmu, &pmus, entry) {
ctx = &per_cpu_ptr(pmu->pmu_cpu_context, cpu)->ctx; cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
ctx = &cpuctx->ctx;
/* Cancel the mux hrtimer to avoid CPU migration */
if (pmu->task_ctx_nr != perf_sw_context) {
raw_spin_lock_irqsave(&cpuctx->hrtimer_lock, flags);
hrtimer_cancel(&cpuctx->hrtimer);
cpuctx->hrtimer_active = 0;
raw_spin_unlock_irqrestore(&cpuctx->hrtimer_lock,
flags);
}
mutex_lock(&ctx->mutex); mutex_lock(&ctx->mutex);
/* /*
* If keeping events across hotplugging is supported, do not * If keeping events across hotplugging is supported, do not

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, 2019 The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -710,8 +710,8 @@ static int qmi_decode_string_elem(struct elem_info *ei_array, void *buf_dst,
decoded_bytes += rc; decoded_bytes += rc;
} }
if (string_len > temp_ei->elem_len) { if (string_len >= temp_ei->elem_len) {
pr_err("%s: String len %d > Max Len %d\n", pr_err("%s: String len %d >= Max Len %d\n",
__func__, string_len, temp_ei->elem_len); __func__, string_len, temp_ei->elem_len);
return -ETOOSMALL; return -ETOOSMALL;
} else if (string_len > tlv_len) { } else if (string_len > tlv_len) {

View file

@ -579,8 +579,8 @@ country IT: DFS-ETSI
country JM: DFS-FCC country JM: DFS-FCC
(2402 - 2482 @ 40), (20) (2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (24), AUTO-BW (5170 - 5250 @ 80), (24), AUTO-BW
(5250 - 5330 @ 80), (24), DFS, AUTO-BW (5250 - 5330 @ 80), (24), AUTO-BW
(5490 - 5730 @ 160), (24), DFS (5490 - 5730 @ 160), (24)
(5735 - 5835 @ 80), (30) (5735 - 5835 @ 80), (30)
# 60 gHz band channels 1-3, FCC # 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40) (57240 - 63720 @ 2160), (40)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2017, Linux Foundation. All rights reserved. * Copyright (c) 2013-2017, 2019 Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -195,7 +195,8 @@ static int lsm_lab_buffer_sanity(struct lsm_priv *prtd,
} }
static void lsm_event_handler(uint32_t opcode, uint32_t token, static void lsm_event_handler(uint32_t opcode, uint32_t token,
void *payload, void *priv) void *payload, uint16_t client_size,
void *priv)
{ {
unsigned long flags; unsigned long flags;
struct lsm_priv *prtd = priv; struct lsm_priv *prtd = priv;
@ -263,6 +264,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
} }
case LSM_SESSION_EVENT_DETECTION_STATUS: case LSM_SESSION_EVENT_DETECTION_STATUS:
if (client_size < 3 * sizeof(uint8_t)) {
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
return;
}
status = (uint16_t)((uint8_t *)payload)[0]; status = (uint16_t)((uint8_t *)payload)[0];
payload_size = (uint16_t)((uint8_t *)payload)[2]; payload_size = (uint16_t)((uint8_t *)payload)[2];
index = 4; index = 4;
@ -272,6 +279,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
break; break;
case LSM_SESSION_EVENT_DETECTION_STATUS_V2: case LSM_SESSION_EVENT_DETECTION_STATUS_V2:
if (client_size < 2 * sizeof(uint8_t)) {
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
return;
}
status = (uint16_t)((uint8_t *)payload)[0]; status = (uint16_t)((uint8_t *)payload)[0];
payload_size = (uint16_t)((uint8_t *)payload)[1]; payload_size = (uint16_t)((uint8_t *)payload)[1];
index = 2; index = 2;
@ -281,6 +294,12 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
break; break;
case LSM_SESSION_EVENT_DETECTION_STATUS_V3: case LSM_SESSION_EVENT_DETECTION_STATUS_V3:
if (client_size < 2 * (sizeof(uint32_t) + sizeof(uint8_t))) {
dev_err(rtd->dev,
"%s: client_size has invalid size[%d]\n",
__func__, client_size);
return;
}
event_ts_lsw = ((uint32_t *)payload)[0]; event_ts_lsw = ((uint32_t *)payload)[0];
event_ts_msw = ((uint32_t *)payload)[1]; event_ts_msw = ((uint32_t *)payload)[1];
status = (uint16_t)((uint8_t *)payload)[8]; status = (uint16_t)((uint8_t *)payload)[8];
@ -318,12 +337,22 @@ static void lsm_event_handler(uint32_t opcode, uint32_t token,
prtd->event_status->payload_size = payload_size; prtd->event_status->payload_size = payload_size;
if (likely(prtd->event_status)) { if (likely(prtd->event_status)) {
memcpy(prtd->event_status->payload, if (client_size >= (payload_size + index)) {
&((uint8_t *)payload)[index], memcpy(prtd->event_status->payload,
payload_size); &((uint8_t *)payload)[index],
prtd->event_avail = 1; payload_size);
spin_unlock_irqrestore(&prtd->event_lock, flags); prtd->event_avail = 1;
wake_up(&prtd->event_wait); spin_unlock_irqrestore(&prtd->event_lock,
flags);
wake_up(&prtd->event_wait);
} else {
spin_unlock_irqrestore(&prtd->event_lock,
flags);
dev_err(rtd->dev,
"%s: Failed to copy memory with invalid size = %d\n",
__func__, payload_size);
return;
}
} else { } else {
spin_unlock_irqrestore(&prtd->event_lock, flags); spin_unlock_irqrestore(&prtd->event_lock, flags);
dev_err(rtd->dev, dev_err(rtd->dev,

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -1020,6 +1020,13 @@ int msm_adsp_inform_mixer_ctl(struct snd_soc_pcm_runtime *rtd,
} }
event_data = (struct msm_adsp_event_data *)payload; event_data = (struct msm_adsp_event_data *)payload;
if (event_data->payload_len < sizeof(struct msm_adsp_event_data)) {
pr_err("%s: event_data size of %x is less than expected.\n",
__func__, event_data->payload_len);
ret = -EINVAL;
goto done;
}
kctl->info(kctl, &kctl_info); kctl->info(kctl, &kctl_info);
if (event_data->payload_len > if (event_data->payload_len >

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -583,7 +583,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
ret = afe_lpass_resources_callback(data); ret = afe_lpass_resources_callback(data);
atomic_set(&this_afe.state, 0); atomic_set(&this_afe.state, 0);
wake_up(&this_afe.wait[data->token]); if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
else
return -EINVAL;
if (!ret) { if (!ret) {
return ret; return ret;
} }

View file

@ -2180,8 +2180,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
buf_index = asm_token._token.buf_index; buf_index = asm_token._token.buf_index;
if (buf_index < 0 || if (buf_index < 0 ||
buf_index >= port->max_buf_cnt) { buf_index >= port->max_buf_cnt) {
pr_debug("%s: Invalid buffer index %u\n", pr_err("%s: Invalid buffer index %u\n",
__func__, buf_index); __func__, buf_index);
spin_unlock_irqrestore(&port->dsp_lock, spin_unlock_irqrestore(&port->dsp_lock,
dsp_flags); dsp_flags);
spin_unlock_irqrestore( spin_unlock_irqrestore(
@ -2300,8 +2300,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
spin_lock_irqsave(&port->dsp_lock, dsp_flags); spin_lock_irqsave(&port->dsp_lock, dsp_flags);
buf_index = asm_token._token.buf_index; buf_index = asm_token._token.buf_index;
if (buf_index < 0 || buf_index >= port->max_buf_cnt) { if (buf_index < 0 || buf_index >= port->max_buf_cnt) {
pr_debug("%s: Invalid buffer index %u\n", pr_err("%s: Invalid buffer index %u\n",
__func__, buf_index); __func__, buf_index);
spin_unlock_irqrestore(&port->dsp_lock, spin_unlock_irqrestore(&port->dsp_lock,
dsp_flags); dsp_flags);
spin_unlock_irqrestore( spin_unlock_irqrestore(

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2018, Linux Foundation. All rights reserved. * Copyright (c) 2013-2019, Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -127,7 +127,8 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
if (data->opcode == LSM_DATA_EVENT_READ_DONE) { if (data->opcode == LSM_DATA_EVENT_READ_DONE) {
struct lsm_cmd_read_done read_done; struct lsm_cmd_read_done read_done;
token = data->token; token = data->token;
if (data->payload_size > sizeof(read_done)) { if (data->payload_size > sizeof(read_done) ||
data->payload_size < 6 * sizeof(payload[0])) {
pr_err("%s: read done error payload size %d expected size %zd\n", pr_err("%s: read done error payload size %d expected size %zd\n",
__func__, data->payload_size, __func__, data->payload_size,
sizeof(read_done)); sizeof(read_done));
@ -145,6 +146,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
if (client->cb) if (client->cb)
client->cb(data->opcode, data->token, client->cb(data->opcode, data->token,
(void *)&read_done, (void *)&read_done,
sizeof(read_done),
client->priv); client->priv);
return 0; return 0;
} else if (data->opcode == APR_BASIC_RSP_RESULT) { } else if (data->opcode == APR_BASIC_RSP_RESULT) {
@ -171,6 +173,11 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
__func__, token, client->session); __func__, token, client->session);
return -EINVAL; return -EINVAL;
} }
if (data->payload_size < 2 * sizeof(payload[0])) {
pr_err("%s: payload has invalid size[%d]\n",
__func__, data->payload_size);
return -EINVAL;
}
client->cmd_err_code = payload[1]; client->cmd_err_code = payload[1];
if (client->cmd_err_code) if (client->cmd_err_code)
pr_err("%s: cmd 0x%x failed status %d\n", pr_err("%s: cmd 0x%x failed status %d\n",
@ -191,7 +198,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
if (client->cb) if (client->cb)
client->cb(data->opcode, data->token, data->payload, client->cb(data->opcode, data->token, data->payload,
client->priv); data->payload_size, client->priv);
return 0; return 0;
} }
@ -1365,6 +1372,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv)
pr_debug("%s: SSR event received 0x%x, event 0x%x,\n" pr_debug("%s: SSR event received 0x%x, event 0x%x,\n"
"proc 0x%x SID 0x%x\n", __func__, data->opcode, "proc 0x%x SID 0x%x\n", __func__, data->opcode,
data->reset_event, data->reset_proc, sid); data->reset_event, data->reset_proc, sid);
if (sid < LSM_MIN_SESSION_ID || sid > LSM_MAX_SESSION_ID)
pr_err("%s: Invalid session %d\n", __func__, sid);
lsm_common.common_client[sid].lsm_cal_phy_addr = 0; lsm_common.common_client[sid].lsm_cal_phy_addr = 0;
cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX, cal_utils_clear_cal_block_q6maps(LSM_MAX_CAL_IDX,
lsm_common.cal_data); lsm_common.cal_data);
@ -1426,7 +1435,8 @@ static int q6lsm_mmapcallback(struct apr_client_data *data, void *priv)
} }
if (client->cb) if (client->cb)
client->cb(data->opcode, data->token, client->cb(data->opcode, data->token,
data->payload, client->priv); data->payload, data->payload_size,
client->priv);
return 0; return 0;
} }

View file

@ -6782,6 +6782,11 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv)
cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data; cvs_voc_pkt = v->shmem_info.sh_buf.buf[1].data;
if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) { if (cvs_voc_pkt != NULL && common.mvs_info.ul_cb != NULL) {
if (v->shmem_info.sh_buf.buf[1].size <
((3 * sizeof(uint32_t)) + cvs_voc_pkt[2])) {
pr_err("%s: invalid voc pkt size\n", __func__);
return -EINVAL;
}
/* cvs_voc_pkt[0] contains tx timestamp */ /* cvs_voc_pkt[0] contains tx timestamp */
common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3], common.mvs_info.ul_cb((uint8_t *)&cvs_voc_pkt[3],
cvs_voc_pkt[2], cvs_voc_pkt[2],