From 52762efa2b256ed1c5274e5177cbd52ee11a2f6a Mon Sep 17 00:00:00 2001 From: Lv Yunlong Date: Mon, 22 Mar 2021 18:46:56 -0700 Subject: [PATCH 1/5] gpu/xen: Fix a use after free in xen_drm_drv_init In function displback_changed, has the call chain displback_connect(front_info)->xen_drm_drv_init(front_info). We can see that drm_info is assigned to front_info->drm_info and drm_info is freed in fail branch in xen_drm_drv_init(). Later displback_disconnect(front_info) is called and it calls xen_drm_drv_fini(front_info) cause a use after free by drm_info = front_info->drm_info statement. My patch has done two things. First fixes the fail label which drm_info = kzalloc() failed and still free the drm_info. Second sets front_info->drm_info to NULL to avoid uaf. Signed-off-by: Lv Yunlong Reviewed-by: Oleksandr Andrushchenko Signed-off-by: Oleksandr Andrushchenko Link: https://patchwork.freedesktop.org/patch/msgid/20210323014656.10068-1-lyl2019@mail.ustc.edu.cn --- drivers/gpu/drm/xen/xen_drm_front.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c index 30d9adf31c84..9f14d99c763c 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.c +++ b/drivers/gpu/drm/xen/xen_drm_front.c @@ -521,7 +521,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info) drm_dev = drm_dev_alloc(&xen_drm_driver, dev); if (IS_ERR(drm_dev)) { ret = PTR_ERR(drm_dev); - goto fail; + goto fail_dev; } drm_info->drm_dev = drm_dev; @@ -551,8 +551,10 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info) drm_kms_helper_poll_fini(drm_dev); drm_mode_config_cleanup(drm_dev); drm_dev_put(drm_dev); -fail: +fail_dev: kfree(drm_info); + front_info->drm_info = NULL; +fail: return ret; } From 014305d001987a0eeada6bac610a8665f92aae24 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Thu, 25 Mar 2021 14:19:01 +0800 Subject: [PATCH 2/5] drivers: gpu: drm: xen_drm_front_drm_info is declared twice struct xen_drm_front_drm_info has been declared. Remove the duplicate. Signed-off-by: Wan Jiabing Reviewed-by: Oleksandr Andrushchenko Signed-off-by: Oleksandr Andrushchenko Link: https://patchwork.freedesktop.org/patch/msgid/20210325061901.851273-1-wanjiabing@vivo.com --- drivers/gpu/drm/xen/xen_drm_front_conn.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/xen/xen_drm_front_conn.h b/drivers/gpu/drm/xen/xen_drm_front_conn.h index 3adacba9a23b..e5f4314899ee 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_conn.h +++ b/drivers/gpu/drm/xen/xen_drm_front_conn.h @@ -16,7 +16,6 @@ struct drm_connector; struct xen_drm_front_drm_info; -struct xen_drm_front_drm_info; int xen_drm_front_conn_init(struct xen_drm_front_drm_info *drm_info, struct drm_connector *connector); From 3b943360a20f3e4b2e0133c7cd7138b51fd93de6 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sat, 27 Feb 2021 22:45:42 +0100 Subject: [PATCH 3/5] drm/panel: panel-dsi-cm: disable TE for now Disable TE for Droid 4 panel, since implementation is currently broken. Also disable it for N950 panel, which is untested. Reported-by: Tony Lindgren Reported-by: Tomi Valkeinen Fixes: 4c1b935fea54 ("drm/omap: dsi: move TE GPIO handling into core") Signed-off-by: Sebastian Reichel Tested-by: Tony Lindgren Acked-by: Thierry Reding Signed-off-by: Tomi Valkeinen Link: https://patchwork.freedesktop.org/patch/msgid/20210227214542.99961-1-sebastian.reichel@collabora.com --- drivers/gpu/drm/panel/panel-dsi-cm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-dsi-cm.c b/drivers/gpu/drm/panel/panel-dsi-cm.c index af381d756ac1..5fbfb71ca3d9 100644 --- a/drivers/gpu/drm/panel/panel-dsi-cm.c +++ b/drivers/gpu/drm/panel/panel-dsi-cm.c @@ -37,6 +37,7 @@ struct dsic_panel_data { u32 height_mm; u32 max_hs_rate; u32 max_lp_rate; + bool te_support; }; struct panel_drv_data { @@ -334,9 +335,11 @@ static int dsicm_power_on(struct panel_drv_data *ddata) if (r) goto err; - r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); - if (r) - goto err; + if (ddata->panel_data->te_support) { + r = mipi_dsi_dcs_set_tear_on(ddata->dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK); + if (r) + goto err; + } /* possible panel bug */ msleep(100); @@ -619,6 +622,7 @@ static const struct dsic_panel_data taal_data = { .height_mm = 0, .max_hs_rate = 300000000, .max_lp_rate = 10000000, + .te_support = true, }; static const struct dsic_panel_data himalaya_data = { @@ -629,6 +633,7 @@ static const struct dsic_panel_data himalaya_data = { .height_mm = 88, .max_hs_rate = 300000000, .max_lp_rate = 10000000, + .te_support = false, }; static const struct dsic_panel_data droid4_data = { @@ -639,6 +644,7 @@ static const struct dsic_panel_data droid4_data = { .height_mm = 89, .max_hs_rate = 300000000, .max_lp_rate = 10000000, + .te_support = false, }; static const struct of_device_id dsicm_of_match[] = { From 35d65ab3fdba1bdecde9ac3424d6d634ea038729 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 18 Mar 2021 17:13:27 +0100 Subject: [PATCH 4/5] drm/vc4: plane: Remove redundant assignment The vc4_plane_atomic_async_update function assigns twice in a row the src_h field in the drm_plane_state structure to the same value. Remove the second one. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210318161328.1471556-2-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_plane.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 7322169c0682..1e9c84cf614a 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -1146,7 +1146,6 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, plane->state->src_y = state->src_y; plane->state->src_w = state->src_w; plane->state->src_h = state->src_h; - plane->state->src_h = state->src_h; plane->state->alpha = state->alpha; plane->state->pixel_blend_mode = state->pixel_blend_mode; plane->state->rotation = state->rotation; From eb9dfdd1ed40357b99a4201c8534c58c562e48c9 Mon Sep 17 00:00:00 2001 From: Dom Cobley Date: Thu, 18 Mar 2021 17:13:28 +0100 Subject: [PATCH 5/5] drm/vc4: crtc: Reduce PV fifo threshold on hvs4 Experimentally have found PV on hvs4 reports fifo full error with expected settings and does not with one less This appears as: [drm:drm_atomic_helper_wait_for_flip_done] *ERROR* [CRTC:82:crtc-3] flip_done timed out with bit 10 of PV_STAT set "HVS driving pixels when the PV FIFO is full" Fixes: c8b75bca92cb ("drm/vc4: Add KMS support for Raspberry Pi.") Signed-off-by: Dom Cobley Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210318161328.1471556-3-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 269390bc586e..76657dcdf9b0 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -210,6 +210,7 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format) { const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc); const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); + struct vc4_dev *vc4 = to_vc4_dev(vc4_crtc->base.dev); u32 fifo_len_bytes = pv_data->fifo_depth; /* @@ -238,6 +239,22 @@ static u32 vc4_get_fifo_full_level(struct vc4_crtc *vc4_crtc, u32 format) if (crtc_data->hvs_output == 5) return 32; + /* + * It looks like in some situations, we will overflow + * the PixelValve FIFO (with the bit 10 of PV stat being + * set) and stall the HVS / PV, eventually resulting in + * a page flip timeout. + * + * Displaying the video overlay during a playback with + * Kodi on an RPi3 seems to be a great solution with a + * failure rate around 50%. + * + * Removing 1 from the FIFO full level however + * seems to completely remove that issue. + */ + if (!vc4->hvs->hvs5) + return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1; + return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX; } }