]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
firmware: arm_scmi: Harden clock parents discovery
authorCristian Marussi <cristian.marussi@arm.com>
Fri, 8 May 2026 15:32:53 +0000 (16:32 +0100)
committerSudeep Holla <sudeep.holla@kernel.org>
Tue, 12 May 2026 14:29:11 +0000 (15:29 +0100)
Fix clock parents enumeration to account only for effectively discovered
parents during enumeration, avoiding to trust the total number of parents
declared upfront by the platform.

Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260508153300.2224715-9-cristian.marussi@arm.com
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
drivers/firmware/arm_scmi/clock.c

index c9b62edce4fdcd16f37eb78edce8f0631feb6f0b..d07cfef243fd3916318cb09a00711728763df7c7 100644 (file)
@@ -270,15 +270,15 @@ static int iter_clk_possible_parents_update_state(struct scmi_iterator_state *st
         * assume it's returned+remaining on first call.
         */
        if (!st->max_resources) {
-               p->clkd->info.num_parents = st->num_returned + st->num_remaining;
-               p->clkd->info.parents = devm_kcalloc(p->dev,
-                                                    p->clkd->info.num_parents,
+               int num_parents = st->num_returned + st->num_remaining;
+
+               p->clkd->info.parents = devm_kcalloc(p->dev, num_parents,
                                                     sizeof(*p->clkd->info.parents),
                                                     GFP_KERNEL);
-               if (!p->clkd->info.parents) {
-                       p->clkd->info.num_parents = 0;
+               if (!p->clkd->info.parents)
                        return -ENOMEM;
-               }
+
+               /* max_resources is used by the iterators to control bounds */
                st->max_resources = st->num_returned + st->num_remaining;
        }
 
@@ -293,9 +293,11 @@ static int iter_clk_possible_parents_process_response(const struct scmi_protocol
        const struct scmi_msg_resp_clock_possible_parents *r = response;
        struct scmi_clk_ipriv *p = priv;
 
-       u32 *parent = &p->clkd->info.parents[st->desc_index + st->loop_idx];
+       p->clkd->info.parents[st->desc_index + st->loop_idx] =
+               le32_to_cpu(r->possible_parents[st->loop_idx]);
 
-       *parent = le32_to_cpu(r->possible_parents[st->loop_idx]);
+       /* Count only effectively discovered parents */
+       p->clkd->info.num_parents++;
 
        return 0;
 }