Commit a614db9a authored by Scott Wood's avatar Scott Wood

powerpc/fsl-rio: Fix fsl_rio_setup error paths and use-after-unmap

Several of the error paths from fsl_rio_setup are missing error
messages.

Worse, fsl_rio_setup initializes several global pointers and does not
NULL them out after freeing/unmapping on error.  This caused
fsl_rio_mcheck_exception() to crash when accessing rio_regs_win which
was non-NULL but had been unmapped.
Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
Cc: Liu Gang <Gang.Liu@freescale.com>
---
Liu Gang, are you sure all of these error conditions are fatal?  Why
does the rio driver fail if rmu is not present (e.g.  on t4240)?
parent f6869e7f
...@@ -391,8 +391,10 @@ int fsl_rio_setup(struct platform_device *dev) ...@@ -391,8 +391,10 @@ int fsl_rio_setup(struct platform_device *dev)
ops->get_inb_message = fsl_get_inb_message; ops->get_inb_message = fsl_get_inb_message;
rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0); rmu_node = of_parse_phandle(dev->dev.of_node, "fsl,srio-rmu-handle", 0);
if (!rmu_node) if (!rmu_node) {
dev_err(&dev->dev, "No valid fsl,srio-rmu-handle property\n");
goto err_rmu; goto err_rmu;
}
rc = of_address_to_resource(rmu_node, 0, &rmu_regs); rc = of_address_to_resource(rmu_node, 0, &rmu_regs);
if (rc) { if (rc) {
dev_err(&dev->dev, "Can't get %s property 'reg'\n", dev_err(&dev->dev, "Can't get %s property 'reg'\n",
...@@ -413,6 +415,7 @@ int fsl_rio_setup(struct platform_device *dev) ...@@ -413,6 +415,7 @@ int fsl_rio_setup(struct platform_device *dev)
/*set up doobell node*/ /*set up doobell node*/
np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit"); np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit");
if (!np) { if (!np) {
dev_err(&dev->dev, "No fsl,srio-dbell-unit node\n");
rc = -ENODEV; rc = -ENODEV;
goto err_dbell; goto err_dbell;
} }
...@@ -441,6 +444,7 @@ int fsl_rio_setup(struct platform_device *dev) ...@@ -441,6 +444,7 @@ int fsl_rio_setup(struct platform_device *dev)
/*set up port write node*/ /*set up port write node*/
np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit"); np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit");
if (!np) { if (!np) {
dev_err(&dev->dev, "No fsl,srio-port-write-unit node\n");
rc = -ENODEV; rc = -ENODEV;
goto err_pw; goto err_pw;
} }
...@@ -633,14 +637,18 @@ int fsl_rio_setup(struct platform_device *dev) ...@@ -633,14 +637,18 @@ int fsl_rio_setup(struct platform_device *dev)
return 0; return 0;
err: err:
kfree(pw); kfree(pw);
pw = NULL;
err_pw: err_pw:
kfree(dbell); kfree(dbell);
dbell = NULL;
err_dbell: err_dbell:
iounmap(rmu_regs_win); iounmap(rmu_regs_win);
rmu_regs_win = NULL;
err_rmu: err_rmu:
kfree(ops); kfree(ops);
err_ops: err_ops:
iounmap(rio_regs_win); iounmap(rio_regs_win);
rio_regs_win = NULL;
err_rio_regs: err_rio_regs:
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment