Эх сурвалжийг харах

disp: msm: sde: avoid null pointer dereference

This change avoids null pointer dereference in different APIs.

Change-Id: I01eba9d64fa4ba2fd81f7f39f586867e22d66771
Signed-off-by: Narendra Muppalla <[email protected]>
Narendra Muppalla 3 жил өмнө
parent
commit
ae96cad06c

+ 20 - 5
msm/sde/sde_connector.c

@@ -2610,18 +2610,32 @@ sde_connector_best_encoder(struct drm_connector *connector)
 static struct drm_encoder *
 sde_connector_atomic_best_encoder(struct drm_connector *connector,
 		struct drm_atomic_state *state)
+{
+	struct sde_connector *c_conn;
+	struct drm_encoder *encoder = NULL;
+	struct drm_connector_state *connector_state = NULL;
+
+	if (!connector) {
+		SDE_ERROR("invalid connector\n");
+		return NULL;
+	}
+
+	connector_state = drm_atomic_get_new_connector_state(state, connector);
+	c_conn = to_sde_connector(connector);
+
+	if (c_conn->ops.atomic_best_encoder)
+		encoder = c_conn->ops.atomic_best_encoder(connector,
+				c_conn->display, connector_state);
+
+	return encoder;
+}
 #else
 static struct drm_encoder *
 sde_connector_atomic_best_encoder(struct drm_connector *connector,
 		struct drm_connector_state *connector_state)
-#endif
 {
 	struct sde_connector *c_conn;
 	struct drm_encoder *encoder = NULL;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-	struct drm_connector_state *connector_state =
-			drm_atomic_get_new_connector_state(state, connector);
-#endif
 
 	if (!connector) {
 		SDE_ERROR("invalid connector\n");
@@ -2636,6 +2650,7 @@ sde_connector_atomic_best_encoder(struct drm_connector *connector,
 
 	return encoder;
 }
+#endif
 
 static int sde_connector_atomic_check(struct drm_connector *connector,
 		struct drm_atomic_state *state)

+ 56 - 23
msm/sde/sde_crtc.c

@@ -3683,13 +3683,9 @@ static void _sde_crtc_clear_all_blend_stages(struct sde_crtc *sde_crtc)
 	}
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
-		struct drm_atomic_state *state)
-#else
-static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
+static void _sde_crtc_atomic_begin(struct drm_crtc *crtc,
 		struct drm_crtc_state *old_state)
