drm/i915: Fix buffer overflow in dsi_calc_mnp()
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 2 Jul 2016 14:36:04 +0000 (15:36 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 2 Jul 2016 18:20:06 +0000 (19:20 +0100)
smatch complain:

drivers/gpu/drm/i915/intel_dsi_pll.c:101 dsi_calc_mnp() error: buffer
overflow 'lfsr_converts' 39 <= 4294967234

and looks justified in doing so.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1467470166-31717-7-git-send-email-chris@chris-wilson.co.uk
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
drivers/gpu/drm/i915/intel_dsi_pll.c

index 4f9930bc89e536f1c580efbddd033f568404b8f9..1fcddeb3303dd0c6ff6f2cbc3f5deac2bce138a9 100644 (file)
@@ -55,12 +55,10 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
                        struct intel_crtc_state *config,
                        int target_dsi_clk)
 {
-       unsigned int calc_m = 0, calc_p = 0;
        unsigned int m_min, m_max, p_min = 2, p_max = 6;
        unsigned int m, n, p;
-       int ref_clk;
-       int delta = target_dsi_clk;
-       u32 m_seed;
+       unsigned int calc_m, calc_p;
+       int delta, ref_clk;
 
        /* target_dsi_clk is expected in kHz */
        if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) {
@@ -80,6 +78,10 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
                m_max = 92;
        }
 
+       calc_p = p_min;
+       calc_m = m_min;
+       delta = abs(target_dsi_clk - (m_min * ref_clk) / (p_min * n));
+
        for (m = m_min; m <= m_max && delta; m++) {
                for (p = p_min; p <= p_max && delta; p++) {
                        /*
@@ -97,11 +99,10 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv,
        }
 
        /* register has log2(N1), this works fine for powers of two */
-       n = ffs(n) - 1;
-       m_seed = lfsr_converts[calc_m - 62];
        config->dsi_pll.ctrl = 1 << (DSI_PLL_P1_POST_DIV_SHIFT + calc_p - 2);
-       config->dsi_pll.div = n << DSI_PLL_N1_DIV_SHIFT |
-               m_seed << DSI_PLL_M1_DIV_SHIFT;
+       config->dsi_pll.div =
+               (ffs(n) - 1) << DSI_PLL_N1_DIV_SHIFT |
+               (u32)lfsr_converts[calc_m - 62] << DSI_PLL_M1_DIV_SHIFT;
 
        return 0;
 }