Linux-Clk Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH] clk: mediatek: clk-mt8173: fix potential memory leak
@ 2020-02-14  3:34 qiwuchen55
  2020-02-14  9:47 ` Matthias Brugger
  0 siblings, 1 reply; 2+ messages in thread
From: qiwuchen55 @ 2020-02-14  3:34 UTC (permalink / raw)
  To: mturquette, sboyd, matthias.bgg
  Cc: kstewart, seiya.wang, gregkh, tglx, linux-clk, linux-mediatek, chenqiwu

From: chenqiwu <chenqiwu@xiaomi.com>

Free clk_data or iomem resources if init is not successful.

Signed-off-by: chenqiwu <chenqiwu@xiaomi.com>
---
 drivers/clk/mediatek/clk-mt8173.c | 43 +++++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 537a7f4..eaf4e70 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -7,6 +7,7 @@
 #include <linux/clk.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/slab.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
@@ -941,9 +942,13 @@ static void __init mtk_topckgen_init(struct device_node *node)
 			&mt8173_clk_lock, clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+		clk_data = NULL;
+		iounmap(base);
+	}
 
 	mtk_clk_enable_critical();
 }
@@ -964,9 +969,11 @@ static void __init mtk_infrasys_init(struct device_node *node)
 				  clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 
 	mtk_register_reset_controller(node, 2, 0x30);
 }
@@ -992,9 +999,12 @@ static void __init mtk_pericfg_init(struct device_node *node)
 			&mt8173_clk_lock, clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+		iounmap(base);
+	}
 
 	mtk_register_reset_controller(node, 2, 0);
 }
@@ -1117,9 +1127,14 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
 	clk_data->clks[CLK_APMIXED_HDMI_REF] = clk;
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		clk_unregister_divider(clk);
+		kfree(clk_data);
+		clk_data = NULL;
+		iounmap(base);
+	}
 
 	mtk_clk_enable_critical();
 }
@@ -1138,9 +1153,11 @@ static void __init mtk_imgsys_init(struct device_node *node)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
 
@@ -1155,9 +1172,11 @@ static void __init mtk_mmsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
 
@@ -1172,9 +1191,11 @@ static void __init mtk_vdecsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
 
@@ -1189,9 +1210,11 @@ static void __init mtk_vencsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
 
@@ -1206,8 +1229,10 @@ static void __init mtk_vencltsys_init(struct device_node *node)
 						clk_data);
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
-	if (r)
+	if (r) {
 		pr_err("%s(): could not register clock provider: %d\n",
 			__func__, r);
+		kfree(clk_data);
+	}
 }
 CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
-- 
1.9.1


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

* Re: [PATCH] clk: mediatek: clk-mt8173: fix potential memory leak
  2020-02-14  3:34 [PATCH] clk: mediatek: clk-mt8173: fix potential memory leak qiwuchen55
@ 2020-02-14  9:47 ` Matthias Brugger
  0 siblings, 0 replies; 2+ messages in thread
From: Matthias Brugger @ 2020-02-14  9:47 UTC (permalink / raw)
  To: qiwuchen55, mturquette, sboyd
  Cc: kstewart, seiya.wang, gregkh, tglx, linux-clk, linux-mediatek, chenqiwu



On 14/02/2020 04:34, qiwuchen55@gmail.com wrote:
> From: chenqiwu <chenqiwu@xiaomi.com>
> 
> Free clk_data or iomem resources if init is not successful.
> 
> Signed-off-by: chenqiwu <chenqiwu@xiaomi.com>
> ---
>  drivers/clk/mediatek/clk-mt8173.c | 43 +++++++++++++++++++++++++++++++--------
>  1 file changed, 34 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index 537a7f4..eaf4e70 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -7,6 +7,7 @@
>  #include <linux/clk.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> +#include <linux/slab.h>
>  
>  #include "clk-mtk.h"
>  #include "clk-gate.h"
> @@ -941,9 +942,13 @@ static void __init mtk_topckgen_init(struct device_node *node)
>  			&mt8173_clk_lock, clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);

we have to free clk_data->clks as well, don't we?
This holds for all the other hunks in this patch as well.

Actually a better solution would be to change mtk_alloc_clk_data to pass it a
struct device and do devm_kzalloc etc. This way we won't need to deal with
freeing data in case of error. This is an API change and includes changes to all
clock drivers of MediaTek though.

Regards,
Matthias

> +		clk_data = NULL;
> +		iounmap(base);
> +	}
>  
>  	mtk_clk_enable_critical();
>  }
> @@ -964,9 +969,11 @@ static void __init mtk_infrasys_init(struct device_node *node)
>  				  clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  
>  	mtk_register_reset_controller(node, 2, 0x30);
>  }
> @@ -992,9 +999,12 @@ static void __init mtk_pericfg_init(struct device_node *node)
>  			&mt8173_clk_lock, clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +		iounmap(base);
> +	}
>  
>  	mtk_register_reset_controller(node, 2, 0);
>  }
> @@ -1117,9 +1127,14 @@ static void __init mtk_apmixedsys_init(struct device_node *node)
>  	clk_data->clks[CLK_APMIXED_HDMI_REF] = clk;
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		clk_unregister_divider(clk);
> +		kfree(clk_data);
> +		clk_data = NULL;
> +		iounmap(base);
> +	}
>  
>  	mtk_clk_enable_critical();
>  }
> @@ -1138,9 +1153,11 @@ static void __init mtk_imgsys_init(struct device_node *node)
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8173-imgsys", mtk_imgsys_init);
>  
> @@ -1155,9 +1172,11 @@ static void __init mtk_mmsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_mmsys, "mediatek,mt8173-mmsys", mtk_mmsys_init);
>  
> @@ -1172,9 +1191,11 @@ static void __init mtk_vdecsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8173-vdecsys", mtk_vdecsys_init);
>  
> @@ -1189,9 +1210,11 @@ static void __init mtk_vencsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_vencsys, "mediatek,mt8173-vencsys", mtk_vencsys_init);
>  
> @@ -1206,8 +1229,10 @@ static void __init mtk_vencltsys_init(struct device_node *node)
>  						clk_data);
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> -	if (r)
> +	if (r) {
>  		pr_err("%s(): could not register clock provider: %d\n",
>  			__func__, r);
> +		kfree(clk_data);
> +	}
>  }
>  CLK_OF_DECLARE(mtk_vencltsys, "mediatek,mt8173-vencltsys", mtk_vencltsys_init);
> 

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

end of thread, back to index

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-14  3:34 [PATCH] clk: mediatek: clk-mt8173: fix potential memory leak qiwuchen55
2020-02-14  9:47 ` Matthias Brugger

Linux-Clk Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-clk/0 linux-clk/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-clk linux-clk/ https://lore.kernel.org/linux-clk \
		linux-clk@vger.kernel.org
	public-inbox-index linux-clk

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-clk


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git