[PATCH] pmdomain: arm: scmi: Fix genpd leak on provider registration failure
Ulf Hansson
ulf.hansson at linaro.org
Wed Oct 22 07:18:07 PDT 2025
On Fri, 17 Oct 2025 at 13:03, Sudeep Holla <sudeep.holla at arm.com> wrote:
>
> If of_genpd_add_provider_onecell() fails during probe, the previously
> created generic power domains are not removed, leading to a memory leak
> and potential kernel crash later in genpd_debug_add().
>
> Add proper error handling to unwind the initialized domains before
> returning from probe to ensure all resources are correctly released on
> failure.
>
> Example crash trace observed without this fix:
>
> | Unable to handle kernel paging request at virtual address fffffffffffffc70
> | CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc1 #405 PREEMPT
> | Hardware name: ARM LTD ARM Juno Development Platform/ARM Juno Development Platform
> | pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> | pc : genpd_debug_add+0x2c/0x160
> | lr : genpd_debug_init+0x74/0x98
> | Call trace:
> | genpd_debug_add+0x2c/0x160 (P)
> | genpd_debug_init+0x74/0x98
> | do_one_initcall+0xd0/0x2d8
> | do_initcall_level+0xa0/0x140
> | do_initcalls+0x60/0xa8
> | do_basic_setup+0x28/0x40
> | kernel_init_freeable+0xe8/0x170
> | kernel_init+0x2c/0x140
> | ret_from_fork+0x10/0x20
>
> Fixes: 898216c97ed2 ("firmware: arm_scmi: add device power domain support using genpd")
> Signed-off-by: Sudeep Holla <sudeep.holla at arm.com>
Applied for fixes and by adding a stable tag, thanks!
Kind regards
Uffe
> ---
> drivers/pmdomain/arm/scmi_pm_domain.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pmdomain/arm/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c
> index 8fe1c0a501c9..b5e2ffd5ea64 100644
> --- a/drivers/pmdomain/arm/scmi_pm_domain.c
> +++ b/drivers/pmdomain/arm/scmi_pm_domain.c
> @@ -41,7 +41,7 @@ static int scmi_pd_power_off(struct generic_pm_domain *domain)
>
> static int scmi_pm_domain_probe(struct scmi_device *sdev)
> {
> - int num_domains, i;
> + int num_domains, i, ret;
> struct device *dev = &sdev->dev;
> struct device_node *np = dev->of_node;
> struct scmi_pm_domain *scmi_pd;
> @@ -108,9 +108,18 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
> scmi_pd_data->domains = domains;
> scmi_pd_data->num_domains = num_domains;
>
> + ret = of_genpd_add_provider_onecell(np, scmi_pd_data);
> + if (ret)
> + goto err_rm_genpds;
> +
> dev_set_drvdata(dev, scmi_pd_data);
>
> - return of_genpd_add_provider_onecell(np, scmi_pd_data);
> + return 0;
> +err_rm_genpds:
> + for (i = num_domains - 1; i >= 0; i--)
> + pm_genpd_remove(domains[i]);
> +
> + return ret;
> }
>
> static void scmi_pm_domain_remove(struct scmi_device *sdev)
> --
> 2.34.1
>
More information about the linux-arm-kernel
mailing list