Skip to content

Commit f185076

Browse files
nathanchancelumag
authored andcommitted
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: c943b49 ("drm/msm/dp: add displayPort driver support") Link: llvm/llvm-project@3793264 [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>
1 parent 42f62cd commit f185076

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

drivers/gpu/drm/msm/dp/dp_ctrl.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,20 +2409,32 @@ static void msm_dp_ctrl_config_msa(struct msm_dp_ctrl_private *ctrl,
24092409
bool is_ycbcr_420)
24102410
{
24112411
u32 pixel_m, pixel_n;
2412-
u32 mvid, nvid, pixel_div = 0, dispcc_input_rate;
2412+
u32 mvid, nvid, pixel_div, dispcc_input_rate;
24132413
u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE;
24142414
u32 const link_rate_hbr2 = 540000;
24152415
u32 const link_rate_hbr3 = 810000;
24162416
unsigned long den, num;
24172417

2418-
if (rate == link_rate_hbr3)
2418+
switch (rate) {
2419+
case link_rate_hbr3:
24192420
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:
24232423
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+
*/
24252435
DRM_ERROR("Invalid pixel mux divider\n");
2436+
return;
2437+
}
24262438

24272439
dispcc_input_rate = (rate * 10) / pixel_div;
24282440

0 commit comments

Comments
 (0)