diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc.c b/drivers/gpu/drm/rockchip/rockchip_ebc.c index a993866ee5db..725b3b812268 100644 --- a/drivers/gpu/drm/rockchip/rockchip_ebc.c +++ b/drivers/gpu/drm/rockchip/rockchip_ebc.c @@ -338,21 +338,22 @@ static int ioctl_trigger_global_refresh(struct drm_device *dev, void *data, } static int ioctl_set_off_screen(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file_priv) { struct drm_rockchip_ebc_off_screen *args = data; struct rockchip_ebc *ebc = dev_get_drvdata(dev->dev); - int copy_result; - pr_info("rockchip-ebc: ioctl_set_off_screen"); + int res = 0; + void __user *ptr_off_screen = u64_to_user_ptr(args->ptr_screen_content); - // TODO: blit - copy_result = copy_from_user(&ebc->final_off_screen, args->ptr_screen_content, 1313144); - copy_result = copy_from_user(&ebc->final_off_screen + 1313144, args->ptr_screen_content, 1313144); - if (copy_result != 0){ - pr_err("Could not copy off screen content from user-supplied data pointer (bytes not copied: %d)", copy_result); - } - - return 0; + if (access_ok(ptr_off_screen, ebc->num_pixels)) { + res = copy_from_user(ebc->final_off_screen, + ptr_off_screen, ebc->num_pixels); + if (res) + pr_err("Could not copy off screen content from user-supplied data pointer (bytes not copied: %d)", + res); + } else + res = -EFAULT; + return res; } struct ebc_crtc_state { diff --git a/include/uapi/drm/rockchip_ebc_drm.h b/include/uapi/drm/rockchip_ebc_drm.h index 473a3845cb34..8fc969c3111a 100644 --- a/include/uapi/drm/rockchip_ebc_drm.h +++ b/include/uapi/drm/rockchip_ebc_drm.h @@ -24,9 +24,16 @@ struct drm_rockchip_ebc_trigger_global_refresh { bool trigger_global_refresh; }; +/** + * struct drm_rockchip_ebc_off_screen - Pointer to userspace buffer. + * @info1: unused. + * @ptr_screen_content: pointer to width * height * buffer containing + * the horizontally flipped off screen. The highest four bits of each + * byte are ignored. + */ struct drm_rockchip_ebc_off_screen { __u64 info1; - char *ptr_screen_content; + __u64 ptr_screen_content; }; /** @@ -94,7 +101,7 @@ struct drm_rockchip_ebc_mode { #define DRM_ROCKCHIP_EBC_NUM_IOCTLS 0x05 #define DRM_IOCTL_ROCKCHIP_EBC_GLOBAL_REFRESH DRM_IOWR(DRM_COMMAND_BASE + 0x00, struct drm_rockchip_ebc_trigger_global_refresh) -#define DRM_IOCTL_ROCKCHIP_EBC_OFF_SCREEN DRM_IOWR(DRM_COMMAND_BASE + 0x01, struct drm_rockchip_ebc_off_screen) +#define DRM_IOCTL_ROCKCHIP_EBC_OFF_SCREEN DRM_IOW(DRM_COMMAND_BASE + 0x01, struct drm_rockchip_ebc_off_screen) #define DRM_IOCTL_ROCKCHIP_EBC_EXTRACT_FBS DRM_IOWR(DRM_COMMAND_BASE + 0x02, struct drm_rockchip_ebc_extract_fbs) #define DRM_IOCTL_ROCKCHIP_EBC_RECT_HINTS DRM_IOW(DRM_COMMAND_BASE + 0x03, struct drm_rockchip_ebc_rect_hints) #define DRM_IOCTL_ROCKCHIP_EBC_MODE DRM_IOWR(DRM_COMMAND_BASE + 0x04, struct drm_rockchip_ebc_mode)