mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									4cd9fa529d
								
							
						
					
					
						commit
						4cba68507c
					
				
					 3 changed files with 27 additions and 1 deletions
				
			
		| 
						 | 
					@ -508,6 +508,22 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Reject event generation for when a CRTC is off and stays off.
 | 
				
			||||||
 | 
						 * It wouldn't be hard to implement this, but userspace has a track
 | 
				
			||||||
 | 
						 * record of happily burning through 100% cpu (or worse, crash) when the
 | 
				
			||||||
 | 
						 * display pipe is suspended. To avoid all that fun just reject updates
 | 
				
			||||||
 | 
						 * that ask for events since likely that indicates a bug in the
 | 
				
			||||||
 | 
						 * compositor's drawing loop. This is consistent with the vblank IOCTL
 | 
				
			||||||
 | 
						 * and legacy page_flip IOCTL which also reject service on a disabled
 | 
				
			||||||
 | 
						 * pipe.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (state->event && !state->active && !crtc->state->active) {
 | 
				
			||||||
 | 
							DRM_DEBUG_ATOMIC("[CRTC:%d] requesting event but off\n",
 | 
				
			||||||
 | 
									 crtc->base.id);
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2284,6 +2284,15 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
	drm_atomic_set_fb_for_plane(plane_state, fb);
 | 
						drm_atomic_set_fb_for_plane(plane_state, fb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Make sure we don't accidentally do a full modeset. */
 | 
				
			||||||
 | 
						state->allow_modeset = false;
 | 
				
			||||||
 | 
						if (!crtc_state->active) {
 | 
				
			||||||
 | 
							DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n",
 | 
				
			||||||
 | 
									 crtc->base.id);
 | 
				
			||||||
 | 
							ret = -EINVAL;
 | 
				
			||||||
 | 
							goto fail;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = drm_atomic_async_commit(state);
 | 
						ret = drm_atomic_async_commit(state);
 | 
				
			||||||
	if (ret != 0)
 | 
						if (ret != 0)
 | 
				
			||||||
		goto fail;
 | 
							goto fail;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,7 +551,8 @@ struct drm_crtc_funcs {
 | 
				
			||||||
	 * ->page_flip() operation is already pending the callback should return
 | 
						 * ->page_flip() operation is already pending the callback should return
 | 
				
			||||||
	 * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode
 | 
						 * -EBUSY. Pageflips on a disabled CRTC (either by setting a NULL mode
 | 
				
			||||||
	 * or just runtime disabled through DPMS respectively the new atomic
 | 
						 * or just runtime disabled through DPMS respectively the new atomic
 | 
				
			||||||
	 * "ACTIVE" state) should result in an -EINVAL error code.
 | 
						 * "ACTIVE" state) should result in an -EINVAL error code. Note that
 | 
				
			||||||
 | 
						 * drm_atomic_helper_page_flip() checks this already for atomic drivers.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	int (*page_flip)(struct drm_crtc *crtc,
 | 
						int (*page_flip)(struct drm_crtc *crtc,
 | 
				
			||||||
			 struct drm_framebuffer *fb,
 | 
								 struct drm_framebuffer *fb,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue