drm/fbdev: Clamp fbdev surface size if too large
authorThomas Zimmermann <tzimmermann@suse.de>
Tue, 5 Oct 2021 07:03:55 +0000 (09:03 +0200)
committerDave Airlie <airlied@redhat.com>
Fri, 15 Oct 2021 05:04:05 +0000 (15:04 +1000)
Clamp the fbdev surface size of the available maximumi height to avoid
failing to init console emulation. An example error is shown below.

  bad framebuffer height 2304, should be >= 768 && <= 768
  [drm] Initialized simpledrm 1.0.0 20200625 for simple-framebuffer.0 on minor 0
  simple-framebuffer simple-framebuffer.0: [drm] *ERROR* fbdev: Failed to setup generic emulation (ret=-22)

This is especially a problem with drivers that have very small screen
sizes and cannot over-allocate at all.

v2:
* reduce warning level (Ville)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reported-by: Amanoel Dawod <kernel@amanoeldawod.com>
Reported-by: Zoltán Kővágó <dirty.ice.hu@gmail.com>
Reported-by: Michael Stapelberg <michael+lkml@stapelberg.ch>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Maxime Ripard <maxime@cerno.tech>
Cc: dri-devel@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v5.14+
Link: https://patchwork.freedesktop.org/patch/msgid/20211005070355.7680-1-tzimmermann@suse.de
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/drm_fb_helper.c

index 3ab0783..8e7a124 100644 (file)
@@ -1506,6 +1506,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 {
        struct drm_client_dev *client = &fb_helper->client;
        struct drm_device *dev = fb_helper->dev;
+       struct drm_mode_config *config = &dev->mode_config;
        int ret = 0;
        int crtc_count = 0;
        struct drm_connector_list_iter conn_iter;
@@ -1663,6 +1664,11 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
        /* Handle our overallocation */
        sizes.surface_height *= drm_fbdev_overalloc;
        sizes.surface_height /= 100;
+       if (sizes.surface_height > config->max_height) {
+               drm_dbg_kms(dev, "Fbdev over-allocation too large; clamping height to %d\n",
+                           config->max_height);
+               sizes.surface_height = config->max_height;
+       }
 
        /* push down into drivers */
        ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes);