On 16/11/18 01:06, Sebastian Reichel wrote:
The DSI encoder sets dssdev->ops->dsi.set_config, which is stored at the same offset as dssdev->ops->hdmi.set_hdmi_mode. The code in omap_encoder only checks if dssdev->ops->hdmi.set_hdmi_mode is NULL. Due to the way union works, it won't be NULL if dsi.set_config is set. This means dsi_set_config will be called with config=hdmi_mode=false=NULL parameter resulting in a NULL dereference. Also the dereference happens while console is locked, so kernel hangs without any debug output (can be avoided by fbmem's lockless_register_fb=1 parameter).
This fixes the issue by exiting early if the output type definitely has no hdmi_set operations.
Fixes: 83910ad3f51fb ("drm/omap: Move most omap_dss_driver operations to omap_dss_device_ops") Signed-off-by: Sebastian Reichel sebastian.reichel@collabora.com
drivers/gpu/drm/omapdrm/omap_encoder.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 32bbe3a80e7d..ba0099f0644c 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -122,6 +122,14 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
dssdev = omap_encoder->output;
- /* The following operations access dssdev->ops->hdmi, which is a union
* also used by DSI. This ensures, that the field does not have data
* for DSI (or any other future output type).
*/
- if (dssdev->output_type != OMAP_DISPLAY_TYPE_HDMI &&
dssdev->output_type != OMAP_DISPLAY_TYPE_DVI)
Good catch.
Why DVI?
I think the whole code block starting from
/* Set the HDMI mode and HDMI infoframe if applicable. */
to the end of the function should be inside
if (dssdev->output_type == OMAP_DISPLAY_TYPE_HDMI)
Tomi