Bug 215638 - drm_fb_helper_single_fb_probe fails to evaluate proper bpp and depth
Summary: drm_fb_helper_single_fb_probe fails to evaluate proper bpp and depth
Status: NEW
Alias: None
Product: Drivers
Classification: Unclassified
Component: Console/Framebuffers (show other bugs)
Hardware: Other Linux
: P1 low
Assignee: James Simmons
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-02-23 13:59 UTC by Siarhei Volkau
Modified: 2022-02-23 13:59 UTC (History)
0 users

See Also:
Kernel Version: 5.15-rc6 and 5.17-rc2
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Siarhei Volkau 2022-02-23 13:59:23 UTC
DRM FB helper: drm_fb_helper_hotplug_event can't gracefully scale down to 16bpp formats.

I'm playing around a DRM driver changes for Ingenic jz4725b based device and found this minor issue.
To reproduce it you can try to change formats supported by your framebuffer driver to keep only one format supported - DRM_FORMAT_RGB565.

I observe following messages in the log:
... [drm] requested bpp 32, scaled depth down to 16
------------[ cut here ]------------
WARNING: CPU: 0 PID: 5 at drivers/gpu/drm/drm_fourcc.c:303 0x803080d4
...
Stack : ...
Call Trace:
...
---[ end trace 6d1c218a93c69a06 ]---
CPU 0 Unable to handle kernel paging request at virtual address 00000006
...
---[ end trace 6d1c218a93c69a07 ]---
Kernel panic - not syncing: Fatal exception
---[ end Kernel panic - not syncing: Fatal exception ]---


My investigation concerns 3 functions:
- drm_fb_helper_single_fb_probe
- drm_mode_legacy_fb_format
- drm_client_framebuffer_create
which called one by another.

1. drm_fb_helper_single_fb_probe evaluates following parameters:
 - surface_depth = 16
 - surface_bpp = 32
which looks odd, but the problem goes later, in the drm_fb_helper_generic_probe call.

2. The function drm_mode_legacy_fb_format tries to evaluate DRM_MODE_... by surfece's bpp/depth but fails to do so returning DRM_MODE_INVALID. After that the invalid mode passed to drm_client_framebuffer_create without validation.

3. The drm_client_buffer_create tries to get drm_format_info for the invalid mode, it gets NULL of course (that's where the warning appear), but it doesn't check it against NULL and de-reference nullptr object with crashing.

I have no idea how to do it right, maybe we need change surface_bpp accordingly, or validate the format with returning an error or fix something behind the scene.

Note You need to log in before you can comment on or make changes to this bug.