Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/msm/dp: Avoid division by zero in msm_dp_ctrl_config_msa()

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 [1]
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>

authored by

Nathan Chancellor and committed by
Dmitry Baryshkov
f185076d 42f62cd7

+18 -6
+18 -6
drivers/gpu/drm/msm/dp/dp_ctrl.c
··· 2409 2409 bool is_ycbcr_420) 2410 2410 { 2411 2411 u32 pixel_m, pixel_n; 2412 - u32 mvid, nvid, pixel_div = 0, dispcc_input_rate; 2412 + u32 mvid, nvid, pixel_div, dispcc_input_rate; 2413 2413 u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE; 2414 2414 u32 const link_rate_hbr2 = 540000; 2415 2415 u32 const link_rate_hbr3 = 810000; 2416 2416 unsigned long den, num; 2417 2417 2418 - if (rate == link_rate_hbr3) 2418 + switch (rate) { 2419 + case link_rate_hbr3: 2419 2420 pixel_div = 6; 2420 - else if (rate == 162000 || rate == 270000) 2421 - pixel_div = 2; 2422 - else if (rate == link_rate_hbr2) 2421 + break; 2422 + case link_rate_hbr2: 2423 2423 pixel_div = 4; 2424 - else 2424 + break; 2425 + case 162000: 2426 + case 270000: 2427 + pixel_div = 2; 2428 + break; 2429 + default: 2430 + /* 2431 + * This cannot be reached but the compiler is not able to know 2432 + * that statically so return early to avoid a possibly invalid 2433 + * division. 2434 + */ 2425 2435 DRM_ERROR("Invalid pixel mux divider\n"); 2436 + return; 2437 + } 2426 2438 2427 2439 dispcc_input_rate = (rate * 10) / pixel_div; 2428 2440