summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Koskovich <AKoskovich@pm.me>2025-12-14 22:16:18 +0300
committerSasha Levin <sashal@kernel.org>2026-03-04 15:20:17 +0300
commite9667db8b17e1fba8974bef6d1f46fbe35c9dbf0 (patch)
tree88616b570ffceb2106e831939c670c7fbbbe1acd
parent82d3eb97a976c9d56bb92b241397610e57a9c629 (diff)
downloadlinux-e9667db8b17e1fba8974bef6d1f46fbe35c9dbf0.tar.xz
power: reset: nvmem-reboot-mode: respect cell size for nvmem_cell_write
[ Upstream commit 36b05629226413836cfbb3fbe6689cd188bca156 ] Some platforms expose reboot mode cells that are smaller than an unsigned int, in which cases lead to write failures. Read the cell first to determine actual size and only write the number of bytes the cell can hold. Fixes: 7a78a7f7695b ("power: reset: nvmem-reboot-mode: use NVMEM as reboot mode write interface") Signed-off-by: Alexander Koskovich <akoskovich@pm.me> Link: https://patch.msgid.link/20251214191529.2470580-1-akoskovich@pm.me Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/power/reset/nvmem-reboot-mode.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c
index 41530b70cfc4..d260715fccf6 100644
--- a/drivers/power/reset/nvmem-reboot-mode.c
+++ b/drivers/power/reset/nvmem-reboot-mode.c
@@ -10,6 +10,7 @@
#include <linux/nvmem-consumer.h>
#include <linux/platform_device.h>
#include <linux/reboot-mode.h>
+#include <linux/slab.h>
struct nvmem_reboot_mode {
struct reboot_mode_driver reboot;
@@ -19,12 +20,22 @@ struct nvmem_reboot_mode {
static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot,
unsigned int magic)
{
- int ret;
struct nvmem_reboot_mode *nvmem_rbm;
+ size_t buf_len;
+ void *buf;
+ int ret;
nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot);
- ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic));
+ buf = nvmem_cell_read(nvmem_rbm->cell, &buf_len);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+ kfree(buf);
+
+ if (buf_len > sizeof(magic))
+ return -EINVAL;
+
+ ret = nvmem_cell_write(nvmem_rbm->cell, &magic, buf_len);
if (ret < 0)
dev_err(reboot->dev, "update reboot mode bits failed\n");