linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] amba: Add amba_read_periphid() helper
@ 2022-04-07 15:02 Kefeng Wang
  2022-04-07 15:02 ` [PATCH 2/2] amba: fix memory leak in amba_device_try_add() Kefeng Wang
  0 siblings, 1 reply; 2+ messages in thread
From: Kefeng Wang @ 2022-04-07 15:02 UTC (permalink / raw)
  To: Russell King, linux-kernel, linux-arm-kernel; +Cc: Rob Herring, Kefeng Wang

Add new amba_read_periphid() helper to simplify error handling.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 drivers/amba/bus.c | 133 +++++++++++++++++++++------------------------
 1 file changed, 62 insertions(+), 71 deletions(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index d3bd14aaabf6..0073d8ba0353 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -395,107 +395,98 @@ static void amba_device_release(struct device *dev)
 	kfree(d);
 }
 
-static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
+static int amba_read_periphid(struct amba_device *dev)
 {
-	u32 size;
+	struct reset_control *rstc;
+	u32 size, pid, cid;
 	void __iomem *tmp;
 	int i, ret;
 
-	ret = request_resource(parent, &dev->res);
+	ret = dev_pm_domain_attach(&dev->dev, true);
 	if (ret)
 		goto err_out;
 
-	/* Hard-coded primecell ID instead of plug-n-play */
-	if (dev->periphid != 0)
-		goto skip_probe;
+	ret = amba_get_enable_pclk(dev);
+	if (ret)
+		goto err_pm;
 
 	/*
-	 * Dynamically calculate the size of the resource
-	 * and use this for iomap
+	 * Find reset control(s) of the amba bus and de-assert them.
 	 */
+	rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node);
+	if (IS_ERR(rstc)) {
+		ret = PTR_ERR(rstc);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&dev->dev, "can't get reset: %d\n", ret);
+		goto err_clk;
+	}
+	reset_control_deassert(rstc);
+	reset_control_put(rstc);
+
 	size = resource_size(&dev->res);
 	tmp = ioremap(dev->res.start, size);
 	if (!tmp) {
 		ret = -ENOMEM;
-		goto err_release;
+		goto err_clk;
 	}
 
-	ret = dev_pm_domain_attach(&dev->dev, true);
-	if (ret) {
-		iounmap(tmp);
-		goto err_release;
-	}
-
-	ret = amba_get_enable_pclk(dev);
-	if (ret == 0) {
-		u32 pid, cid;
-		struct reset_control *rstc;
-
-		/*
-		 * Find reset control(s) of the amba bus and de-assert them.
-		 */
-		rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node);
-		if (IS_ERR(rstc)) {
-			ret = PTR_ERR(rstc);
-			if (ret != -EPROBE_DEFER)
-				dev_err(&dev->dev, "can't get reset: %d\n",
-					ret);
-			goto err_reset;
-		}
-		reset_control_deassert(rstc);
-		reset_control_put(rstc);
-
-		/*
-		 * Read pid and cid based on size of resource
-		 * they are located at end of region
-		 */
-		for (pid = 0, i = 0; i < 4; i++)
-			pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) <<
-				(i * 8);
-		for (cid = 0, i = 0; i < 4; i++)
-			cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) <<
-				(i * 8);
-
-		if (cid == CORESIGHT_CID) {
-			/* set the base to the start of the last 4k block */
-			void __iomem *csbase = tmp + size - 4096;
-
-			dev->uci.devarch =
-				readl(csbase + UCI_REG_DEVARCH_OFFSET);
-			dev->uci.devtype =
-				readl(csbase + UCI_REG_DEVTYPE_OFFSET) & 0xff;
-		}
+	/*
+	 * Read pid and cid based on size of resource
+	 * they are located at end of region
+	 */
+	for (pid = 0, i = 0; i < 4; i++)
+		pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8);
+	for (cid = 0, i = 0; i < 4; i++)
+		cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8);
 
-		amba_put_disable_pclk(dev);
+	if (cid == CORESIGHT_CID) {
+		/* set the base to the start of the last 4k block */
+		void __iomem *csbase = tmp + size - 4096;
 
-		if (cid == AMBA_CID || cid == CORESIGHT_CID) {
-			dev->periphid = pid;
-			dev->cid = cid;
-		}
+		dev->uci.devarch = readl(csbase + UCI_REG_DEVARCH_OFFSET);
+		dev->uci.devtype = readl(csbase + UCI_REG_DEVTYPE_OFFSET) & 0xff;
+	}
 
-		if (!dev->periphid)
-			ret = -ENODEV;
+	if (cid == AMBA_CID || cid == CORESIGHT_CID) {
+		dev->periphid = pid;
+		dev->cid = cid;
 	}
 
+	if (!dev->periphid)
+		ret = -ENODEV;
+
 	iounmap(tmp);
+
+err_clk:
+	amba_put_disable_pclk(dev);
+err_pm:
 	dev_pm_domain_detach(&dev->dev, true);
+err_out:
+	return ret;
+}
 
+static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
+{
+	int ret;
+
+	ret = request_resource(parent, &dev->res);
 	if (ret)
-		goto err_release;
+		goto err_out;
+
+	/* Hard-coded primecell ID instead of plug-n-play */
+	if (dev->periphid != 0)
+		goto skip_probe;
 
- skip_probe:
+	ret = amba_read_periphid(dev);
+	if (ret)
+		goto err_release;
+skip_probe:
 	ret = device_add(&dev->dev);
- err_release:
+err_release:
 	if (ret)
 		release_resource(&dev->res);
- err_out:
+err_out:
 	return ret;
-
- err_reset:
-	amba_put_disable_pclk(dev);
-	iounmap(tmp);
-	dev_pm_domain_detach(&dev->dev, true);
-	goto err_release;
 }
 
 /*
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] amba: fix memory leak in amba_device_try_add()
  2022-04-07 15:02 [PATCH 1/2] amba: Add amba_read_periphid() helper Kefeng Wang
@ 2022-04-07 15:02 ` Kefeng Wang
  0 siblings, 0 replies; 2+ messages in thread
