aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2015-12-08 03:49:20 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-01-05 04:07:51 -0500
commit4cba68507cf58db99752cf79198beb4a85a9f8ce (patch)
treece0e53f48983a7414baedc51df01a284908fe7e6
parent4cd9fa529d77dde8f760adb3d934dfac6e169b1e (diff)
drm/atomic-helper: Reject legacy flips on a disabled pipe
We want this for consistency with existing page_flip semantics. Since this spurred quite a discussion on IRC also document why we reject event generation when the pipe is off: It's not that it's hard to implement, but userspace has a track recording which proves that it's way too easy to accidentally abuse and cause havoc. We want to make sure userspace doesn't get away with that. v2: Somehow thought we do reject events already, but that code only existed in my imagination ... Also suggestions from Thierry. Cc: Daniel Stone <daniels@collabora.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Thierry Reding <thierry.reding@gmail.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1449564561-3896-4-git-send-email-daniel.vetter@ffwll.ch
-rw-r--r--drivers/gpu/drm/drm_atomic.c16
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c9
-rw-r--r--include/drm/drm_crtc.h3
3 files changed, 27 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 14b321580517..6050c80f1dbc 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -508,6 +508,22 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
508 return -EINVAL; 508 return -EINVAL;
509 } 509 }
510 510
511 /*
512 * Reject event generation for when a CRTC is off and stays off.
513 * It wouldn't be hard to implement this, but userspace has a track
514 * record of happily burning through 100% cpu (or worse, crash) when the
515 * display pipe is suspended. To avoid all that fun just reject updates
516 * that ask for events since likely that indicates a bug in the
517 * compositor's drawing loop. This is consistent with the vblank IOCTL
518 * and legacy page_flip IOCTL which also reject service on a disabled
519 * pipe.
520 */
521 if (state->event && !state->active && !crtc->state->active) {
522 DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n",
523 crtc->base.id);
524 return -EINVAL;
525 }
526
511 return 0; 527 return 0;
512} 528}
513 529
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 26d258d0618b..738104b68d26 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2284,6 +2284,15 @@ retry:
2284 goto fail; 2284 goto fail;
2285 drm_atomic_set_fb_for_plane(plane_state, fb); 2285 drm_atomic_set_fb_for_plane(plane_state, fb);
2286 2286
2287 /* Make sure we don't accidentally do a full modeset. */
2288 state->allow_modeset = false;
2289 if (!crtc_state->active) {
2290 DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n",
2291 crtc->base.id);
2292 ret = -EINVAL;
2293 goto fail;
2294 }
2295
2287 ret = drm_atomic_async_commit(state); 2296 ret = drm_atomic_async_commit(state);
2288 if (ret != 0) 2297 if (ret != 0)
2289 goto fail; 2298 goto fail;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index e3c4d486e1af..c65a212db77e 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -551,7 +551,8 @@ struct drm_crtc_funcs {
551 * ->page_flip() operation is already pending the callback should return 551 * ->page_flip() operation is already pending the callback should return
552 * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode 552 * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode
553 * or just runtime disabled through DPMS respectively the new atomic 553 * or just runtime disabled through DPMS respectively the new atomic
554 * "ACTIVE" state) should result in an -EINVAL error code. 554 * "ACTIVE" state) should result in an -EINVAL error code. Note that
555 * drm_atomic_helper_page_flip() checks this already for atomic drivers.
555 */ 556 */
556 int (*page_flip)(struct drm_crtc *crtc, 557 int (*page_flip)(struct drm_crtc *crtc,
557 struct drm_framebuffer *fb, 558 struct drm_framebuffer *fb,