Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a614db9a authored by Scott Wood's avatar Scott Wood
Browse files

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
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -391,8 +391,10 @@ int fsl_rio_setup(struct platform_device *dev)
	ops->get_inb_message = fsl_get_inb_message;

	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;
	}
	rc = of_address_to_resource(rmu_node, 0, &rmu_regs);
	if (rc) {
		dev_err(&dev->dev, "Can't get %s property 'reg'\n",
@@ -413,6 +415,7 @@ int fsl_rio_setup(struct platform_device *dev)
	/*set up doobell node*/
	np = of_find_compatible_node(NULL, NULL, "fsl,srio-dbell-unit");
	if (!np) {
		dev_err(&dev->dev, "No fsl,srio-dbell-unit node\n");
		rc = -ENODEV;
		goto err_dbell;
	}
@@ -441,6 +444,7 @@ int fsl_rio_setup(struct platform_device *dev)
	/*set up port write node*/
	np = of_find_compatible_node(NULL, NULL, "fsl,srio-port-write-unit");
	if (!np) {
		dev_err(&dev->dev, "No fsl,srio-port-write-unit node\n");
		rc = -ENODEV;
		goto err_pw;
	}
@@ -633,14 +637,18 @@ int fsl_rio_setup(struct platform_device *dev)
	return 0;
err:
	kfree(pw);
	pw = NULL;
err_pw:
	kfree(dbell);
	dbell = NULL;
err_dbell:
	iounmap(rmu_regs_win);
	rmu_regs_win = NULL;
err_rmu:
	kfree(ops);
err_ops:
	iounmap(rio_regs_win);
	rio_regs_win = NULL;
err_rio_regs:
	return rc;
}