From: Kefeng Wang @ 2022-04-07 15:02 UTC (permalink / raw)
  To: Russell King, linux-kernel, linux-arm-kernel; +Cc: Rob Herring, Kefeng Wang

If amba_device_try_add() return error code (not EPROBE_DEFER),
memory leak occurred when amba device fails to read periphid.

unreferenced object 0xc1c60800 (size 1024):
  comm "swapper/0", pid 1, jiffies 4294937333 (age 75.200s)
  hex dump (first 32 bytes):
    40 40 db c1 04 08 c6 c1 04 08 c6 c1 00 00 00 00  @@..............
    00 d9 c1 c1 84 6f 38 c1 00 00 00 00 01 00 00 00  .....o8.........
  backtrace:
    [<(ptrval)>] kmem_cache_alloc_trace+0x168/0x2b4
    [<(ptrval)>] amba_device_alloc+0x38/0x7c
    [<(ptrval)>] of_platform_bus_create+0x2f4/0x4e8
    [<(ptrval)>] of_platform_bus_create+0x380/0x4e8
    [<(ptrval)>] of_platform_bus_create+0x380/0x4e8
    [<(ptrval)>] of_platform_bus_create+0x380/0x4e8
    [<(ptrval)>] of_platform_populate+0x70/0xc4
    [<(ptrval)>] of_platform_default_populate_init+0xb4/0xcc
    [<(ptrval)>] do_one_initcall+0x58/0x218
    [<(ptrval)>] kernel_init_freeable+0x250/0x29c
    [<(ptrval)>] kernel_init+0x24/0x148
    [<(ptrval)>] ret_from_fork+0x14/0x1c
    [<00000000>] 0x0
unreferenced object 0xc1db4040 (size 64):
  comm "swapper/0", pid 1, jiffies 4294937333 (age 75.200s)
  hex dump (first 32 bytes):
    31 63 30 66 30 30 30 30 2e 77 64 74 00 00 00 00  1c0f0000.wdt....
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<(ptrval)>] __kmalloc_track_caller+0x19c/0x2f8
    [<(ptrval)>] kvasprintf+0x60/0xcc
    [<(ptrval)>] kvasprintf_const+0x54/0x78
    [<(ptrval)>] kobject_set_name_vargs+0x34/0xa8
    [<(ptrval)>] dev_set_name+0x40/0x5c
    [<(ptrval)>] of_device_make_bus_id+0x128/0x1f8
    [<(ptrval)>] of_platform_bus_create+0x4dc/0x4e8
    [<(ptrval)>] of_platform_bus_create+0x380/0x4e8
    [<(ptrval)>] of_platform_bus_create+0x380/0x4e8
    [<(ptrval)>] of_platform_bus_create+0x380/0x4e8
    [<(ptrval)>] of_platform_populate+0x70/0xc4
    [<(ptrval)>] of_platform_default_populate_init+0xb4/0xcc
    [<(ptrval)>] do_one_initcall+0x58/0x218
    [<(ptrval)>] kernel_init_freeable+0x250/0x29c
    [<(ptrval)>] kernel_init+0x24/0x148
    [<(ptrval)>] ret_from_fork+0x14/0x1c

Fix them by adding amba_device_put() to release device name and
amba device.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 drivers/amba/bus.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 0073d8ba0353..7e775ba6fdd9 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -478,8 +478,14 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
 		goto skip_probe;
 
 	ret = amba_read_periphid(dev);
-	if (ret)
+	if (ret) {
+		if (ret != -EPROBE_DEFER) {
+			amba_device_put(dev);
+			goto err_out;
+		}
 		goto err_release;
+	}
+
 skip_probe:
 	ret = device_add(&dev->dev);
 err_release:
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-04-07 14:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-07 15:02 [PATCH 1/2] amba: Add amba_read_periphid() helper Kefeng Wang
2022-04-07 15:02 ` [PATCH 2/2] amba: fix memory leak in amba_device_try_add() Kefeng Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).