[PATCH 22/36] drm/amd/display: Check dc_stream_state before it is used

Hamza Mahfooz hamza.mahfooz at amd.com
Tue Jun 11 16:51:25 UTC 2024


From: Alex Hung <alex.hung at amd.com>

dc_state_get_stream_status dc_state_get_paired_subvp_stream and other
functions can return null, and therefore null must be checked before
status can be used.

This fixes 21 NULL_RETURNS issues reported by Coverity.

Reviewed-by: Harry Wentland <harry.wentland at amd.com>
Acked-by: Hamza Mahfooz <hamza.mahfooz at amd.com>
Signed-off-by: Alex Hung <alex.hung at amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 17 +++++++++----
 .../gpu/drm/amd/display/dc/core/dc_state.c    | 24 ++++++++++++-------
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  | 20 ++++++++++++++--
 .../drm/amd/display/dc/dml/dcn32/dcn32_fpu.c  |  8 +++----
 .../amd/display/dc/dml2/dml21/dml21_utils.c   | 12 +++++++++-
 .../display/dc/dml2/dml2_dc_resource_mgmt.c   |  6 +++--
 .../amd/display/dc/hwss/dcn20/dcn20_hwseq.c   |  9 ++++---
 .../dc/resource/dcn32/dcn32_resource.c        |  2 ++
 8 files changed, 74 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 25a498f65c1c..fce1c3e03094 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1233,11 +1233,14 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
 			 */
 			if (is_phantom) {
 				if (tg->funcs->enable_crtc) {
-					int main_pipe_width, main_pipe_height;
+					int main_pipe_width = 0, main_pipe_height = 0;
 					struct dc_stream_state *old_paired_stream = dc_state_get_paired_subvp_stream(dc->current_state, old_stream);
 
-					main_pipe_width = old_paired_stream->dst.width;
-					main_pipe_height = old_paired_stream->dst.height;
+					if (old_paired_stream) {
+						main_pipe_width = old_paired_stream->dst.width;
+						main_pipe_height = old_paired_stream->dst.height;
+					}
+
 					if (dc->hwss.blank_phantom)
 						dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
 					tg->funcs->enable_crtc(tg);
@@ -1628,6 +1631,9 @@ static void program_timing_sync(
 		for (k = 0; k < group_size; k++) {
 			struct dc_stream_status *status = dc_state_get_stream_status(ctx, pipe_set[k]->stream);
 
+			if (!status)
+				continue;
+
 			status->timing_sync_info.group_id = num_group;
 			status->timing_sync_info.group_size = group_size;
 			if (k == 0)
@@ -2225,6 +2231,9 @@ enum dc_status dc_commit_streams(struct dc *dc, struct dc_commit_streams_params
 			if (dc_is_embedded_signal(params->streams[i]->signal)) {
 				struct dc_stream_status *status = dc_state_get_stream_status(context, params->streams[i]);
 
+				if (!status)
+					continue;
+
 				if (dc->hwss.is_abm_supported)
 					status->is_abm_supported = dc->hwss.is_abm_supported(dc, context, params->streams[i]);
 				else
@@ -4023,7 +4032,7 @@ static void commit_planes_for_stream(struct dc *dc,
 			stream_status =
 				stream_get_status(context, pipe_ctx->stream);
 
-			if (dc->hwss.apply_ctx_for_surface)
+			if (dc->hwss.apply_ctx_for_surface && stream_status)
 				dc->hwss.apply_ctx_for_surface(
 					dc, pipe_ctx->stream, stream_status->plane_count, context);
 		}
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
index c75dcdc20428..e990346e51f6 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -794,11 +794,16 @@ enum dc_status dc_state_add_phantom_stream(const struct dc *dc,
 
 	/* setup subvp meta */
 	main_stream_status = dc_state_get_stream_status(state, main_stream);
+	if (main_stream_status) {
+		main_stream_status->mall_stream_config.type = SUBVP_MAIN;
+		main_stream_status->mall_stream_config.paired_stream = phantom_stream;
+	}
+
 	phantom_stream_status = dc_state_get_stream_status(state, phantom_stream);
-	phantom_stream_status->mall_stream_config.type = SUBVP_PHANTOM;
-	phantom_stream_status->mall_stream_config.paired_stream = main_stream;
-	main_stream_status->mall_stream_config.type = SUBVP_MAIN;
-	main_stream_status->mall_stream_config.paired_stream = phantom_stream;
+	if (phantom_stream_status) {
+		phantom_stream_status->mall_stream_config.type = SUBVP_PHANTOM;
+		phantom_stream_status->mall_stream_config.paired_stream = main_stream;
+	}
 
 	return res;
 }
@@ -807,14 +812,17 @@ enum dc_status dc_state_remove_phantom_stream(const struct dc *dc,
 		struct dc_state *state,
 		struct dc_stream_state *phantom_stream)
 {
-	struct dc_stream_status *main_stream_status;
+	struct dc_stream_status *main_stream_status = NULL;
 	struct dc_stream_status *phantom_stream_status;
 
 	/* reset subvp meta */
 	phantom_stream_status = dc_state_get_stream_status(state, phantom_stream);
-	main_stream_status = dc_state_get_stream_status(state, phantom_stream_status->mall_stream_config.paired_stream);
-	phantom_stream_status->mall_stream_config.type = SUBVP_NONE;
-	phantom_stream_status->mall_stream_config.paired_stream = NULL;
+	if (phantom_stream_status) {
+		main_stream_status = dc_state_get_stream_status(state, phantom_stream_status->mall_stream_config.paired_stream);
+		phantom_stream_status->mall_stream_config.type = SUBVP_NONE;
+		phantom_stream_status->mall_stream_config.paired_stream = NULL;
+	}
+
 	if (main_stream_status) {
 		main_stream_status->mall_stream_config.type = SUBVP_NONE;
 		main_stream_status->mall_stream_config.paired_stream = NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index 6ff87b023081..b2051c4dd7b6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -562,7 +562,7 @@ static void populate_subvp_cmd_drr_info(struct dc *dc,
 {
 	struct dc_stream_state *phantom_stream = dc_state_get_paired_subvp_stream(context, subvp_pipe->stream);
 	struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing;
-	struct dc_crtc_timing *phantom_timing = &phantom_stream->timing;
+	struct dc_crtc_timing *phantom_timing;
 	struct dc_crtc_timing *drr_timing = &vblank_pipe->stream->timing;
 	uint16_t drr_frame_us = 0;
 	uint16_t min_drr_supported_us = 0;
@@ -576,6 +576,11 @@ static void populate_subvp_cmd_drr_info(struct dc *dc,
 	uint16_t min_vtotal_supported = 0;
 	uint16_t max_vtotal_supported = 0;
 
+	if (!phantom_stream)
+		return;
+
+	phantom_timing = &phantom_stream->timing;
+
 	pipe_data->pipe_config.vblank_data.drr_info.drr_in_use = true;
 	pipe_data->pipe_config.vblank_data.drr_info.use_ramping = false; // for now don't use ramping
 	pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms = 4; // hardcode 4ms DRR window for now
@@ -699,7 +704,13 @@ static void update_subvp_prefetch_end_to_mall_start(struct dc *dc,
 	struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data = NULL;
 
 	phantom_stream0 = dc_state_get_paired_subvp_stream(context, subvp_pipes[0]->stream);
+	if (!phantom_stream0)
+		return;
+
 	phantom_stream1 = dc_state_get_paired_subvp_stream(context, subvp_pipes[1]->stream);
+	if (!phantom_stream1)
+		return;
+
 	phantom_timing0 = &phantom_stream0->timing;
 	phantom_timing1 = &phantom_stream1->timing;
 
@@ -754,9 +765,14 @@ static void populate_subvp_cmd_pipe_info(struct dc *dc,
 			&cmd->fw_assisted_mclk_switch_v2.config_data.pipe_data[cmd_pipe_index];
 	struct dc_stream_state *phantom_stream = dc_state_get_paired_subvp_stream(context, subvp_pipe->stream);
 	struct dc_crtc_timing *main_timing = &subvp_pipe->stream->timing;
-	struct dc_crtc_timing *phantom_timing = &phantom_stream->timing;
+	struct dc_crtc_timing *phantom_timing;
 	uint32_t out_num_stream, out_den_stream, out_num_plane, out_den_plane, out_num, out_den;
 
+	if (!phantom_stream)
+		return;
+
+	phantom_timing = &phantom_stream->timing;
+
 	pipe_data->mode = SUBVP;
 	pipe_data->pipe_config.subvp_data.pix_clk_100hz = subvp_pipe->stream->timing.pix_clk_100hz;
 	pipe_data->pipe_config.subvp_data.htotal = subvp_pipe->stream->timing.h_total;
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 5ef10e2b9443..a63b5dcba3f5 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -738,9 +738,9 @@ static bool subvp_subvp_schedulable(struct dc *dc, struct dc_state *context)
 		/* Loop to calculate the maximum microschedule time between the two SubVP pipes,
 		 * and also to store the two main SubVP pipe pointers in subvp_pipes[2].
 		 */
-		if (pipe->stream && pipe->plane_state && !pipe->top_pipe &&
+		phantom = dc_state_get_paired_subvp_stream(context, pipe->stream);
+		if (phantom && pipe->stream && pipe->plane_state && !pipe->top_pipe &&
 			dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_MAIN) {
-			phantom = dc_state_get_paired_subvp_stream(context, pipe->stream);
 			microschedule_lines = (phantom->timing.v_total - phantom->timing.v_front_porch) +
 					phantom->timing.v_addressable;
 
@@ -845,8 +845,8 @@ static bool subvp_drr_schedulable(struct dc *dc, struct dc_state *context)
 		}
 	}
 
-	if (subvp_found && drr_found) {
-		phantom_stream = dc_state_get_paired_subvp_stream(context, pipe->stream);
+	phantom_stream = dc_state_get_paired_subvp_stream(context, pipe->stream);
+	if (phantom_stream && subvp_found && drr_found) {
 		main_timing = &pipe->stream->timing;
 		phantom_timing = &phantom_stream->timing;
 		drr_timing = &drr_pipe->stream->timing;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
index b97d9abfdbc6..87c7b13391bc 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_utils.c
@@ -108,6 +108,8 @@ int dml21_find_dc_pipes_for_plane(const struct dc *in_dc,
 
 	dc_main_stream = dml_ctx->config.callbacks.get_stream_from_id(context, main_stream_id);
 	dc_main_stream_status = dml_ctx->config.callbacks.get_stream_status(context, dc_main_stream);
+	if (!dc_main_stream_status)
+		return num_pipes;
 
 	/* find main plane based on id */
 	dc_plane_index = dml21_get_dc_plane_idx_from_plane_id(dml_ctx->v21.dml_to_dc_pipe_mapping.dml_pipe_idx_to_plane_id[dml_plane_idx]);
@@ -325,6 +327,8 @@ static struct dc_stream_state *dml21_add_phantom_stream(struct dml2_context *dml
 	struct dml2_stream_parameters *phantom_stream_descriptor = &stream_programming->phantom_stream.descriptor;
 
 	phantom_stream = dml_ctx->config.svp_pstate.callbacks.create_phantom_stream(dc, context, main_stream);
+	if (!phantom_stream)
+		return NULL;
 
 	/* copy details of phantom stream from main */
 	memcpy(&phantom_stream->timing, &main_stream->timing, sizeof(phantom_stream->timing));
@@ -411,7 +415,7 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c
 
 			main_stream_status = dml_ctx->config.callbacks.get_stream_status(context, main_stream);
 
-			if (main_stream_status->plane_count == 0)
+			if (!main_stream_status || main_stream_status->plane_count == 0)
 				continue;
 
 			/* create phantom stream for subvp enabled stream */
@@ -421,6 +425,9 @@ void dml21_handle_phantom_streams_planes(const struct dc *dc, struct dc_state *c
 					main_stream,
 					&dml_ctx->v21.mode_programming.programming->stream_programming[dml_stream_index]);
 
+			if (!phantom_stream)
+				continue;
+
 			/* iterate through DML planes associated with this stream */
 			for (dml_plane_index = 0; dml_plane_index < dml_ctx->v21.mode_programming.programming->display_config.num_planes; dml_plane_index++) {
 				if (dml_ctx->v21.mode_programming.programming->plane_programming[dml_plane_index].plane_descriptor->stream_index == dml_stream_index) {
@@ -509,6 +516,9 @@ void dml21_build_fams2_programming(const struct dc *dc,
 			break;
 		case FAMS2_STREAM_TYPE_SUBVP:
 			phantom_stream = dml_ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(context, stream);
+			if (!phantom_stream)
+				break;
+
 			phantom_status = dml_ctx->config.callbacks.get_stream_status(context, phantom_stream);
 
 			/* phantom status should always be present */
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
index 23ffecfd70eb..486b222083e0 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -874,13 +874,14 @@ static unsigned int get_target_odm_factor(
 		default:
 			break;
 		}
-	}
-	else if (ctx->architecture == dml2_architecture_21) {
+	} else if (ctx->architecture == dml2_architecture_21) {
 		if (ctx->config.svp_pstate.callbacks.get_stream_subvp_type(state, stream) == SUBVP_PHANTOM) {
 			struct dc_stream_state *main_stream;
 
 			/* get stream id of main stream */
 			main_stream = ctx->config.svp_pstate.callbacks.get_paired_subvp_stream(state, stream);
+			if (!main_stream)
+				goto failed;
 
 			/* get cfg idx for associated main stream */
 			cfg_idx = find_disp_cfg_idx_by_stream_id(
@@ -893,6 +894,7 @@ static unsigned int get_target_odm_factor(
 		return ctx->v21.mode_programming.programming->stream_programming[cfg_idx].num_odms_required;
 	}
 
+failed:
 	ASSERT(false);
 	return 1;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 09376c367c14..1b71cb365aa9 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -2051,11 +2051,14 @@ void dcn20_program_front_end_for_ctx(
 
 			if (tg->funcs->enable_crtc) {
 				if (dc->hwss.blank_phantom) {
-					int main_pipe_width, main_pipe_height;
+					int main_pipe_width = 0, main_pipe_height = 0;
 					struct dc_stream_state *phantom_stream = dc_state_get_paired_subvp_stream(dc->current_state, dc->current_state->res_ctx.pipe_ctx[i].stream);
 
-					main_pipe_width = phantom_stream->dst.width;
-					main_pipe_height = phantom_stream->dst.height;
+					if (phantom_stream) {
+						main_pipe_width = phantom_stream->dst.width;
+						main_pipe_height = phantom_stream->dst.height;
+					}
+
 					dc->hwss.blank_phantom(dc, tg, main_pipe_width, main_pipe_height);
 				}
 				tg->funcs->enable_crtc(tg);
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index 2e1b30a33ea9..969658313fd6 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1687,6 +1687,8 @@ static struct dc_stream_state *dcn32_enable_phantom_stream(struct dc *dc,
 	struct pipe_ctx *ref_pipe = &context->res_ctx.pipe_ctx[dc_pipe_idx];
 
 	phantom_stream = dc_state_create_phantom_stream(dc, context, ref_pipe->stream);
+	if (!phantom_stream)
+		return phantom_stream;
 
 	/* stream has limited viewport and small timing */
 	memcpy(&phantom_stream->timing, &ref_pipe->stream->timing, sizeof(phantom_stream->timing));
-- 
2.45.1



More information about the amd-gfx mailing list