mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	drm: introduce CLOSEFB IOCTL
This new IOCTL allows callers to close a framebuffer without disabling planes or CRTCs. This takes inspiration from Rob Clark's unref_fb IOCTL [1] and DRM_MODE_FB_PERSIST [2]. User-space patch for wlroots available at [3]. IGT test available at [4]. v2: add an extra pad field just in case we want to extend this IOCTL in the future (Pekka, Sima). [1]: https://lore.kernel.org/dri-devel/20170509153654.23464-1-robdclark@gmail.com/ [2]: https://lore.kernel.org/dri-devel/20211006151921.312714-1-contact@emersion.fr/ [3]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4394 [4]: https://lists.freedesktop.org/archives/igt-dev/2023-October/063294.html Signed-off-by: Simon Ser <contact@emersion.fr> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com> Cc: Hans de Goede <hdegoede@redhat.com> Cc: Dennis Filder <d.filder@web.de> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: Rob Clark <robdclark@gmail.com> Cc: Sean Paul <seanpaul@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20231020101926.145327-2-contact@emersion.fr
This commit is contained in:
		
							parent
							
								
									0226ba393e
								
							
						
					
					
						commit
						d208d87566
					
				| @ -222,6 +222,8 @@ int drm_mode_addfb2_ioctl(struct drm_device *dev, | |||||||
| 			  void *data, struct drm_file *file_priv); | 			  void *data, struct drm_file *file_priv); | ||||||
| int drm_mode_rmfb_ioctl(struct drm_device *dev, | int drm_mode_rmfb_ioctl(struct drm_device *dev, | ||||||
| 			void *data, struct drm_file *file_priv); | 			void *data, struct drm_file *file_priv); | ||||||
|  | int drm_mode_closefb_ioctl(struct drm_device *dev, | ||||||
|  | 			   void *data, struct drm_file *file_priv); | ||||||
| int drm_mode_getfb(struct drm_device *dev, | int drm_mode_getfb(struct drm_device *dev, | ||||||
| 		   void *data, struct drm_file *file_priv); | 		   void *data, struct drm_file *file_priv); | ||||||
| int drm_mode_getfb2_ioctl(struct drm_device *dev, | int drm_mode_getfb2_ioctl(struct drm_device *dev, | ||||||
|  | |||||||
| @ -480,6 +480,28 @@ int drm_mode_rmfb_ioctl(struct drm_device *dev, | |||||||
| 	return drm_mode_rmfb(dev, *fb_id, file_priv); | 	return drm_mode_rmfb(dev, *fb_id, file_priv); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int drm_mode_closefb_ioctl(struct drm_device *dev, | ||||||
|  | 			   void *data, struct drm_file *file_priv) | ||||||
|  | { | ||||||
|  | 	struct drm_mode_closefb *r = data; | ||||||
|  | 	struct drm_framebuffer *fb; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (!drm_core_check_feature(dev, DRIVER_MODESET)) | ||||||
|  | 		return -EOPNOTSUPP; | ||||||
|  | 
 | ||||||
|  | 	if (r->pad) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); | ||||||
|  | 	if (!fb) | ||||||
|  | 		return -ENOENT; | ||||||
|  | 
 | ||||||
|  | 	ret = drm_mode_closefb(fb, file_priv); | ||||||
|  | 	drm_framebuffer_put(fb); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * drm_mode_getfb - get FB info |  * drm_mode_getfb - get FB info | ||||||
|  * @dev: drm device for the ioctl |  * @dev: drm device for the ioctl | ||||||
|  | |||||||
| @ -675,6 +675,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = { | |||||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0), | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0), | ||||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0), | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0), | ||||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0), | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0), | ||||||
|  | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CLOSEFB, drm_mode_closefb_ioctl, 0), | ||||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER), | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER), | ||||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER), | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER), | ||||||
| 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0), | 	DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, 0), | ||||||
|  | |||||||
| @ -1218,6 +1218,26 @@ extern "C" { | |||||||
| 
 | 
 | ||||||
| #define DRM_IOCTL_SYNCOBJ_EVENTFD	DRM_IOWR(0xCF, struct drm_syncobj_eventfd) | #define DRM_IOCTL_SYNCOBJ_EVENTFD	DRM_IOWR(0xCF, struct drm_syncobj_eventfd) | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * DRM_IOCTL_MODE_CLOSEFB - Close a framebuffer. | ||||||
|  |  * | ||||||
|  |  * This closes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL | ||||||
|  |  * argument is a framebuffer object ID. | ||||||
|  |  * | ||||||
|  |  * This IOCTL is similar to &DRM_IOCTL_MODE_RMFB, except it doesn't disable | ||||||
|  |  * planes and CRTCs. As long as the framebuffer is used by a plane, it's kept | ||||||
|  |  * alive. When the plane no longer uses the framebuffer (because the | ||||||
|  |  * framebuffer is replaced with another one, or the plane is disabled), the | ||||||
|  |  * framebuffer is cleaned up. | ||||||
|  |  * | ||||||
|  |  * This is useful to implement flicker-free transitions between two processes. | ||||||
|  |  * | ||||||
|  |  * Depending on the threat model, user-space may want to ensure that the | ||||||
|  |  * framebuffer doesn't expose any sensitive user information: closed | ||||||
|  |  * framebuffers attached to a plane can be read back by the next DRM master. | ||||||
|  |  */ | ||||||
|  | #define DRM_IOCTL_MODE_CLOSEFB		DRM_IOWR(0xD0, struct drm_mode_closefb) | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Device specific ioctls should only be in their respective headers |  * Device specific ioctls should only be in their respective headers | ||||||
|  * The device specific ioctl range is from 0x40 to 0x9f. |  * The device specific ioctl range is from 0x40 to 0x9f. | ||||||
|  | |||||||
| @ -1323,6 +1323,16 @@ struct drm_mode_rect { | |||||||
| 	__s32 y2; | 	__s32 y2; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * struct drm_mode_closefb | ||||||
|  |  * @fb_id: Framebuffer ID. | ||||||
|  |  * @pad: Must be zero. | ||||||
|  |  */ | ||||||
|  | struct drm_mode_closefb { | ||||||
|  | 	__u32 fb_id; | ||||||
|  | 	__u32 pad; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Simon Ser
						Simon Ser