summaryrefslogtreecommitdiffstats
path: root/drivers/rpmsg
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2018-06-04 05:39:01 -0400
committerBjorn Andersson <bjorn.andersson@linaro.org>2018-06-04 15:35:03 -0400
commit4a2e84c6ed85434ce7843e4844b4d3263f7e233b (patch)
tree44ce7a2a7f84a94d1b3888149f26b7131424a9ca /drivers/rpmsg
parent136200f4fd365a0a9c549893c9641f6eeff53f22 (diff)
rpmsg: smd: do not use mananged resources for endpoints and channels
All the managed resources would be freed by the time release function is invoked. Handling such memory in qcom_smd_edge_release() would do bad things. Found this issue while testing Audio usecase where the dsp is started up and shutdown in a loop. This patch fixes this issue by using simple kzalloc for allocating channel->name and channel which is then freed in qcom_smd_edge_release(). Without this patch restarting a remoteproc would crash the system. Fixes: 53e2822e56c7 ("rpmsg: Introduce Qualcomm SMD backend") Cc: <stable@vger.kernel.org> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Diffstat (limited to 'drivers/rpmsg')
-rw-r--r--drivers/rpmsg/qcom_smd.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
index 6d01eefe2bda..6437bbeebc91 100644
--- a/drivers/rpmsg/qcom_smd.c
+++ b/drivers/rpmsg/qcom_smd.c
@@ -1108,12 +1108,12 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
1108 void *info; 1108 void *info;
1109 int ret; 1109 int ret;
1110 1110
1111 channel = devm_kzalloc(&edge->dev, sizeof(*channel), GFP_KERNEL); 1111 channel = kzalloc(sizeof(*channel), GFP_KERNEL);
1112 if (!channel) 1112 if (!channel)
1113 return ERR_PTR(-ENOMEM); 1113 return ERR_PTR(-ENOMEM);
1114 1114
1115 channel->edge = edge; 1115 channel->edge = edge;
1116 channel->name = devm_kstrdup(&edge->dev, name, GFP_KERNEL); 1116 channel->name = kstrdup(name, GFP_KERNEL);
1117 if (!channel->name) 1117 if (!channel->name)
1118 return ERR_PTR(-ENOMEM); 1118 return ERR_PTR(-ENOMEM);
1119 1119
@@ -1164,8 +1164,8 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
1164 return channel; 1164 return channel;
1165 1165
1166free_name_and_channel: 1166free_name_and_channel:
1167 devm_kfree(&edge->dev, channel->name); 1167 kfree(channel->name);
1168 devm_kfree(&edge->dev, channel); 1168 kfree(channel);
1169 1169
1170 return ERR_PTR(ret); 1170 return ERR_PTR(ret);
1171} 1171}
@@ -1396,13 +1396,13 @@ static int qcom_smd_parse_edge(struct device *dev,
1396 */ 1396 */
1397static void qcom_smd_edge_release(struct device *dev) 1397static void qcom_smd_edge_release(struct device *dev)
1398{ 1398{
1399 struct qcom_smd_channel *channel; 1399 struct qcom_smd_channel *channel, *tmp;
1400 struct qcom_smd_edge *edge = to_smd_edge(dev); 1400 struct qcom_smd_edge *edge = to_smd_edge(dev);
1401 1401
1402 list_for_each_entry(channel, &edge->channels, list) { 1402 list_for_each_entry_safe(channel, tmp, &edge->channels, list) {
1403 SET_RX_CHANNEL_INFO(channel, state, SMD_CHANNEL_CLOSED); 1403 list_del(&channel->list);
1404 SET_RX_CHANNEL_INFO(channel, head, 0); 1404 kfree(channel->name);
1405 SET_RX_CHANNEL_INFO(channel, tail, 0); 1405 kfree(channel);
1406 } 1406 }
1407 1407
1408 kfree(edge); 1408 kfree(edge);