diff options
| author | Nicolas Frattaroli <nicolas.frattaroli@collabora.com> | 2025-11-24 12:07:02 +0100 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-02-26 15:01:23 -0800 |
| commit | b676494fc197e628cd5e4273eaae8483c9ae4b33 (patch) | |
| tree | 3e258d752454b420690a999ce2c52791f1bc9eed /drivers/interconnect | |
| parent | 71882771bb1c1cc8b5882e06316084bcfe6ed4b0 (diff) | |
interconnect: mediatek: Aggregate bandwidth with saturating add
[ Upstream commit 6ffd02b82243d9907b5f5d2c7a2fc6a62669eece ]
By using a regular non-overflow-checking add, the MediaTek icc-emi
driver will happy wrap at U32_MAX + 1 to 0. As it's common for the
interconnect core to fill in INT_MAX values, this is not a hypothetical
situation, but something that actually happens in regular use. This
would be pretty disasterous if anything used this driver.
Replace the addition with an overflow-checked addition from overflow.h,
and saturate to U32_MAX if an overflow is detected.
Fixes: b45293799f75 ("interconnect: mediatek: Add MediaTek MT8183/8195 EMI Interconnect driver")
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Link: https://lore.kernel.org/r/20251124-mt8196-dvfsrc-v2-13-d9c1334db9f3@collabora.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/interconnect')
| -rw-r--r-- | drivers/interconnect/mediatek/icc-emi.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/interconnect/mediatek/icc-emi.c b/drivers/interconnect/mediatek/icc-emi.c index 182aa2b0623a..dfa3a9cd9399 100644 --- a/drivers/interconnect/mediatek/icc-emi.c +++ b/drivers/interconnect/mediatek/icc-emi.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/overflow.h> #include <linux/platform_device.h> #include <linux/soc/mediatek/dvfsrc.h> @@ -22,7 +23,9 @@ static int mtk_emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, { struct mtk_icc_node *in = node->data; - *agg_avg += avg_bw; + if (check_add_overflow(*agg_avg, avg_bw, agg_avg)) + *agg_avg = U32_MAX; + *agg_peak = max_t(u32, *agg_peak, peak_bw); in->sum_avg = *agg_avg; |
