| From e89b0a9b8be7bd14a39067e9a229ad855b47fa26 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 18 Nov 2020 08:50:09 -0600 |
| Subject: regulator: ti-abb: Fix array out of bound read access on the first |
| transition |
| |
| From: Nishanth Menon <nm@ti.com> |
| |
| [ Upstream commit 2ba546ebe0ce2af47833d8912ced9b4a579f13cb ] |
| |
| At the start of driver initialization, we do not know what bias |
| setting the bootloader has configured the system for and we only know |
| for certain the very first time we do a transition. |
| |
| However, since the initial value of the comparison index is -EINVAL, |
| this negative value results in an array out of bound access on the |
| very first transition. |
| |
| Since we don't know what the setting is, we just set the bias |
| configuration as there is nothing to compare against. This prevents |
| the array out of bound access. |
| |
| NOTE: Even though we could use a more relaxed check of "< 0" the only |
| valid values(ignoring cosmic ray induced bitflips) are -EINVAL, 0+. |
| |
| Fixes: 40b1936efebd ("regulator: Introduce TI Adaptive Body Bias(ABB) on-chip LDO driver") |
| Link: https://lore.kernel.org/linux-mm/CA+G9fYuk4imvhyCN7D7T6PMDH6oNp6HDCRiTUKMQ6QXXjBa4ag@mail.gmail.com/ |
| Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org> |
| Reviewed-by: Arnd Bergmann <arnd@arndb.de> |
| Signed-off-by: Nishanth Menon <nm@ti.com> |
| Link: https://lore.kernel.org/r/20201118145009.10492-1-nm@ti.com |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/regulator/ti-abb-regulator.c | 12 +++++++++++- |
| 1 file changed, 11 insertions(+), 1 deletion(-) |
| |
| diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c |
| index 89b9314d64c9d..016330f909c09 100644 |
| --- a/drivers/regulator/ti-abb-regulator.c |
| +++ b/drivers/regulator/ti-abb-regulator.c |
| @@ -342,8 +342,17 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) |
| return ret; |
| } |
| |
| - /* If data is exactly the same, then just update index, no change */ |
| info = &abb->info[sel]; |
| + /* |
| + * When Linux kernel is starting up, we are'nt sure of the |
| + * Bias configuration that bootloader has configured. |
| + * So, we get to know the actual setting the first time |
| + * we are asked to transition. |
| + */ |
| + if (abb->current_info_idx == -EINVAL) |
| + goto just_set_abb; |
| + |
| + /* If data is exactly the same, then just update index, no change */ |
| oinfo = &abb->info[abb->current_info_idx]; |
| if (!memcmp(info, oinfo, sizeof(*info))) { |
| dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n", __func__, |
| @@ -351,6 +360,7 @@ static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned sel) |
| goto out; |
| } |
| |
| +just_set_abb: |
| ret = ti_abb_set_opp(rdev, abb, info); |
| |
| out: |
| -- |
| 2.27.0 |
| |