diff options
author | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-10-18 12:02:50 +0200 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@bootlin.com> | 2018-10-19 11:50:25 +0200 |
commit | e84cb605e02f1b3d0aee8d7157419cd8aaa06038 (patch) | |
tree | a479bb12e9d290e8f14da3402ad48fcabf9cf6d0 | |
parent | 4364bcb2cd21d042bde4776448417ddffbc54045 (diff) |
drm/sun4i: Fix an ulong overflow in the dotclock driverdrm-misc-fixes-2018-10-19
The calculated ideal rate can easily overflow an unsigned long, thus
making the best div selection buggy as soon as no ideal match is found
before the overflow occurs.
Fixes: 4731a72df273 ("drm/sun4i: request exact rates to our parents")
Cc: <stable@vger.kernel.org>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181018100250.12565-1-boris.brezillon@bootlin.com
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_dotclock.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_dotclock.c b/drivers/gpu/drm/sun4i/sun4i_dotclock.c index e36004fbe453..2a15f2f9271e 100644 --- a/drivers/gpu/drm/sun4i/sun4i_dotclock.c +++ b/drivers/gpu/drm/sun4i/sun4i_dotclock.c @@ -81,9 +81,19 @@ static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate, int i; for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) { - unsigned long ideal = rate * i; + u64 ideal = (u64)rate * i; unsigned long rounded; + /* + * ideal has overflowed the max value that can be stored in an + * unsigned long, and every clk operation we might do on a + * truncated u64 value will give us incorrect results. + * Let's just stop there since bigger dividers will result in + * the same overflow issue. + */ + if (ideal > ULONG_MAX) + goto out; + rounded = clk_hw_round_rate(clk_hw_get_parent(hw), ideal); |