summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@bootlin.com>2018-10-18 12:02:50 +0200
committerMaxime Ripard <maxime.ripard@bootlin.com>2018-10-19 11:50:25 +0200
commite84cb605e02f1b3d0aee8d7157419cd8aaa06038 (patch)
treea479bb12e9d290e8f14da3402ad48fcabf9cf6d0
parent4364bcb2cd21d042bde4776448417ddffbc54045 (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.c12
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);