Blob Blame History Raw
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Date: Wed, 12 Jul 2017 10:13:29 +0200
Subject: drm/simple-kms-helper: Fix the check for the mismatch between plane
 and CRTC enabled.
Git-commit: 765831dc27ab141b3a0be1ab55b922b012427902
Patch-mainline: v4.14-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

You can enable the CRTC and without adding the plane to the state and
it will succeed. This should be prevented in the crtc check instead of
the plane check, because the plane check may never run for atomic
enable, but the crtc check always will.

This is based on a similar check in vmwgfx.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: David Airlie <airlied@linux.ie>
Link: http://patchwork.freedesktop.org/patch/msgid/20170712081344.25495-2-maarten.lankhorst@linux.intel.com
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/drm_simple_kms_helper.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/drm_simple_kms_helper.c
+++ b/drivers/gpu/drm/drm_simple_kms_helper.c
@@ -37,6 +37,13 @@ static const struct drm_encoder_funcs dr
 static int drm_simple_kms_crtc_check(struct drm_crtc *crtc,
 				     struct drm_crtc_state *state)
 {
+	bool has_primary = state->plane_mask &
+			   BIT(drm_plane_index(crtc->primary));
+
+	/* We always want to have an active plane with an active CRTC */
+	if (has_primary != state->enable)
+		return -EINVAL;
+
 	return drm_atomic_add_affected_planes(state->state, crtc);
 }
 
@@ -90,9 +97,6 @@ static int drm_simple_kms_plane_atomic_c
 	pipe = container_of(plane, struct drm_simple_display_pipe, plane);
 	crtc_state = drm_atomic_get_new_crtc_state(plane_state->state,
 						   &pipe->crtc);
-	if (crtc_state->enable != !!plane_state->crtc)
-		return -EINVAL; /* plane must match crtc enable state */
-
 	if (!crtc_state->enable)
 		return 0; /* nothing to check when disabling or disabled */