From: sashiko-bot@kernel.org
To: "Joshua Yeong" <joshua.yeong@starfivetech.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v2 5/7] cpufreq: Add RISC-V RPMI cpufreq driver
Date: Thu, 08 Oct 2026 09:23:58 +0000 [thread overview]
Message-ID: <sashiko-outbox-163932@kernel.org> (raw)
In-Reply-To: <20261008091032.2832333-6-joshua.yeong@starfivetech.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] cpufreq: data race on global driver_data during concurrent probe causes NULL dereference
- [Medium] cpufreq: uninitialized stack memory read of args.args[0] on malformed DT
--
commit d5239b6ffbfd0e1e9bde3c75990dec71b8fdd74f
Author: Joshua Yeong <joshua.yeong@starfivetech.com>
cpufreq: Add RISC-V RPMI cpufreq driver
This patch adds a cpufreq driver for RISC-V platforms utilizing the RPMI
performance service group. The driver serves as a front-end over the RPMI
core to manage frequency switching and registers an energy model based on
the power cost of each level.
> diff --git a/drivers/cpufreq/riscv-rpmi-cpufreq.c b/drivers/cpufreq/riscv-rpmi-cpufreq.c
> new file mode 100644
> index 0000000000000..1a5d0248f879e
> --- /dev/null
> +++ b/drivers/cpufreq/riscv-rpmi-cpufreq.c
> @@ -0,0 +1,294 @@
[ ... ]
> +static int rpmi_perf_init(struct cpufreq_policy *policy)
> +{
> + struct cpufreq_frequency_table *freq_table;
> + struct rpmi_perf_cpufreq_data *data;
> + struct rpmi_perf_domain *domain;
> + struct platform_device *pdev = cpufreq_get_driver_data();
> + struct rpmi_perf **mpxy_perf = dev_get_platdata(&pdev->dev);
> + struct of_phandle_args args;
> + int ret, nr_opp;
> + struct device *cpu_dev;
> +
> + cpu_dev = get_cpu_device(policy->cpu);
> + if (!cpu_dev) {
> + pr_err("failed to get cpu%d device\n", policy->cpu);
> + return -ENODEV;
> + }
> +
> + data = kzalloc(sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + ret = of_perf_domain_get_sharing_cpumask(policy->cpu,
> + "performance-domains",
> + "#performance-domain-cells",
> + policy->cpus, &args);
> + if (ret) {
> + dev_err(cpu_dev, "%s: failed to get performance domain info: %d\n",
> + __func__, ret);
> + goto out_free_priv;
> + }
> +
> + /* A domain ID only means something to the provider the CPU names. */
> + if (args.np != dev_of_node(pdev->dev.parent)) {
> + dev_err(cpu_dev, "performance domain of %pOF, not of %pOF\n",
> + args.np, dev_of_node(pdev->dev.parent));
> + of_node_put(args.np);
> + ret = -ENODEV;
> + goto out_free_priv;
> + }
> +
> + domain = rpmi_perf_domain_by_id(*mpxy_perf, args.args[0]);
[Severity: Medium]
Does this read uninitialized stack memory if the device tree is malformed or
specifies #performance-domain-cells = <0>?
If of_perf_domain_get_sharing_cpumask() resolves the phandle but
args.args_count is 0, the args.args array will be left uninitialized since
struct of_phandle_args args was declared on the stack.
Unconditionally consuming args.args[0] could leak uninitialized kernel stack
memory into the domain ID lookup, potentially logging garbage values on
failure and causing erratic domain resolution.
> + of_node_put(args.np);
> + if (!domain) {
> + dev_err(cpu_dev, "performance domain %u is not usable\n",
> + args.args[0]);
> + ret = -EINVAL;
> + goto out_free_priv;
> + }
[ ... ]
> +static int rpmi_cpufreq_probe(struct platform_device *pdev)
> +{
> + struct rpmi_perf **mpxy_perf = dev_get_platdata(&pdev->dev);
> + struct device *dev = &pdev->dev;
> + int ret;
> +
> + if (!mpxy_perf || !*mpxy_perf)
> + return -EINVAL;
> +
> + /*
> + * There is one cpufreq driver for the whole system, so only one
> + * provider can drive the CPUs. Refuse another one rather than point
> + * the registered driver at its domains.
> + */
> + if (rpmi_perf_cpufreq_driver.driver_data)
> + return dev_err_probe(dev, -EBUSY,
> + "CPUs are already driven by another provider\n");
> +
> + rpmi_perf_cpufreq_driver.driver_data = pdev;
> +
> + ret = cpufreq_register_driver(&rpmi_perf_cpufreq_driver);
> + if (ret) {
> + rpmi_perf_cpufreq_driver.driver_data = NULL;
> + return dev_err_probe(dev, ret, "registering cpufreq failed\n");
> + }
[Severity: High]
Is this check-and-set sequence protected against concurrent probing?
If multiple riscv-rpmi-cpufreq platform devices probe concurrently (such as
from asynchronous probing or manual sysfs binds), multiple threads might
bypass the initial if (rpmi_perf_cpufreq_driver.driver_data) check and
overwrite driver_data.
Both threads would then attempt to register the driver. The cpufreq core's
internal locks would cause the second thread to fail with -EEXIST.
The failing thread would execute this error path and set driver_data to NULL,
corrupting the state established by the successful thread.
Later, when the cpufreq core invokes rpmi_perf_init(), it calls
cpufreq_get_driver_data(), which would return NULL. The function then attempts
to access pdev->dev.parent, which could lead to a NULL pointer dereference.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261008091032.2832333-1-joshua.yeong@starfivetech.com?part=5
next prev parent reply other threads:[~2026-10-08 9:23 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-08 9:10 [PATCH v2 0/7] Add RISC-V RPMI performance service support Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 9:10 ` [PATCH v2 1/7] dt-bindings: dvfs: Add RPMI performance service message proxy bindings Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 9:10 ` [PATCH v2 2/7] dt-bindings: dvfs: Add RPMI performance service bindings Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 10:41 ` Conor Dooley
2026-10-08 10:41 ` Conor Dooley
2026-10-08 9:10 ` [PATCH v2 3/7] dt-bindings: riscv: cpus: document performance-domains property Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 9:10 ` [PATCH v2 4/7] firmware: riscv: Add RPMI performance service Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 9:23 ` sashiko-bot
2026-10-08 9:10 ` [PATCH v2 5/7] cpufreq: Add RISC-V RPMI cpufreq driver Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 9:23 ` sashiko-bot [this message]
2026-10-08 9:10 ` [PATCH v2 6/7] pmdomain: riscv: Add RPMI performance domains as power domains Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
2026-10-08 9:27 ` sashiko-bot
2026-10-08 9:10 ` [PATCH v2 7/7] MAINTAINERS: Add RISC-V RPMI performance driver Joshua Yeong
2026-10-08 9:10 ` Joshua Yeong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-163932@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=joshua.yeong@starfivetech.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.