From: sashiko-bot@kernel.org
To: "Vincent Jardin" <vjardin@free.fr>
Cc: conor+dt@kernel.org, robh@kernel.org,
linux-hwmon@vger.kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v2 3/3] hwmon: pmbus: add MPQ8646 driver
Date: Thu, 23 Jul 2026 16:07:17 +0000 [thread overview]
Message-ID: <20260723160717.8AEA61F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260723-mpq8646_v0-v2-3-3c4cb71f23c0@free.fr>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] Stack-allocated buffers are passed to `i2c_transfer()` in `mpq8646_raw_xfer_rword()`, violating DMA mapping rules.
- [Medium] Writing to `alarm_poll_interval_ms` via debugfs fails to restart polling if it was previously disabled.
- [Medium] The driver bypasses the PMBus core lock (`pmbus_lock()`) during concurrent hardware accesses from delayed workers, debugfs, and NVMEM reads.
- [Low] `mpq8646_write_byte` incorrectly hooks the Send Byte callback to intercept `PMBUS_PAGE` writes, making the swallow logic dead code.
- [Low] Multi-variable data race in debugfs probe handlers leads to torn diagnostic data being exposed to userspace.
- [Low] Direct hardware page writes in debugfs bypass PMBus core, permanently desynchronizing the cached page state.
--
--- Patch [3]: [PATCH v2 3/3] hwmon: pmbus: add MPQ8646 driver ---
commit 8f8537703d7daf4f173be90253175f7bc734cf66
Author: Vincent Jardin <vjardin@free.fr>
Subject: hwmon: pmbus: add MPQ8646 driver
This commit adds a new PMBus driver for the MPS MPQ8646 synchronous buck
converter. It provides basic PMBus telemetry along with MPS-specific
extensions for alarm polling, STATUS_WORD decoding, and NVM recovery.
The driver also integrates with the regulator framework and provides debugfs
entries for hardware introspection.
> diff --git a/drivers/hwmon/pmbus/mpq8646.c b/drivers/hwmon/pmbus/mpq8646.c
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/mpq8646.c
[ ... ]
> +static int mpq8646_raw_xfer_rword(struct i2c_client *client, u8 reg)
> +{
> + u8 cmd = reg;
> + __le16 data = 0;
> + struct i2c_msg msg[] = {
> + {
> + .addr = client->addr,
> + .flags = 0,
> + .len = sizeof(cmd),
> + .buf = &cmd,
> + },
> + {
> + .addr = client->addr,
> + .flags = I2C_M_RD,
> + .len = sizeof(data),
> + .buf = (u8 *)&data,
> + },
> + };
[Severity: High]
Is it safe to pass stack-allocated buffers to i2c_transfer() here?
If the underlying I2C adapter driver uses DMA for transfers, dma_map_single()
will attempt to map these stack addresses. On systems with virtually mapped
stacks, this violates DMA mapping rules and could lead to memory corruption.
[ ... ]
> +static int mpq8646_write_byte(struct i2c_client *client, int page, u8 value)
> +{
> + struct mpq8646_priv *priv = mpq8646_priv_from_client(client);
> +
> + atomic_inc(&priv->write_byte_calls);
> + MPQ8646_TRACE("write_byte page=%d value=0x%02x\n", page, value);
> +
> + if (priv->debug_delay_us)
> + udelay(priv->debug_delay_us);
> +
> + if (value == PMBUS_PAGE) {
> + atomic_inc(&priv->page_writes_swallowed);
> + return 0;
> + }
[Severity: Low]
Does this hook effectively intercept page writes?
The write_byte callback is used for the PMBus Send Byte protocol, but PMBus
page changes use the Write Byte Data protocol via i2c_smbus_write_byte_data().
It appears page changes will completely bypass this check.
[ ... ]
> +static int mpq8646_nvmem_read(void *data, unsigned int offset, void *val,
> + size_t bytes)
> +{
> + struct mpq8646_priv *priv = data;
> + u8 *out = val;
> + size_t i;
> +
> + if (offset >= MPQ8646_NVMEM_SIZE)
> + return -EINVAL;
> + if (offset + bytes > MPQ8646_NVMEM_SIZE)
> + bytes = MPQ8646_NVMEM_SIZE - offset;
> +
> + memset(out, 0, bytes);
> +
> + mutex_lock(&priv->mps_lock);
> + for (i = 0; i < ARRAY_SIZE(mpq8646_nvmem_map); i++) {
[Severity: Medium]
Does this sequence bypass the PMBus core serialization?
By using the private mps_lock instead of pmbus_lock(), the PMBus core could
concurrently issue sysfs reads during these NVMEM reads.
[ ... ]
> +static int mpq8646_dbg_probe_smbus_rword(void *data, u64 val)
> +{
> + struct mpq8646_priv *priv = data;
> + int rc;
> +
> + rc = i2c_smbus_read_word_data(priv->client, (u8)val);
> + priv->last_probe_rc = rc;
> + priv->last_probe_data = (rc < 0) ? 0 : (u16)rc;
> + return 0;
> +}
[Severity: Low]
Could concurrent debugfs writes cause torn diagnostic state here?
The last_probe_rc and last_probe_data variables are updated sequentially
without synchronization. This might expose mismatched values to userspace
readers in mpq8646_dbg_last_probe_show().
[ ... ]
> +static int mpq8646_dbg_probe_page_write(void *data, u64 val)
> +{
> + struct mpq8646_priv *priv = data;
> + int rc;
> +
> + rc = i2c_smbus_write_byte_data(priv->client, PMBUS_PAGE, (u8)val);
[Severity: Low]
Could this direct hardware page write desynchronize the PMBus core page cache?
Since the core's software page cache is not updated, and the driver declares
pages = 1, the core assumes page switches are unnecessary and will not restore
it. This could cause sysfs telemetry to return incorrect data until reload.
[ ... ]
> +static int mpq8646_dbg_clear_protection_last_force(void *data, u64 val)
> +{
> + struct mpq8646_priv *priv = data;
> + int rc, last_rc;
> + int wp_orig, cfg_orig;
> +
> + if (!val)
> + return 0;
> +
> + mutex_lock(&priv->mps_lock);
> +
> + wp_orig = i2c_smbus_read_byte_data(priv->client, PMBUS_WRITE_PROTECT);
[Severity: Medium]
Does this multi-step unlock sequence bypass pmbus_lock()?
The PMBus core could issue interleaved sysfs reads while the chip is unlocked
or busy writing to NVM, potentially leading to I2C NACKs.
[ ... ]
> +static void mpq8646_debugfs_register(struct mpq8646_priv *priv)
> +{
[ ... ]
> + debugfs_create_file_unsafe("restore_all", 0200, root, priv,
> + &mpq8646_dbg_restore_all_fops);
> + debugfs_create_u32("alarm_poll_interval_ms", 0600, root,
> + &priv->alarm_poll_interval_ms);
[Severity: Medium]
How is the worker restarted if a user writes to this debugfs file after
disabling polling?
Because the variable is exported directly without a setter function, writing
a non-zero value updates the integer but fails to call schedule_delayed_work()
to re-arm the worker.
[ ... ]
> +static void mpq8646_alarm_poll_work(struct work_struct *work)
> +{
> + struct mpq8646_priv *priv = container_of(to_delayed_work(work),
> + struct mpq8646_priv,
> + alarm_poll_work);
> + int rc;
> + u16 cur, newly_set;
> + size_t i;
> +
> + if (priv->client->irq)
> + return; /* SMBALERT# wired; polling not needed */
> +
> + if (!priv->alarm_poll_interval_ms)
> + return; /* polling disabled; don't re-arm */
> +
> + if (!priv->hwmon_dev)
> + goto rearm; /* hwmon not ready yet; try again next tick */
> +
> + rc = i2c_smbus_read_word_data(priv->client, PMBUS_STATUS_WORD);
[Severity: Medium]
Does this direct hardware telemetry access also bypass pmbus_lock()?
Without the core lock, concurrent accesses from this background worker
could conflict with other sysfs polling.
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260723-mpq8646_v0-v2-0-3c4cb71f23c0@free.fr?part=3
next prev parent reply other threads:[~2026-07-23 16:07 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 15:46 [PATCH v2 0/3] hwmon: pmbus: add MPS MPQ8646 support Vincent Jardin via B4 Relay
2026-07-23 15:46 ` [PATCH v2 1/3] hwmon: pmbus: event notification with alarms Vincent Jardin via B4 Relay
2026-07-23 15:52 ` sashiko-bot
2026-07-23 15:46 ` [PATCH v2 2/3] dt-bindings: hwmon: pmbus: add MPS MPQ8646 binding Vincent Jardin via B4 Relay
2026-07-23 15:53 ` sashiko-bot
2026-07-23 15:46 ` [PATCH v2 3/3] hwmon: pmbus: add MPQ8646 driver Vincent Jardin via B4 Relay
2026-07-23 16:07 ` sashiko-bot [this message]
2026-07-23 20:23 ` Vincent Jardin
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=20260723160717.8AEA61F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vjardin@free.fr \
/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