From: Anvesh Jain P <anvesh.p@oss.qualcomm.com>
To: sashiko-reviews@lists.linux.dev
Cc: robh@kernel.org, devicetree@vger.kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH 2/8] platform: arm64: qcom-hamoa-ec: Add SoC junction temperature reporting
Date: Wed, 5 Aug 2026 16:10:26 +0530 [thread overview]
Message-ID: <020e8c1d-c96c-4dcd-ad6c-1ec9d88a11b2@oss.qualcomm.com> (raw)
In-Reply-To: <20260728180217.26B4B1F000E9@smtp.kernel.org>
On 7/28/2026 11:32 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
> - [High] Race condition in probe leading to NULL pointer dereference in IRQ handler
> - [High] Incorrect error code on device_link_add failure causes permanent probe failure
> - [Medium] Missing `io_lock` acquisition in fan control functions breaks EC command serialization
> - [Medium] Thermal polling delayed work unconditionally requeues itself even if no thermal zones were found
> - [Medium] Suspend error path permanently disables thermal polling
> - [Medium] Integer overflow when accumulating args.args[0] into total leads to heap buffer overflow
> --
>
> --- Patch [2]: [PATCH 2/8] platform: arm64: qcom-hamoa-ec: Add SoC junction temperature reporting ---
> commit d5d00275c6c452ac414dd45c11ca38e64c17b24a
> Author: Anvesh Jain P <anvesh.p@oss.qualcomm.com>
>
> platform: arm64: qcom-hamoa-ec: Add SoC junction temperature reporting
>
> Add the EC command definitions and handler function for reporting the
> SoC junction temperature (Tj) to the EC.
>
> [ ... ]
>
>> diff --git a/drivers/platform/arm64/qcom-hamoa-ec.c b/drivers/platform/arm64/qcom-hamoa-ec.c
>> index 5ca7308c60774..4c745b78322c4 100644
>> --- a/drivers/platform/arm64/qcom-hamoa-ec.c
>> +++ b/drivers/platform/arm64/qcom-hamoa-ec.c
>
> [ ... ]
>
>> @@ -77,10 +89,14 @@ struct qcom_ec_cooling_dev {
>> };
>>
>> struct qcom_ec {
>> + struct i2c_client *client;
>> struct qcom_ec_cooling_dev *ec_cdev;
>> + struct thermal_zone_device **soc_tj_zones;
>> + struct delayed_work soc_tj_work;
>> + struct mutex io_lock; /* serializes EC command sequences */
>
> [Severity: Medium]
> Does this mutex also need to be acquired in existing fan control functions
> like qcom_ec_set_fan_profile()?
>
> Because the thermal framework can invoke fan control at any time, these
> commands might interleave with the new background thermal polling delayed
> work, which could violate the intended EC firmware serialization.
>
Yeah, both callers already hold io_lock around that call, same as
everywhere else in the driver.
>> struct qcom_ec_thermal_cap thermal_cap;
>> struct qcom_ec_version version;
>> - struct i2c_client *client;
>> + int num_soc_tj_zones;
>> };
>
> [ ... ]
>
>> +static int qcom_ec_setup_soc_tj_zones(struct qcom_ec *ec)
>> +{
>> + struct device *dev = &ec->client->dev;
>> + struct device_node *np = dev->of_node;
>> + int nproviders, total, i;
>> +
>> + nproviders = of_property_count_elems_of_size(np, "qcom,tsens",
>> + 2 * sizeof(u32));
>> + if (nproviders <= 0)
>> + return 0;
>> +
>> + total = 0;
>> + for (i = 0; i < nproviders; i++) {
>> + struct of_phandle_args args;
>> +
>> + if (of_parse_phandle_with_fixed_args(np, "qcom,tsens", 1, i, &args))
>> + return -EINVAL;
>> +
>> + of_node_put(args.np);
>> + total += args.args[0];
>
> [Severity: Medium]
> Is it possible for the total accumulation to overflow if the device tree
> provides large values for the qcom,tsens property?
>
> If the sum surpasses the maximum integer value, devm_kcalloc() would allocate
> an undersized array, and the subsequent loop could cause a heap buffer
> overflow when writing to ec->soc_tj_zones.
>
I'm dropping qcom,tsens in favor of thermal-sensors, so this
accumulation code goes away entirely.
>> + }
>> +
>> + ec->soc_tj_zones = devm_kcalloc(dev, total, sizeof(*ec->soc_tj_zones),
>> + GFP_KERNEL);
>> + if (!ec->soc_tj_zones)
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < nproviders; i++) {
>> + struct of_phandle_args args;
>> + struct platform_device *sensor_pdev;
>> + u32 id;
>> +
>> + if (of_parse_phandle_with_fixed_args(np, "qcom,tsens", 1, i, &args))
>> + return -EINVAL;
>> +
>> + sensor_pdev = of_find_device_by_node(args.np);
>> + if (!sensor_pdev) {
>> + of_node_put(args.np);
>> + return -EPROBE_DEFER;
>> + }
>> +
>> + /* Ensure we unbind before the sensor frees its zones */
>> + if (!device_link_add(dev, &sensor_pdev->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
>> + dev_err(dev, "Failed to link to sensor %pOF\n", args.np);
>> + put_device(&sensor_pdev->dev);
>> + of_node_put(args.np);
>> + return -ENODEV;
>
> [Severity: High]
> Should this return -EPROBE_DEFER instead of -ENODEV?
>
> If the EC driver is probing and the sensor is not yet bound to a driver,
> device_link_add() refuses to create a managed link and returns NULL.
> Returning -ENODEV causes the probe to fail permanently, whereas returning
> -EPROBE_DEFER would allow it to try again once the sensor driver binds.
>
No, we already defer earlier if the sensor pdev isn't registered yet, so
that's not why this would fail. The only other case is a dependency
cycle, which won't fix itself on retry, so -ENODEV is right here.
>> + }
>> + put_device(&sensor_pdev->dev);
>
> [ ... ]
>
>> +static void qcom_ec_soc_tj_work_fn(struct work_struct *work)
>> +{
>> + struct qcom_ec *ec = container_of(work, struct qcom_ec, soc_tj_work.work);
>> +
>> + qcom_ec_send_soc_tj_temp(ec);
>> +
>> + queue_delayed_work(system_percpu_wq, &ec->soc_tj_work, EC_SOC_TJ_TEMP_POLL_JIFFIES);
>
> [Severity: Medium]
> Should the work item only be requeued if thermal zones were actually found?
>
> If ec->num_soc_tj_zones is 0, qcom_ec_send_soc_tj_temp() evaluates valid as 0
> and does nothing, and then the work unconditionally requeues itself every
> 125ms, creating a permanent timer tick on systems without these sensors.
>
I'll fix this in the next series, bail out early if num_soc_tj_zones is
0 instead of requeuing unconditionally.
>> +}
>> +
>> static int qcom_ec_resume(struct device *dev)
>
> [ ... ]
>
>> static int qcom_ec_suspend(struct device *dev)
>> {
>> struct i2c_client *client = to_i2c_client(dev);
>> + struct qcom_ec *ec = i2c_get_clientdata(client);
>> + int ret;
>>
>> - return i2c_smbus_write_byte_data(client, EC_MODERN_STANDBY_CMD,
>> - EC_MODERN_STANDBY_ENTER);
>> + disable_delayed_work_sync(&ec->soc_tj_work);
>> +
>> + mutex_lock(&ec->io_lock);
>> + ret = i2c_smbus_write_byte_data(client, EC_MODERN_STANDBY_CMD,
>> + EC_MODERN_STANDBY_ENTER);
>> + mutex_unlock(&ec->io_lock);
>> +
>> + return ret;
>
> [Severity: Medium]
> If the I2C write for the modern standby command fails, does the error path
> leave the thermal polling permanently disabled?
>
> The PM core aborts the system suspend on error but does not call the resume
> callback for the device that failed suspend, so enable_delayed_work() won't
> be called. Should the error path re-enable the delayed work before returning?
>
I'll fix that, re-enable and requeue soc_tj_work on the error path
before returning so polling doesn't stay stuck off.
>> }
>>
>> static int qcom_ec_probe(struct i2c_client *client)
>
> [ ... ]
>
>> @@ -370,10 +587,24 @@ static int qcom_ec_probe(struct i2c_client *client)
>> if (ret < 0)
>> return dev_err_probe(dev, ret, "Failed to enable SCI events\n");
>>
>> + ret = devm_add_action_or_reset(dev, qcom_ec_sci_evt_disable, dev);
>> + if (ret)
>> + return ret;
>> +
>> ret = qcom_ec_thermal_capabilities(dev);
>> if (ret < 0)
>> return dev_err_probe(dev, ret, "Failed to read thermal capabilities\n");
>>
>> + ret = qcom_ec_setup_soc_tj_zones(ec);
>
> [Severity: High]
> Can an SCI event trigger the IRQ handler before the probe finishes, causing
> a NULL pointer dereference?
>
> The IRQ is requested and SCI events are enabled on the EC prior to calling
> qcom_ec_setup_soc_tj_zones(), which allocates ec->ec_cdev further down in
> the probe function.
>
> If an event fires in this widened window, or if the setup fails and returns
> an error, qcom_ec_irq() can execute before devres disables the IRQ. The
> handler checks if the fan_id is less than ec->thermal_cap.fan_cnt, which
> would be true, and then dereferences the unallocated ec_cdev array.
>
I'll move the IRQ request and SCI-event enable to after the fan cooling
devices and ec_cdev array are set up, so the handler can't fire before
ec_cdev is allocated.
>> + if (ret < 0)
>> + return dev_err_probe(dev, ret, "Failed to setup SoC Tj thermal zones\n");
>> +
>> + ret = devm_delayed_work_autocancel(dev, &ec->soc_tj_work, qcom_ec_soc_tj_work_fn);
>> + if (ret)
>> + return ret;
>> +
>> + queue_delayed_work(system_percpu_wq, &ec->soc_tj_work, EC_SOC_TJ_TEMP_POLL_JIFFIES);
>
> [Severity: Medium]
> Could we avoid queueing the work initially if ec->num_soc_tj_zones is 0?
>
> Similar to the requeue path, this starts a background polling process even
> if no thermal zones were found during setup.
>
I'll make sure that only queues when num_soc_tj_zones is non-zero.
>> +
>> if (ec->thermal_cap.fan_cnt == 0) {
>> dev_warn(dev, FW_BUG "Failed to get fan count, firmware update required\n");
>> return 0;
>
--
Best Regards,
Anvesh
next prev parent reply other threads:[~2026-08-05 10:40 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-28 17:44 [PATCH 0/8] Extend Qualcomm reference device EC driver with fan LUT, profile and SoC Tj support Anvesh Jain P
2026-07-28 17:44 ` [PATCH 1/8] dt-bindings: embedded-controller: qcom,hamoa-crd-ec: Add qcom,tsens Anvesh Jain P
2026-07-28 17:54 ` sashiko-bot
2026-08-05 9:54 ` Anvesh Jain P
2026-07-29 11:08 ` Krzysztof Kozlowski
2026-07-29 11:54 ` Anvesh Jain P
2026-07-29 12:32 ` Krzysztof Kozlowski
2026-07-29 13:00 ` Anvesh Jain P
2026-07-29 11:13 ` Konrad Dybcio
2026-07-29 12:13 ` Anvesh Jain P
2026-07-30 17:11 ` Konrad Dybcio
2026-07-31 5:55 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 2/8] platform: arm64: qcom-hamoa-ec: Add SoC junction temperature reporting Anvesh Jain P
2026-07-28 18:02 ` sashiko-bot
2026-08-05 10:40 ` Anvesh Jain P [this message]
2026-07-29 10:59 ` Konrad Dybcio
2026-07-29 13:03 ` Anvesh Jain P
2026-07-30 17:04 ` Konrad Dybcio
2026-07-31 5:47 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 3/8] platform: arm64: qcom-hamoa-ec: Switch fan profile based on power supply state Anvesh Jain P
2026-07-28 18:05 ` sashiko-bot
2026-08-05 13:12 ` Anvesh Jain P
2026-07-29 11:02 ` Konrad Dybcio
2026-07-30 6:21 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 4/8] platform: arm64: qcom-hamoa-ec: Add fan RPM query and LUT calibration Anvesh Jain P
2026-07-28 18:15 ` sashiko-bot
2026-08-05 13:15 ` Anvesh Jain P
2026-07-29 11:07 ` Konrad Dybcio
2026-07-30 6:35 ` Anvesh Jain P
2026-07-30 17:08 ` Konrad Dybcio
2026-07-31 6:25 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 5/8] platform: arm64: qcom-hamoa-ec: Verify required I2C adapter functionality Anvesh Jain P
2026-07-28 18:14 ` sashiko-bot
2026-08-05 14:20 ` Anvesh Jain P
2026-07-29 11:08 ` Konrad Dybcio
2026-07-30 6:37 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 6/8] platform: arm64: qcom-hamoa-ec: Retry I2C transfers on NACK Anvesh Jain P
2026-07-28 18:26 ` sashiko-bot
2026-08-05 15:10 ` Anvesh Jain P
2026-07-29 11:11 ` Konrad Dybcio
2026-07-30 6:40 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 7/8] arm64: dts: qcom: x1p42100-crd: Add qcom,tsens for EC fan thermal management Anvesh Jain P
2026-07-28 18:26 ` sashiko-bot
2026-08-06 4:29 ` Anvesh Jain P
2026-07-28 17:44 ` [PATCH 8/8] arm64: dts: qcom: x1e80100-crd: " Anvesh Jain P
2026-07-28 18:36 ` sashiko-bot
2026-08-06 4:37 ` Anvesh Jain P
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=020e8c1d-c96c-4dcd-ad6c-1ec9d88a11b2@oss.qualcomm.com \
--to=anvesh.p@oss.qualcomm.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox