[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251209100217.167581-1-buaajxlj@163.com>
Date: Tue, 9 Dec 2025 18:02:17 +0800
From: Liang Jie <buaajxlj@....com>
To: Sean Wang <sean.wang@...nel.org>,
Linus Walleij <linus.walleij@...aro.org>,
Matthias Brugger <matthias.bgg@...il.com>,
AngeloGioacchino Del Regno <angelogioacchino.delregno@...labora.com>,
linux-mediatek@...ts.infradead.org (moderated list:PIN CONTROLLER - MEDIATEK),
linux-gpio@...r.kernel.org (open list:PIN CONTROL SUBSYSTEM),
linux-kernel@...r.kernel.org (open list:ARM/Mediatek SoC support),
linux-arm-kernel@...ts.infradead.org (moderated list:ARM/Mediatek SoC support)
Cc: liangjie@...iang.com,
fanggeng <fanggeng@...iang.com>
Subject: [PATCH] pinctrl: mediatek: make devm allocations safer and clearer in mtk_eint_do_init()
From: Liang Jie <liangjie@...iang.com>
mtk_eint_do_init() allocates several pointer arrays which are then
populated in a per-instance loop and freed on error. The arrays are
currently allocated with devm_kmalloc(), so their entries are left
uninitialised until the per-instance allocations succeed.
On a failure in the middle of the loop, the error path iterates over
the full nbase range and calls devm_kfree() on each element. For
indices which were never initialised, the corresponding array entries
contain stack garbage. If any of those happen to be non-zero,
devm_kfree() will pass them to devres_destroy(), which will WARN
because there is no matching devm_kmalloc() resource for such bogus
pointers.
Improve the robustness and readability by:
- Using devm_kcalloc() for the pointer arrays so that all entries
start as NULL, ensuring that only genuinely initialised elements
may be freed and preventing spurious WARN_ON()s in the error path.
- Switching the allocations to sizeof(*ptr) / sizeof(**ptr) forms,
avoiding hard-coded element types and making the code more resilient
to future type changes.
- Dropping the redundant NULL checks before devm_kfree(), as
devm_kfree() safely handles NULL pointers.
The functional behaviour in the successful initialisation path remains
unchanged, while the error handling becomes simpler and less
error-prone.
Reviewed-by: fanggeng <fanggeng@...iang.com>
Signed-off-by: Liang Jie <liangjie@...iang.com>
---
drivers/pinctrl/mediatek/mtk-eint.c | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
index 9f175c73613f..2ea0902b4f66 100644
--- a/drivers/pinctrl/mediatek/mtk-eint.c
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -539,24 +539,32 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
}
}
- eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL);
+ eint->pin_list = devm_kcalloc(eint->dev, eint->nbase,
+ sizeof(*eint->pin_list), GFP_KERNEL);
if (!eint->pin_list)
goto err_pin_list;
- eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
+ eint->wake_mask = devm_kcalloc(eint->dev, eint->nbase,
+ sizeof(*eint->wake_mask), GFP_KERNEL);
if (!eint->wake_mask)
goto err_wake_mask;
- eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL);
+ eint->cur_mask = devm_kcalloc(eint->dev, eint->nbase,
+ sizeof(*eint->cur_mask), GFP_KERNEL);
if (!eint->cur_mask)
goto err_cur_mask;
for (i = 0; i < eint->nbase; i++) {
- eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16),
+ eint->pin_list[i] = devm_kzalloc(eint->dev,
+ eint->base_pin_num[i] * sizeof(**eint->pin_list),
GFP_KERNEL);
port = DIV_ROUND_UP(eint->base_pin_num[i], 32);
- eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
- eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL);
+ eint->wake_mask[i] = devm_kzalloc(eint->dev,
+ port * sizeof(**eint->wake_mask),
+ GFP_KERNEL);
+ eint->cur_mask[i] = devm_kzalloc(eint->dev,
+ port * sizeof(**eint->cur_mask),
+ GFP_KERNEL);
if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i])
goto err_eint;
}
@@ -592,12 +600,9 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin)
err_eint:
for (i = 0; i < eint->nbase; i++) {
- if (eint->cur_mask[i])
- devm_kfree(eint->dev, eint->cur_mask[i]);
- if (eint->wake_mask[i])
- devm_kfree(eint->dev, eint->wake_mask[i]);
- if (eint->pin_list[i])
- devm_kfree(eint->dev, eint->pin_list[i]);
+ devm_kfree(eint->dev, eint->cur_mask[i]);
+ devm_kfree(eint->dev, eint->wake_mask[i]);
+ devm_kfree(eint->dev, eint->pin_list[i]);
}
devm_kfree(eint->dev, eint->cur_mask);
err_cur_mask:
--
2.25.1
Powered by blists - more mailing lists