Skip to content

Commit eae0612

Browse files
committed
drm: refuse ADDFB2 ioctl for broken bigendian drivers
Drivers must set the quirk_addfb_prefer_host_byte_order quirk to make the drm_mode_addfb() compat code work correctly on bigendian machines. If they don't they interpret pixel_format values incorrectly for bug compatibility, which in turn implies the ADDFB2 ioctl does not work correctly then. So block it to make userspace fallback to ADDFB. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/20180907073213.20410-1-kraxel@redhat.com
1 parent ea4584c commit eae0612

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

drivers/gpu/drm/drm_crtc_internal.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,17 @@ void drm_fb_release(struct drm_file *file_priv);
182182

183183
int drm_mode_addfb(struct drm_device *dev, struct drm_mode_fb_cmd *or,
184184
struct drm_file *file_priv);
185+
int drm_mode_addfb2(struct drm_device *dev,
186+
void *data, struct drm_file *file_priv);
185187
int drm_mode_rmfb(struct drm_device *dev, u32 fb_id,
186188
struct drm_file *file_priv);
187189

188190

189191
/* IOCTL */
190192
int drm_mode_addfb_ioctl(struct drm_device *dev,
191193
void *data, struct drm_file *file_priv);
192-
int drm_mode_addfb2(struct drm_device *dev,
193-
void *data, struct drm_file *file_priv);
194+
int drm_mode_addfb2_ioctl(struct drm_device *dev,
195+
void *data, struct drm_file *file_priv);
194196
int drm_mode_rmfb_ioctl(struct drm_device *dev,
195197
void *data, struct drm_file *file_priv);
196198
int drm_mode_getfb(struct drm_device *dev,

drivers/gpu/drm/drm_framebuffer.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,30 @@ int drm_mode_addfb2(struct drm_device *dev,
369369
return 0;
370370
}
371371

372+
int drm_mode_addfb2_ioctl(struct drm_device *dev,
373+
void *data, struct drm_file *file_priv)
374+
{
375+
#ifdef __BIG_ENDIAN
376+
if (!dev->mode_config.quirk_addfb_prefer_host_byte_order) {
377+
/*
378+
* Drivers must set the
379+
* quirk_addfb_prefer_host_byte_order quirk to make
380+
* the drm_mode_addfb() compat code work correctly on
381+
* bigendian machines.
382+
*
383+
* If they don't they interpret pixel_format values
384+
* incorrectly for bug compatibility, which in turn
385+
* implies the ADDFB2 ioctl does not work correctly
386+
* then. So block it to make userspace fallback to
387+
* ADDFB.
388+
*/
389+
DRM_DEBUG_KMS("addfb2 broken on bigendian");
390+
return -EINVAL;
391+
}
392+
#endif
393+
return drm_mode_addfb2(dev, data, file_priv);
394+
}
395+
372396
struct drm_mode_rmfb_work {
373397
struct work_struct work;
374398
struct list_head fbs;

drivers/gpu/drm/drm_ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
645645
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_UNLOCKED),
646646
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_UNLOCKED),
647647
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, DRM_UNLOCKED),
648-
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_UNLOCKED),
648+
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, DRM_UNLOCKED),
649649
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, DRM_UNLOCKED),
650650
DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_UNLOCKED),
651651
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_UNLOCKED),

0 commit comments

Comments
 (0)