From: sashiko-bot@kernel.org
To: "Manikandan Muralidharan" <manikandan.m@microchip.com>,
pratyush@kernel.org, mwalle@kernel.org,
takahiro.kuwano@infineon.com, miquel.raynal@bootlin.com,
richard@nod.at, vigneshr@ti.com, srini@kernel.org,
linux-mtd@lists.infradead.org
Subject: Re: [PATCH 2/2] nvmem: core: don't defer for a missing cell once the layout is bound
Date: Wed, 11 Nov 2026 13:07:50 +0000 [thread overview]
Message-ID: <sashiko-outbox-209041@kernel.org> (raw)
In-Reply-To: <6b8408e4052882b2d248db3c873242f879e897b0.1794391847.git.manikandan.m@microchip.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [Medium] nvmem: core: race in of_nvmem_cell_get() with concurrent
layout probe
- [Medium] nvmem: core: race in nvmem_layout_pending() with layout init,
probe, and free
- [Low] nvmem: core: missing Fixes trailer for commit fc29fd821d9a
--
commit fb2c3415ead8c8d1df19a4c33f70cbcf0a16033a
Author: Manikandan Muralidharan <manikandan.m@microchip.com>
> nvmem: core: don't defer for a missing cell once the layout is bound
>
> of_nvmem_cell_get() returns -EPROBE_DEFER whenever a requested cell is
> not found and the nvmem device has a layout, assuming the layout has not
> added its cells yet. A layout may add none, e.g. when the data the cell
> describes is not programmed on the device. The layout is then bound but
> the cell is never going to show up, and the consumer is deferred forever
> instead of falling back.
>
> Only defer while the layout device is not bound yet, and return -ENOENT
> once it is, so that a consumer such as an Ethernet MAC can fall back to a
> random address.
>
> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
[Severity: Low]
This looks like a bug fix for layout device handling. Should this
include:
Fixes: fc29fd821d9a ("nvmem: core: Rework layouts to become regular devices")
> diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
> index be3a051500850..f34a35a04e553 100644
> --- a/drivers/nvmem/core.c
> +++ b/drivers/nvmem/core.c
> @@ -1403,6 +1403,31 @@ static int nvmem_layout_module_get_optional(struct nvmem_device *nvmem)
> return 0;
> }
>
> +/**
> + * nvmem_layout_pending() - Check whether a layout may still add cells
> + * @nvmem: nvmem device the layout belongs to
> + *
> + * A layout adds its cells from its probe. Once the layout device is bound,
> + * a cell that is still missing is never going to show up.
> + *
> + * Return: true if @nvmem has a layout that is not bound yet, false otherwise.
> + */
> +static bool nvmem_layout_pending(struct nvmem_device *nvmem)
> +{
> + struct device *dev;
> + bool bound;
> +
> + if (!nvmem->layout)
> + return false;
> +
> + dev = &nvmem->layout->dev;
> + device_lock(dev);
> + bound = device_is_bound(dev);
> + device_unlock(dev);
> +
> + return !bound;
> +}
[Severity: Medium]
Can nvmem_layout_pending() lock an uninitialized or freed mutex on
nvmem->layout->dev?
In nvmem_register(), device_add(&nvmem->dev) publishes the nvmem device on
nvmem_bus_type before nvmem_populate_layout() runs, and
nvmem_layout_create_device() sets nvmem->layout before device_initialize()
initializes layout->dev.mutex:
CPU0 CPU1
nvmem_register()
device_add(&nvmem->dev)
nvmem_populate_layout()
nvmem_layout_create_device()
nvmem->layout = layout;
of_nvmem_cell_get()
...
nvmem_layout_pending()
device_lock(&nvmem->layout->dev)
<-- uninitialized mutex
device_initialize(dev)
Similarly, nvmem_destroy_layout() unregisters and frees nvmem->layout
before nvmem->dev is removed from nvmem_bus_type and without clearing
nvmem->layout, so a concurrent nvmem_layout_pending() can dereference and
lock a freed layout device.
> @@ -1486,7 +1511,7 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
> of_node_put(cell_np);
> if (!cell_entry) {
> nvmem_layout_module_put(nvmem);
> - ret = nvmem->layout ? -EPROBE_DEFER : -ENOENT;
> + ret = nvmem_layout_pending(nvmem) ? -EPROBE_DEFER : -ENOENT;
> nvmem_device_put(nvmem);
> return ERR_PTR(ret);
> }
[Severity: Medium]
Can of_nvmem_cell_get() falsely return -ENOENT when racing with a layout
driver probe?
During really_probe(), device_set_driver() sets layout->dev.driver under
device_lock(&layout->dev) before the layout's probe callback adds cells to
nvmem->cells:
CPU0 CPU1
really_probe(&layout->dev)
device_lock(&layout->dev)
device_set_driver(dev, drv)
of_nvmem_cell_get()
nvmem_layout_module_get_optional()
sees dev.driver != NULL
nvmem_find_cell_entry_by_node()
returns NULL
nvmem_layout_pending()
device_lock(&layout->dev)
call_driver_probe()
adds cell to nvmem->cells
driver_bound(dev)
device_unlock(&layout->dev)
device_is_bound(dev) == true
returns ERR_PTR(-ENOENT)
Consumer drivers then treat a valid cell that was just added as missing.
In addition, if really_probe() fails, device_unbind_cleanup() clears
layout->dev.driver under device_lock(&layout->dev), so
nvmem_layout_module_put() can see dev.driver == NULL and leak the module
reference acquired by nvmem_layout_module_get_optional().
Checking device_is_bound() and taking the module reference under
device_lock(&nvmem->layout->dev) in nvmem_layout_module_get_optional()
before searching nvmem->cells would avoid both issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794391847.git.manikandan.m@microchip.com?part=2
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
prev parent reply other threads:[~2026-11-11 13:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 12:01 [PATCH 0/2] mtd/nvmem: don't defer forever on absent NVMEM suppliers Manikandan Muralidharan
2026-11-11 12:01 ` [PATCH 1/2] mtd: spi-nor: drop fw_devlink suppliers below a flash that failed to probe Manikandan Muralidharan
2026-11-11 12:48 ` sashiko-bot
2026-11-11 12:01 ` [PATCH 2/2] nvmem: core: don't defer for a missing cell once the layout is bound Manikandan Muralidharan
2026-11-11 13:07 ` sashiko-bot [this message]
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-209041@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=manikandan.m@microchip.com \
--cc=miquel.raynal@bootlin.com \
--cc=mwalle@kernel.org \
--cc=pratyush@kernel.org \
--cc=richard@nod.at \
--cc=sashiko-reviews@lists.linux.dev \
--cc=srini@kernel.org \
--cc=takahiro.kuwano@infineon.com \
--cc=vigneshr@ti.com \
/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