Change the return type of drm_sysfb_get_visible_size() to s64 so
that it returns a possible errno code from _get_validated_size0().
Fix callers to handle the errno code.

The currently returned unsigned type converts an errno code to a
very large size value, which drivers interpret as visible size of
the system framebuffer. Later efforts to reserve the framebuffer
resource fail.

The bug has been present since efidrm and vesadrm got merged. It
was then part of each driver.

Signed-off-by: Thomas Zimmermann <[email protected]>
Fixes: 32ae90c66fb6 ("drm/sysfb: Add efidrm for EFI displays")
Fixes: a84eb6abe2b6 ("drm/sysfb: Add vesadrm for VESA displays")
Reviewed-by: Javier Martinez Canillas <[email protected]>
Cc: Thomas Zimmermann <[email protected]>
Cc: Javier Martinez Canillas <[email protected]>
Cc: [email protected]
Cc: <[email protected]> # v6.16+
---
 drivers/gpu/drm/sysfb/drm_sysfb_helper.h      | 2 +-
 drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c | 2 +-
 drivers/gpu/drm/sysfb/efidrm.c                | 7 ++++---
 drivers/gpu/drm/sysfb/vesadrm.c               | 6 +++---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h 
b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
index 2a2b553366fb..547f2327af5e 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
@@ -50,7 +50,7 @@ struct resource *drm_sysfb_get_memory_si(struct drm_device 
*dev,
 int drm_sysfb_get_stride_si(struct drm_device *dev, const struct screen_info 
*si,
                            const struct drm_format_info *format,
                            unsigned int width, unsigned int height, u64 size);
-u64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct 
screen_info *si,
+s64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct 
screen_info *si,
                                  unsigned int height, unsigned int stride, u64 
size);
 #endif
 
diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c 
b/drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c
index 8b14eaa304c0..042d1b796696 100644
--- a/drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c
+++ b/drivers/gpu/drm/sysfb/drm_sysfb_screen_info.c
@@ -65,7 +65,7 @@ int drm_sysfb_get_stride_si(struct drm_device *dev, const 
struct screen_info *si
 }
 EXPORT_SYMBOL(drm_sysfb_get_stride_si);
 
-u64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct 
screen_info *si,
+s64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct 
screen_info *si,
                                  unsigned int height, unsigned int stride, u64 
size)
 {
        u64 vsize = mul_u32_u32(height, stride);
diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c
index 1a1e36700976..3f9cd5d03efb 100644
--- a/drivers/gpu/drm/sysfb/efidrm.c
+++ b/drivers/gpu/drm/sysfb/efidrm.c
@@ -152,7 +152,8 @@ static struct efidrm_device *efidrm_device_create(struct 
drm_driver *drv,
        const struct screen_info *si;
        const struct drm_format_info *format;
        int width, height, stride;
-       u64 vsize, mem_flags;
+       s64 vsize;
+       u64 mem_flags;
        struct resource resbuf;
        struct resource *res;
        struct efidrm_device *efi;
@@ -206,8 +207,8 @@ static struct efidrm_device *efidrm_device_create(struct 
drm_driver *drv,
        if (stride < 0)
                return ERR_PTR(stride);
        vsize = drm_sysfb_get_visible_size_si(dev, si, height, stride, 
resource_size(res));
-       if (!vsize)
-               return ERR_PTR(-EINVAL);
+       if (vsize < 0)
+               return ERR_PTR(vsize);
 
        drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d bytes\n",
                &format->format, width, height, stride);
diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c
index dbc317778d54..6a67b2d2e451 100644
--- a/drivers/gpu/drm/sysfb/vesadrm.c
+++ b/drivers/gpu/drm/sysfb/vesadrm.c
@@ -402,7 +402,7 @@ static struct vesadrm_device *vesadrm_device_create(struct 
drm_driver *drv,
        const struct screen_info *si;
        const struct drm_format_info *format;
        int width, height, stride;
-       u64 vsize;
+       s64 vsize;
        struct resource resbuf;
        struct resource *res;
        struct vesadrm_device *vesa;
@@ -457,8 +457,8 @@ static struct vesadrm_device *vesadrm_device_create(struct 
drm_driver *drv,
        if (stride < 0)
                return ERR_PTR(stride);
        vsize = drm_sysfb_get_visible_size_si(dev, si, height, stride, 
resource_size(res));
-       if (!vsize)
-               return ERR_PTR(-EINVAL);
+       if (vsize < 0)
+               return ERR_PTR(vsize);
 
        drm_dbg(dev, "framebuffer format=%p4cc, size=%dx%d, stride=%d bytes\n",
                &format->format, width, height, stride);
-- 
2.54.0

Reply via email to