]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Fix NULL pointer assumptions in dcn42_init_hw()
authorSrinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Tue, 17 Mar 2026 03:08:38 +0000 (08:38 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 23 Mar 2026 18:18:27 +0000 (14:18 -0400)
dcn42_init_hw() calls update_bw_bounding_box() when FAMS2 is disabled or
when the dchub reference clock changes. However the existing condition
mixes the callback pointer check with only one side of the || expression:

  ((!fams2_enable && update_bw_bounding_box) || freq_changed)

This allows the block to be entered through the freq_changed path even
when update_bw_bounding_box() is NULL. The function is then called
unconditionally inside the block, which can lead to a NULL pointer
dereference.

Additionally, the code dereferences dc->clk_mgr->bw_params without
verifying that dc->clk_mgr and bw_params are valid.

Restructure the condition so that the update trigger remains the same
(FAMS2 disabled or dchub ref clock changed), but guard the call with
explicit checks for:

  - update_bw_bounding_box callback
  - dc->clk_mgr
  - dc->clk_mgr->bw_params

Also introduce a helper boolean (dchub_ref_freq_changed) to improve
readability of the clock-change condition.

This fixes Smatch warnings about inconsistent NULL assumptions in
dcn42_init_hw().

drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn42/dcn42_hwseq.c:264 dcn42_init_hw() error: we previously assumed 'dc->clk_mgr' could be null (see line 253)
drivers/gpu/drm/amd/amdgpu/../display/dc/hwss/dcn42/dcn42_hwseq.c:278 dcn42_init_hw() error: we previously assumed 'dc->res_pool->funcs->update_bw_bounding_box' could be null (see line 274)

Cc: Roman Li <roman.li@amd.com>
Cc: Alex Hung <alex.hung@amd.com>
Cc: Jerry Zuo <jerry.zuo@amd.com>
Cc: Sun peng Li <sunpeng.li@amd.com>
Cc: Tom Chung <chiahsuan.chung@amd.com>
Cc: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/hwss/dcn42/dcn42_hwseq.c

index 7bf94eae30a6fd403eb3bac06a153561e2e76e76..7f9c121c00e67bf1a6943e5bc75b84e79b286668 100644 (file)
@@ -69,6 +69,7 @@ void dcn42_init_hw(struct dc *dc)
        int edp_num;
        uint32_t backlight = MAX_BACKLIGHT_LEVEL;
        uint32_t user_level = MAX_BACKLIGHT_LEVEL;
+       bool dchub_ref_freq_changed;
        int current_dchub_ref_freq = 0;
 
        if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) {
@@ -261,8 +262,12 @@ void dcn42_init_hw(struct dc *dc)
        if (dc->res_pool->hubbub->funcs->init_crb)
                dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);
 
-       if (dc->res_pool->hubbub->funcs->set_request_limit && dc->config.sdpif_request_limit_words_per_umc > 0)
-               dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub, dc->clk_mgr->bw_params->num_channels, dc->config.sdpif_request_limit_words_per_umc);
+       if (dc->res_pool->hubbub->funcs->set_request_limit &&
+           dc->clk_mgr && dc->clk_mgr->bw_params &&
+           dc->config.sdpif_request_limit_words_per_umc > 0)
+               dc->res_pool->hubbub->funcs->set_request_limit(dc->res_pool->hubbub,
+                                                              dc->clk_mgr->bw_params->num_channels,
+                                                              dc->config.sdpif_request_limit_words_per_umc);
 
        // Get DMCUB capabilities
        if (dc->ctx->dmub_srv) {
@@ -270,13 +275,18 @@ void dcn42_init_hw(struct dc *dc)
                dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;
                dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver > 0;
                dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;
+
+               /* sw and fw FAMS versions must match for support */
                dc->debug.fams2_config.bits.enable &=
-                               dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; // sw & fw fams versions must match for support
-               if ((!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box)
-                       || res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq) {
+                       dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver;
+               dchub_ref_freq_changed =
+                       res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000 != current_dchub_ref_freq;
+
+               if ((!dc->debug.fams2_config.bits.enable || dchub_ref_freq_changed) &&
+                   dc->res_pool->funcs->update_bw_bounding_box &&
+                   dc->clk_mgr && dc->clk_mgr->bw_params) {
                        /* update bounding box if FAMS2 disabled, or if dchub clk has changed */
-                       if (dc->clk_mgr)
-                               dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
+                       dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params);
                }
        }
        if (dc->res_pool->pg_cntl) {