diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d3c679ee3fbf..5e7b907e54d6 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3150,6 +3150,10 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state) plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation); plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation); + ret = intel_plane_check_stride(plane_state); + if (ret) + return ret; + if (!plane_state->base.visible) return 0; @@ -3285,10 +3289,15 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) int src_x = plane_state->base.src.x1 >> 16; int src_y = plane_state->base.src.y1 >> 16; u32 offset; + int ret; intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation); plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation); + ret = intel_plane_check_stride(plane_state); + if (ret) + return ret; + intel_add_fb_offsets(&src_x, &src_y, plane_state, 0); if (INTEL_GEN(dev_priv) >= 4) @@ -9683,10 +9692,15 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state) unsigned int rotation = plane_state->base.rotation; int src_x, src_y; u32 offset; + int ret; intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation); plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation); + ret = intel_plane_check_stride(plane_state); + if (ret) + return ret; + src_x = plane_state->base.src_x >> 16; src_y = plane_state->base.src_y >> 16; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 07707728e4b6..8de41ac75d84 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -2138,6 +2138,7 @@ unsigned int skl_plane_max_stride(struct intel_plane *plane, unsigned int rotation); int skl_plane_check(struct intel_crtc_state *crtc_state, struct intel_plane_state *plane_state); +int intel_plane_check_stride(const struct intel_plane_state *plane_state); int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state); int chv_plane_check_rotation(const struct intel_plane_state *plane_state); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 96de5a33dbaf..d9e407d837b9 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -230,6 +230,28 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) #endif } +int intel_plane_check_stride(const struct intel_plane_state *plane_state) +{ + struct intel_plane *plane = to_intel_plane(plane_state->base.plane); + const struct drm_framebuffer *fb = plane_state->base.fb; + unsigned int rotation = plane_state->base.rotation; + u32 stride, max_stride; + + /* FIXME other color planes? */ + stride = plane_state->color_plane[0].stride; + max_stride = plane->max_stride(plane, fb->format->format, + fb->modifier, rotation); + + if (stride > max_stride) { + DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n", + fb->base.id, stride, + plane->base.base.id, plane->base.name, max_stride); + return -EINVAL; + } + + return 0; +} + int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state) { const struct drm_framebuffer *fb = plane_state->base.fb;