drm/i915: Check fb stride against plane max stride
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 18 Sep 2018 14:02:43 +0000 (17:02 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 25 Sep 2018 17:54:35 +0000 (20:54 +0300)
commit 4e0b83a567e2 ("drm/i915: Extract per-platform plane->check()
functions") removed the plane max stride check for sprite planes.
I was going to add it back when introducing GTT remapping for the
display, but after further thought it seems better to re-introduce
it separately.

So let's add the max stride check back. And let's do it in a nicer
form than what we had before and do it for all plane types (easy
now that we have the ->max_stride() plane vfunc).

Only sprite planes really need this for now since primary planes
are capable of scanning out the current max fb size we allow, and
cursors have more stringent stride checks elsewhere.

Cc: José Roberto de Souza <jose.souza@intel.com>
Fixes: 4e0b83a567e2 ("drm/i915: Extract per-platform plane->check() functions")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180918140243.12207-1-ville.syrjala@linux.intel.com
Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_sprite.c

index d3c679ee3fbfa8d44bc3cb9cea0142a82cd174a3..5e7b907e54d626d614e173473608813117da99f5 100644 (file)
@@ -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;
 
index 07707728e4b68f412eae2c9bf30274aba6e850f4..8de41ac75d842116bcc43cb076cb30bfa75c8f6f 100644 (file)
@@ -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);
 
index 96de5a33dbaf1418d3a1780b28f117d3f0c5aaa5..d9e407d837b9149c3119e9de66ae54438a4d56d8 100644 (file)
@@ -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;