diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-12-08 03:49:20 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-01-05 04:07:51 -0500 |
commit | 4cba68507cf58db99752cf79198beb4a85a9f8ce (patch) | |
tree | ce0e53f48983a7414baedc51df01a284908fe7e6 | |
parent | 4cd9fa529d77dde8f760adb3d934dfac6e169b1e (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.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 9 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 3 |
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, |