]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/msm/dp: Avoid division by zero in msm_dp_ctrl_config_msa()
authorNathan Chancellor <nathan@kernel.org>
Wed, 14 Jan 2026 00:00:31 +0000 (17:00 -0700)
committerDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Wed, 21 Jan 2026 00:12:34 +0000 (02:12 +0200)
An (admittedly problematic) optimization change in LLVM 20 [1] turns
known division by zero into the equivalent of __builtin_unreachable(),
which invokes undefined behavior if it is encountered in a control flow
graph, destroying code generation. When compile testing for x86_64,
objtool flags an instance of this optimization triggering in
msm_dp_ctrl_config_msa(), inlined into msm_dp_ctrl_on_stream():

  drivers/gpu/drm/msm/msm.o: warning: objtool: msm_dp_ctrl_on_stream(): unexpected end of section .text.msm_dp_ctrl_on_stream

The zero division happens if the else branch in the first if statement
in msm_dp_ctrl_config_msa() is taken because pixel_div is initialized to
zero and it is not possible for LLVM to eliminate the else branch since
rate is still not known after inlining into msm_dp_ctrl_on_stream().

Transform the if statements into a switch statement with a default case
with the existing error print and an early return to avoid the invalid
division. Add a comment to note this helps the compiler, even though the
case is known to be unreachable. With this, pixel_dev's default zero
initialization can be dropped, as it is dead with this change.

Fixes: c943b4948b58 ("drm/msm/dp: add displayPort driver support")
Link: https://github.com/llvm/llvm-project/commit/37932643abab699e8bb1def08b7eb4eae7ff1448
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202601081959.9UVJEOfP-lkp@intel.com/
Suggested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/698355/
Link: https://lore.kernel.org/r/20260113-drm-msm-dp_ctrl-avoid-zero-div-v2-1-f1aa67bf6e8e@kernel.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
drivers/gpu/drm/msm/dp/dp_ctrl.c

index aa2303d0e1483bb50dbb18060d08be3dd0e295fb..5fc261191cb789dbfdd5cc51b0d62bb592ddfb06 100644 (file)
@@ -2409,20 +2409,32 @@ static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl,
                               bool is_ycbcr_420)
 {
        u32 pixel_m, pixel_n;
-       u32 mvid, nvid, pixel_div = 0, dispcc_input_rate;
+       u32 mvid, nvid, pixel_div, dispcc_input_rate;
        u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE;
        u32 const link_rate_hbr2 = 540000;
        u32 const link_rate_hbr3 = 810000;
        unsigned long den, num;
 
-       if (rate == link_rate_hbr3)
+       switch (rate) {
+       case link_rate_hbr3:
                pixel_div = 6;
-       else if (rate == 162000 || rate == 270000)
-               pixel_div = 2;
-       else if (rate == link_rate_hbr2)
+               break;
+       case link_rate_hbr2:
                pixel_div = 4;
-       else
+               break;
+       case 162000:
+       case 270000:
+               pixel_div = 2;
+               break;
+       default:
+               /*
+                * This cannot be reached but the compiler is not able to know
+                * that statically so return early to avoid a possibly invalid
+                * division.
+                */
                DRM_ERROR("Invalid pixel mux divider\n");
+               return;
+       }
 
        dispcc_input_rate = (rate * 10) / pixel_div;