summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2012-09-25 10:01:56 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-07 08:35:56 -0700
commita4edc1f646c0cf3b8835d37ce68d8c0b2da42d7c (patch)
treeb71e4c8dd795c6490d580f82eadefb2c69d84061
parentdf34ee9a8a0355d9d2ff59fd62b2d95983619047 (diff)
downloadlwn-a4edc1f646c0cf3b8835d37ce68d8c0b2da42d7c.tar.gz
lwn-a4edc1f646c0cf3b8835d37ce68d8c0b2da42d7c.zip
remoteproc: fix a potential NULL-dereference on cleanup
commit 7168d914a782086e217214c57ddfc7cc4b738c0c upstream. 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. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> [ohad: revise commit log] Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 66324ee4678f..99b6ee749d0d 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -643,17 +643,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, rsc->len, &dma, GFP_KERNEL);
@@ -683,11 +676,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;
}
/*
@@ -728,12 +728,12 @@ static int rproc_handle_carveout(struct rproc *rproc,
return 0;
+free_mapping:
+ kfree(mapping);
dma_free:
dma_free_coherent(dev, rsc->len, va, dma);
free_carv:
kfree(carveout);
-free_mapping:
- kfree(mapping);
return ret;
}