-#endif
+
 {
 	struct sde_crtc *sde_crtc;
 	struct drm_encoder *encoder;
@@ -3698,14 +3694,6 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
 	struct sde_splash_display *splash_display;
 	bool cont_splash_enabled = false;
 	size_t i;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-	struct drm_crtc_state *old_state = drm_atomic_get_new_crtc_state(state, crtc);
-#endif
-
-	if (!crtc) {
-		SDE_ERROR("invalid crtc\n");
-		return;
-	}
 
 	if (!crtc->state->enable) {
 		SDE_DEBUG("crtc%d -> enable %d, skip atomic_begin\n",
@@ -3800,6 +3788,33 @@ end:
 	SDE_ATRACE_END("crtc_atomic_begin");
 }
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *old_state = NULL;
+
+	if (!crtc) {
+		SDE_ERROR("invalid crtc\n");
+		return;
+	}
+
+	old_state = drm_atomic_get_old_crtc_state(state, crtc);
+	_sde_crtc_atomic_begin(crtc, old_state);
+}
+#else
+static void sde_crtc_atomic_begin(struct drm_crtc *crtc,
+		struct drm_crtc_state *old_state)
+{
+	if (!crtc) {
+		SDE_ERROR("invalid crtc\n");
+		return;
+	}
+	_sde_crtc_atomic_begin(crtc, old_state);
+}
+#endif
+
+
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
 static void sde_crtc_atomic_flush(struct drm_crtc *crtc,
 		struct drm_atomic_state *state)
@@ -5499,13 +5514,8 @@ static int _sde_crtc_check_plane_layout(struct drm_crtc *crtc,
 	return 0;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-static int sde_crtc_atomic_check(struct drm_crtc *crtc,
-		struct drm_atomic_state *atomic_state)
-#else
-static int sde_crtc_atomic_check(struct drm_crtc *crtc,
+static int _sde_crtc_atomic_check(struct drm_crtc *crtc,
 		struct drm_crtc_state *state)
-#endif
 {
 	struct drm_device *dev;
 	struct sde_crtc *sde_crtc;
@@ -5516,9 +5526,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 	struct sde_multirect_plane_states *multirect_plane = NULL;
 	struct drm_connector *conn;
 	struct drm_connector_list_iter conn_iter;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-	struct drm_crtc_state *state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
-#endif
 
 	if (!crtc) {
 		SDE_ERROR("invalid crtc\n");
@@ -5614,6 +5621,32 @@ end:
 	return rc;
 }
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+static int sde_crtc_atomic_check(struct drm_crtc *crtc,
+		struct drm_atomic_state *atomic_state)
+{
+	struct drm_crtc_state *state = NULL;
+
+	if (!crtc) {
+		SDE_ERROR("invalid crtc\n");
+		return -EINVAL;
+	}
+
+	state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+	return _sde_crtc_atomic_check(crtc, state);
+}
+#else
+static int sde_crtc_atomic_check(struct drm_crtc *crtc,
+		struct drm_crtc_state *state)
+{
+	if (!crtc) {
+		SDE_ERROR("invalid crtc\n");
+		return -EINVAL;
+	}
+	return _sde_crtc_atomic_check(crtc, state);
+}
+#endif
+
 /**
  * sde_crtc_get_num_datapath - get the number of layermixers active
  *				on primary connector

+ 6 - 1
msm/sde/sde_encoder_phys_cmd.c

@@ -180,6 +180,9 @@ static void _sde_encoder_phys_signal_frame_done(struct sde_encoder_phys *phys_en
 	cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
 	ctl = phys_enc->hw_ctl;
 
+	if (!ctl)
+		return;
+
 	/* notify all synchronous clients first, then asynchronous clients */
 	if (phys_enc->parent_ops.handle_frame_done &&
 		atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0)) {
@@ -1860,11 +1863,13 @@ static void sde_encoder_phys_cmd_prepare_commit(
 		struct sde_encoder_phys *phys_enc)
 {
 	struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
-	struct sde_kms *sde_kms = phys_enc->sde_kms;
+	struct sde_kms *sde_kms;
 
 	if (!phys_enc || !sde_encoder_phys_cmd_is_master(phys_enc))
 		return;
 
+	sde_kms = phys_enc->sde_kms;
+
 	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0,
 			cmd_enc->autorefresh.cfg.enable);
 

+ 2 - 1
msm/sde/sde_encoder_phys_wb.c

@@ -1929,7 +1929,8 @@ static int sde_encoder_phys_wb_prepare_for_kickoff(struct sde_encoder_phys *phys
 	struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc);
 	int ret = 0;
 
-	phys_enc->frame_trigger_mode = params->frame_trigger_mode;
+	phys_enc->frame_trigger_mode = params ?
+		params->frame_trigger_mode : FRAME_DONE_WAIT_DEFAULT;
 	if (!phys_enc->in_clone_mode && (phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_DEFAULT)
 			&& (atomic_read(&phys_enc->pending_kickoff_cnt))) {
 		ret = _sde_encoder_phys_wb_wait_for_idle(phys_enc, true);

+ 30 - 16
msm/sde/sde_plane.c

@@ -2709,27 +2709,12 @@ modeset_update:
 	return ret;
 }
 
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-static int sde_plane_atomic_check(struct drm_plane *plane,
-		struct drm_atomic_state *atomic_state)
-#else
-static int sde_plane_atomic_check(struct drm_plane *plane,
+static int _sde_plane_atomic_check(struct drm_plane *plane,
 		struct drm_plane_state *state)
-#endif
 {
 	int ret = 0;
 	struct sde_plane *psde;
 	struct sde_plane_state *pstate;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
-	struct drm_plane_state *state = drm_atomic_get_new_plane_state(atomic_state, plane);
-#endif
-
-	if (!plane || !state) {
-		SDE_ERROR("invalid arg(s), plane %d state %d\n",
-				!plane, !state);
-		ret = -EINVAL;
-		goto exit;
-	}
 
 	psde = to_sde_plane(plane);
 	pstate = to_sde_plane_state(state);
@@ -2746,6 +2731,35 @@ exit:
 	return ret;
 }
 
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+static int sde_plane_atomic_check(struct drm_plane *plane,
+		struct drm_atomic_state *atomic_state)
+{
+	struct drm_plane_state *state = NULL;
+
+	if (!plane || !atomic_state) {
+		SDE_ERROR("invalid arg(s), plane %d atomic_state %d\n",
+				!plane, !atomic_state);
+		return -EINVAL;
+	}
+	state = drm_atomic_get_new_plane_state(atomic_state, plane);
+	return _sde_plane_atomic_check(plane, state);
+}
+#else
+static int sde_plane_atomic_check(struct drm_plane *plane,
+		struct drm_plane_state *state)
+{
+	if (!plane || !state) {
+		SDE_ERROR("invalid arg(s), plane %d state %d\n",
+				!plane, !state);
+		return -EINVAL;
+	}
+
+	return _sde_plane_atomic_check(plane, state);
+}
+#endif
+
 void sde_plane_flush(struct drm_plane *plane)
 {
 	struct sde_plane *psde;

+ 3 - 2
msm/sde/sde_rm.c

@@ -610,7 +610,7 @@ static int _sde_rm_hw_blk_create(
 	struct sde_hw_mdp *hw_mdp;
 	struct sde_hw_blk_reg_map *hw;
 	struct sde_kms *sde_kms = to_sde_kms(ddev_to_msm_kms(rm->dev));
-	struct sde_vbif_clk_client clk_client;
+	struct sde_vbif_clk_client clk_client = {0};
 
 	hw_mdp = rm->hw_mdp;
 
@@ -680,7 +680,8 @@ static int _sde_rm_hw_blk_create(
 
 	_sde_rm_inc_resource_info(rm, &rm->avail_res, blk);
 
-	if (test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_kms->catalog->features) &&
+	if (sde_kms && sde_kms->catalog &&
+			test_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_kms->catalog->features) &&
 			SDE_CLK_CTRL_VALID(clk_client.clk_ctrl)) {
 		rc = sde_vbif_clk_register(sde_kms, &clk_client);
 		if (rc) {