summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqctecmdr <qctecmdr@localhost>2020-07-14 05:45:51 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2020-07-14 05:45:51 -0700
commitebfe8dd23f85146ce8ec45ecaaf858c9e3969803 (patch)
treec02931e1392f86d950993b40191ed77085c93616
parentf813d50dc4db8936dcde05ac1fe2d564e590be9d (diff)
parent4744ed702bae3b6c6fa8c59e617631f954eea566 (diff)
downloadmsm-extra-ebfe8dd23f85146ce8ec45ecaaf858c9e3969803.tar.gz
Merge "dsp: Fix a memory leak issue when nvmem read returns invalid length"
-rw-r--r--dsp/adsp-loader.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/dsp/adsp-loader.c b/dsp/adsp-loader.c
index 8316f003..e99d6a3c 100644
--- a/dsp/adsp-loader.c
+++ b/dsp/adsp-loader.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2012-2014, 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2017-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
@@ -333,6 +333,8 @@ static int adsp_loader_probe(struct platform_device *pdev)
int fw_name_size;
u32 adsp_var_idx = 0;
int ret = 0;
+ u32 adsp_fuse_not_supported = 0;
+ const char *adsp_fw_name;
ret = adsp_loader_init_sysfs(pdev);
if (ret != 0) {
@@ -344,15 +346,58 @@ static int adsp_loader_probe(struct platform_device *pdev)
/* get adsp variant idx */
cell = nvmem_cell_get(&pdev->dev, "adsp_variant");
if (IS_ERR_OR_NULL(cell)) {
- dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__);
+ dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n",
+ __func__);
+
+ /*
+ * When ADSP variant read from fuse register is not
+ * supported, check if image with different fw image
+ * name needs to be loaded
+ */
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "adsp-fuse-not-supported",
+ &adsp_fuse_not_supported);
+ if (ret) {
+ dev_dbg(&pdev->dev,
+ "%s: adsp_fuse_not_supported prop not found",
+ __func__, ret);
+ goto wqueue;
+ }
+
+ if (adsp_fuse_not_supported) {
+ /* Read ADSP firmware image name */
+ ret = of_property_read_string(pdev->dev.of_node,
+ "adsp-fw-name",
+ &adsp_fw_name);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "%s: unable to read fw-name\n",
+ __func__);
+ goto wqueue;
+ }
+
+ fw_name_size = strlen(adsp_fw_name) + 1;
+ priv->adsp_fw_name = devm_kzalloc(&pdev->dev,
+ fw_name_size,
+ GFP_KERNEL);
+ if (!priv->adsp_fw_name)
+ goto wqueue;
+ strlcpy(priv->adsp_fw_name, adsp_fw_name,
+ fw_name_size);
+ }
goto wqueue;
}
buf = nvmem_cell_read(cell, &len);
nvmem_cell_put(cell);
- if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(u32)) {
+ if (IS_ERR_OR_NULL(buf)) {
dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
goto wqueue;
}
+ if (len <= 0 || len > sizeof(u32)) {
+ dev_dbg(&pdev->dev, "%s: nvmem cell length out of range: %d\n",
+ __func__, len);
+ kfree(buf);
+ goto wqueue;
+ }
memcpy(&adsp_var_idx, buf, len);
kfree(buf);