mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] soc: samsung: exynos-pmu: fix of_node leak and refactor regmap lookup
@ 2026-06-09  9:52 geoffrey
  2026-06-09  9:52 ` [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap() geoffrey
  2026-06-09  9:52 ` [PATCH 2/2] soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers geoffrey
  0 siblings, 2 replies; 4+ messages in thread
From: geoffrey @ 2026-06-09  9:52 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
	linux-samsung-soc, linux-kernel, Weigang He

From: Weigang He <geoffreyhe2@gmail.com>

exynos_get_pmu_regmap() leaks the device_node reference taken by
of_find_matching_node(): it passes the node to
exynos_get_pmu_regmap_by_phandle(np, NULL), which with propname == NULL
uses the node directly and never drops the reference.

Patch 1 is the minimal fix: drop the reference in the function that
acquired it. It is small and safe to backport.

Patch 2 is a follow-up cleanup that factors the shared PMU-node lookup
into a helper so that each public function owns and releases only the
node it acquired, removing the need to pass NULL to the by-phandle
helper. It also makes exynos_get_pmu_regmap_by_phandle() reject
propname == NULL with -EINVAL (passing NULL was never a documented use
of that interface). It is a cleanup only and not needed for the fix.

The leak was found by the static analysis tool CodeQL. I do not have
Exynos hardware, so the series has been build-tested only (arm64);
runtime testing on real hardware would be appreciated.

Weigang He (2):
  soc: samsung: exynos-pmu: fix of_node refcount leak in
    exynos_get_pmu_regmap()
  soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers

 drivers/soc/samsung/exynos-pmu.c | 71 +++++++++++++++++++-------------
 1 file changed, 43 insertions(+), 28 deletions(-)


base-commit: 0f61b1860cc3f52aef9036d7235ed1f017632193
-- 
2.43.0


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

