summaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2012-09-25 09:01:56 +0200
committerOhad Ben-Cohen <ohad@wizery.com>2012-10-02 09:57:28 +0200
commit7168d914a782086e217214c57ddfc7cc4b738c0c (patch)
tree24219d5248763072a4d683dd0ca667227d42cd0b /drivers/remoteproc
parentremoteproc: select VIRTIO to avoid build breakage (diff)
downloadlinux-7168d914a782086e217214c57ddfc7cc4b738c0c.tar.xz
linux-7168d914a782086e217214c57ddfc7cc4b738c0c.zip
remoteproc: fix a potential NULL-dereference on cleanup
We only need to allocate mapping if there is an IOMMU domain. Otherwise, when the mappings are released, the assumption that an IOMMU domain is there will crash and burn. CC: stable@vger.kernel.org Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> [ohad: revise commit log] Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r--drivers/remoteproc/remoteproc_core.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index b6c622982f8c..f163704b6ce5 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -573,17 +573,10 @@ static int rproc_handle_carveout(struct rproc *rproc,
dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
rsc->da, rsc->pa, rsc->len, rsc->flags);
- mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
- if (!mapping) {
- dev_err(dev, "kzalloc mapping failed\n");
- return -ENOMEM;
- }
-
carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
if (!carveout) {
dev_err(dev, "kzalloc carveout failed\n");
- ret = -ENOMEM;
- goto free_mapping;
+ return -ENOMEM;
}
va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
@@ -613,11 +606,18 @@ static int rproc_handle_carveout(struct rproc *rproc,
* physical address in this case.
*/
if (rproc->domain) {
+ mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping) {
+ dev_err(dev, "kzalloc mapping failed\n");
+ ret = -ENOMEM;
+ goto dma_free;
+ }
+
ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
rsc->flags);
if (ret) {
dev_err(dev, "iommu_map failed: %d\n", ret);
- goto dma_free;
+ goto free_mapping;
}
/*
@@ -662,12 +662,12 @@ static int rproc_handle_carveout(struct rproc *rproc,
return 0;
+free_mapping:
+ kfree(mapping);
dma_free:
dma_free_coherent(dev->parent, rsc->len, va, dma);
free_carv:
kfree(carveout);
-free_mapping:
- kfree(mapping);
return ret;
}