* [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap()
  2026-06-09  9:52 [PATCH 0/2] soc: samsung: exynos-pmu: fix of_node leak and refactor regmap lookup geoffrey
@ 2026-06-09  9:52 ` geoffrey
  2026-06-09 10:07   ` Krzysztof Kozlowski
  2026-06-09  9:52 ` [PATCH 2/2] soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers geoffrey
  1 sibling, 1 reply; 4+ messages in thread
From: geoffrey @ 2026-06-09  9:52 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
	linux-samsung-soc, linux-kernel, Weigang He

From: Weigang He <geoffreyhe2@gmail.com>

exynos_get_pmu_regmap() obtains a device_node via of_find_matching_node()
and passes it to exynos_get_pmu_regmap_by_phandle(np, NULL). With
propname == NULL the callee uses np directly and only drops a reference
when propname is set, so the reference taken by of_find_matching_node()
is leaked on every call -- including on each -EPROBE_DEFER retry of the
only in-tree caller, exynos_retention_init() in the Exynos pinctrl
driver.

Drop the reference in the function that acquired it.

Found by static analysis tool CodeQL.

Fixes: 76640b84bd7a ("soc: samsung: pmu: Provide global function to get PMU regmap")
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
---
 drivers/soc/samsung/exynos-pmu.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index d58376c38179b..a5da2741852b4 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -167,11 +167,17 @@ static const struct mfd_cell exynos_pmu_devs[] = {
  */
 struct regmap *exynos_get_pmu_regmap(void)
 {
-	struct device_node *np = of_find_matching_node(NULL,
-						      exynos_pmu_of_device_ids);
-	if (np)
-		return exynos_get_pmu_regmap_by_phandle(np, NULL);
-	return ERR_PTR(-ENODEV);
+	struct device_node *np;
+	struct regmap *regmap;
+
+	np = of_find_matching_node(NULL, exynos_pmu_of_device_ids);
+	if (!np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = exynos_get_pmu_regmap_by_phandle(np, NULL);
+	of_node_put(np);
+
+	return regmap;
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 
-- 
2.43.0


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

* [PATCH 2/2] soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers
  2026-06-09  9:52 [PATCH 0/2] soc: samsung: exynos-pmu: fix of_node leak and refactor regmap lookup geoffrey
  2026-06-09  9:52 ` [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap() geoffrey
@ 2026-06-09  9:52 ` geoffrey
  1 sibling, 0 replies; 4+ messages in thread
From: geoffrey @ 2026-06-09  9:52 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
	linux-samsung-soc, linux-kernel, Weigang He

From: Weigang He <geoffreyhe2@gmail.com>

With the of_node leak in exynos_get_pmu_regmap() now fixed, the remaining
reference handling is still awkward: exynos_get_pmu_regmap() obtains the
PMU node by passing NULL to exynos_get_pmu_regmap_by_phandle(), which then
treats its np argument as the PMU node directly.

Factor the common PMU-node lookup into a helper,
exynos_get_pmu_regmap_by_node(), which only borrows the node. Each public
function then owns and releases the node it acquired: the node from
of_find_matching_node() in exynos_get_pmu_regmap(), and the node from
of_parse_phandle() in exynos_get_pmu_regmap_by_phandle().

exynos_get_pmu_regmap_by_phandle() now rejects propname == NULL with
-EINVAL. Passing NULL was never a documented use of this interface, which
looks up a PMU node through a phandle property; the only in-tree user of
that form is exynos_get_pmu_regmap(), which no longer needs it. Document
the requirement in the kerneldoc.

No functional change for the supported callers.

Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
---
 drivers/soc/samsung/exynos-pmu.c | 57 ++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index a5da2741852b4..ab19ad265aeb1 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -157,6 +157,28 @@ static const struct mfd_cell exynos_pmu_devs[] = {
 	{ .name = "exynos-clkout", },
 };
 
+/*
+ * Look up the regmap of an already-probed exynos-pmu device. The caller
+ * retains ownership of @pmu_np; this helper does not take a reference.
+ */
+static struct regmap *exynos_get_pmu_regmap_by_node(struct device_node *pmu_np)
+{
+	struct device *dev;
+
+	/*
+	 * Determine if exynos-pmu device has probed and therefore regmap
+	 * has been created and can be returned to the caller. Otherwise we
+	 * return -EPROBE_DEFER.
+	 */
+	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver, pmu_np);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	put_device(dev);
+
+	return syscon_node_to_regmap(pmu_np);
+}
+
 /**
  * exynos_get_pmu_regmap() - Obtain pmureg regmap
  *
@@ -174,7 +196,7 @@ struct regmap *exynos_get_pmu_regmap(void)
 	if (!np)
 		return ERR_PTR(-ENODEV);
 
-	regmap = exynos_get_pmu_regmap_by_phandle(np, NULL);
+	regmap = exynos_get_pmu_regmap_by_node(np);
 	of_node_put(np);
 
 	return regmap;
@@ -184,44 +206,31 @@ EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 /**
  * exynos_get_pmu_regmap_by_phandle() - Obtain pmureg regmap via phandle
  * @np: Device node holding PMU phandle property
- * @propname: Name of property holding phandle value
+ * @propname: Name of property holding phandle value (must not be NULL)
  *
  * Find the pmureg regmap previously configured in probe() and return regmap
  * pointer.
  *
- * Return: A pointer to regmap if found or ERR_PTR error value.
+ * Return: A pointer to regmap on success or an ERR_PTR() error value;
+ *         -EINVAL if @propname is NULL.
  */
 struct regmap *exynos_get_pmu_regmap_by_phandle(struct device_node *np,
 						const char *propname)
 {
 	struct device_node *pmu_np;
-	struct device *dev;
+	struct regmap *regmap;
 
-	if (propname)
-		pmu_np = of_parse_phandle(np, propname, 0);
-	else
-		pmu_np = np;
+	if (!propname)
+		return ERR_PTR(-EINVAL);
 
+	pmu_np = of_parse_phandle(np, propname, 0);
 	if (!pmu_np)
 		return ERR_PTR(-ENODEV);
 
-	/*
-	 * Determine if exynos-pmu device has probed and therefore regmap
-	 * has been created and can be returned to the caller. Otherwise we
-	 * return -EPROBE_DEFER.
-	 */
-	dev = driver_find_device_by_of_node(&exynos_pmu_driver.driver,
-					    (void *)pmu_np);
+	regmap = exynos_get_pmu_regmap_by_node(pmu_np);
+	of_node_put(pmu_np);
 
-	if (propname)
-		of_node_put(pmu_np);
-
-	if (!dev)
-		return ERR_PTR(-EPROBE_DEFER);
-
-	put_device(dev);
-
-	return syscon_node_to_regmap(pmu_np);
+	return regmap;
 }
 EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle);
 
-- 
2.43.0


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

* Re: [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap()
  2026-06-09  9:52 ` [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap() geoffrey
@ 2026-06-09 10:07   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 4+ messages in thread
From: Krzysztof Kozlowski @ 2026-06-09 10:07 UTC (permalink / raw)
  To: geoffrey
  Cc: Alim Akhtar, Marek Szyprowski, Tomasz Figa, linux-arm-kernel,
	linux-samsung-soc, linux-kernel

On 09/06/2026 11:52, geoffrey wrote:
> From: Weigang He <geoffreyhe2@gmail.com>
> 
> exynos_get_pmu_regmap() obtains a device_node via of_find_matching_node()
> and passes it to exynos_get_pmu_regmap_by_phandle(np, NULL). With
> propname == NULL the callee uses np directly and only drops a reference
> when propname is set, so the reference taken by of_find_matching_node()
> is leaked on every call -- including on each -EPROBE_DEFER retry of the
> only in-tree caller, exynos_retention_init() in the Exynos pinctrl
> driver.
> 
> Drop the reference in the function that acquired it.
> 
> Found by static analysis tool CodeQL.
> 
> Fixes: 76640b84bd7a ("soc: samsung: pmu: Provide global function to get PMU regmap")
> Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
> ---
>  drivers/soc/samsung/exynos-pmu.c | 16 +++++++++++-----
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index d58376c38179b..a5da2741852b4 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -167,11 +167,17 @@ static const struct mfd_cell exynos_pmu_devs[] = {
>   */
>  struct regmap *exynos_get_pmu_regmap(void)
>  {
> -	struct device_node *np = of_find_matching_node(NULL,
> -						      exynos_pmu_of_device_ids);

Use __free() to make it simpler.

>  


Best regards,
Krzysztof

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

end of thread, other threads:[~2026-06-09 10:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-09  9:52 [PATCH 0/2] soc: samsung: exynos-pmu: fix of_node leak and refactor regmap lookup geoffrey
2026-06-09  9:52 ` [PATCH 1/2] soc: samsung: exynos-pmu: fix of_node refcount leak in exynos_get_pmu_regmap() geoffrey
2026-06-09 10:07   ` Krzysztof Kozlowski
2026-06-09  9:52 ` [PATCH 2/2] soc: samsung: exynos-pmu: refactor PMU regmap lookup helpers geoffrey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®