From: Sasha Levin Date: Tue, 1 Sep 2020 03:02:44 +0000 (-0400) Subject: Fixes for 5.8 X-Git-Tag: v4.4.235~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4feb43a790d4a4ee92bf83cecf1227179bc5500d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.8 Signed-off-by: Sasha Levin --- diff --git a/queue-5.8/drm-atomic-helper-reset-vblank-on-crtc-reset.patch b/queue-5.8/drm-atomic-helper-reset-vblank-on-crtc-reset.patch new file mode 100644 index 00000000000..2f4e022eda7 --- /dev/null +++ b/queue-5.8/drm-atomic-helper-reset-vblank-on-crtc-reset.patch @@ -0,0 +1,333 @@ +From fd269bb55f86a50546bfcff27eeb587823753d59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Jun 2020 18:00:49 +0200 +Subject: drm/atomic-helper: reset vblank on crtc reset + +From: Daniel Vetter + +[ Upstream commit 51f644b40b4b794b28b982fdd5d0dd8ee63f9272 ] + +Only when vblanks are supported ofc. + +Some drivers do this already, but most unfortunately missed it. This +opens up bugs after driver load, before the crtc is enabled for the +first time. syzbot spotted this when loading vkms as a secondary +output. Given how many drivers are buggy it's best to solve this once +and for all in shared helper code. + +Aside from moving the few existing calls to drm_crtc_vblank_reset into +helpers (i915 doesn't use helpers, so keeps its own) I think the +regression risk is minimal: atomic helpers already rely on drivers +calling drm_crtc_vblank_on/off correctly in their hooks when they +support vblanks. And driver that's failing to handle vblanks after +this is missing those calls already, and vblanks could only work by +accident when enabling a CRTC for the first time right after boot. + +Big thanks to Tetsuo for helping track down what's going wrong here. + +There's only a few drivers which already had the necessary call and +needed some updating: +- komeda, atmel and tidss also needed to be changed to call + __drm_atomic_helper_crtc_reset() intead of open coding it +- tegra and msm even had it in the same place already, just code + motion, and malidp already uses __drm_atomic_helper_crtc_reset(). +- Laurent noticed that rcar-du and omap open-code their crtc reset and + hence would actually be broken by this patch now. So fix them up by + reusing the helpers, which brings the drm_crtc_vblank_reset() back. + +Only call left is in i915, which doesn't use drm_mode_config_reset, +but has its own fastboot infrastructure. So that's the only case where +we actually want this in the driver still. + +I've also reviewed all other drivers which set up vblank support with +drm_vblank_init. After the previous patch fixing mxsfb all atomic +drivers do call drm_crtc_vblank_on/off as they should, the remaining +drivers are either legacy kms or legacy dri1 drivers, so not affected +by this change to atomic helpers. + +v2: Use the drm_dev_has_vblank() helper. + +v3: Laurent pointed out that omap and rcar-du used drm_crtc_vblank_off +instead of drm_crtc_vblank_reset. Adjust them too. + +v4: Laurent noticed that rcar-du and omap open-code their crtc reset +and hence would actually be broken by this patch now. So fix them up +by reusing the helpers, which brings the drm_crtc_vblank_reset() back. + +v5: also mention rcar-du and ompadrm in the proper commit message +above (Laurent). + +Reviewed-by: Laurent Pinchart +Acked-by: Maxime Ripard +Cc: Laurent Pinchart +Reviewed-by: Boris Brezillon +Acked-by: Liviu Dudau +Acked-by: Thierry Reding +Link: https://syzkaller.appspot.com/bug?id=0ba17d70d062b2595e1f061231474800f076c7cb +Reported-by: Tetsuo Handa +Reported-by: syzbot+0871b14ca2e2fb64f6e3@syzkaller.appspotmail.com +Cc: Tetsuo Handa +Cc: "James (Qian) Wang" +Cc: Liviu Dudau +Cc: Mihail Atanassov +Cc: Brian Starkey +Cc: Sam Ravnborg +Cc: Boris Brezillon +Cc: Nicolas Ferre +Cc: Alexandre Belloni +Cc: Ludovic Desroches +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: Thomas Zimmermann +Cc: David Airlie +Cc: Daniel Vetter +Cc: Thierry Reding +Cc: Jonathan Hunter +Cc: Jyri Sarha +Cc: Tomi Valkeinen +Cc: Rob Clark +Cc: Sean Paul +Cc: Brian Masney +Cc: Emil Velikov +Cc: zhengbin +Cc: Thomas Gleixner +Cc: linux-tegra@vger.kernel.org +Cc: Kieran Bingham +Cc: linux-arm-kernel@lists.infradead.org +Cc: linux-renesas-soc@vger.kernel.org +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20200612160056.2082681-1-daniel.vetter@ffwll.ch +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 7 ++----- + drivers/gpu/drm/arm/malidp_drv.c | 1 - + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 7 ++----- + drivers/gpu/drm/drm_atomic_state_helper.c | 4 ++++ + drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 2 -- + drivers/gpu/drm/omapdrm/omap_crtc.c | 8 +++++--- + drivers/gpu/drm/omapdrm/omap_drv.c | 4 ---- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 6 +----- + drivers/gpu/drm/tegra/dc.c | 1 - + drivers/gpu/drm/tidss/tidss_crtc.c | 3 +-- + drivers/gpu/drm/tidss/tidss_kms.c | 5 ----- + 11 files changed, 15 insertions(+), 33 deletions(-) + +diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +index 56bd938961eee..f33418d6e1a08 100644 +--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +@@ -492,10 +492,8 @@ static void komeda_crtc_reset(struct drm_crtc *crtc) + crtc->state = NULL; + + state = kzalloc(sizeof(*state), GFP_KERNEL); +- if (state) { +- crtc->state = &state->base; +- crtc->state->crtc = crtc; +- } ++ if (state) ++ __drm_atomic_helper_crtc_reset(crtc, &state->base); + } + + static struct drm_crtc_state * +@@ -616,7 +614,6 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms, + return err; + + drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs); +- drm_crtc_vblank_reset(crtc); + + crtc->port = kcrtc->master->of_output_port; + +diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c +index def8c9ffafcaf..a2a10bfbccac4 100644 +--- a/drivers/gpu/drm/arm/malidp_drv.c ++++ b/drivers/gpu/drm/arm/malidp_drv.c +@@ -870,7 +870,6 @@ static int malidp_bind(struct device *dev) + drm->irq_enabled = true; + + ret = drm_vblank_init(drm, drm->mode_config.num_crtc); +- drm_crtc_vblank_reset(&malidp->crtc); + if (ret < 0) { + DRM_ERROR("failed to initialise vblank\n"); + goto vblank_fail; +diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +index 10985134ce0ba..ce246b96330b7 100644 +--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c ++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +@@ -411,10 +411,8 @@ static void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) + } + + state = kzalloc(sizeof(*state), GFP_KERNEL); +- if (state) { +- crtc->state = &state->base; +- crtc->state->crtc = crtc; +- } ++ if (state) ++ __drm_atomic_helper_crtc_reset(crtc, &state->base); + } + + static struct drm_crtc_state * +@@ -528,7 +526,6 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev) + } + + drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); +- drm_crtc_vblank_reset(&crtc->base); + + drm_mode_crtc_set_gamma_size(&crtc->base, ATMEL_HLCDC_CLUT_SIZE); + drm_crtc_enable_color_mgmt(&crtc->base, 0, false, +diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c +index 8fce6a115dfe3..9ad74045158ec 100644 +--- a/drivers/gpu/drm/drm_atomic_state_helper.c ++++ b/drivers/gpu/drm/drm_atomic_state_helper.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -93,6 +94,9 @@ __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, + if (crtc_state) + __drm_atomic_helper_crtc_state_reset(crtc_state, crtc); + ++ if (drm_dev_has_vblank(crtc->dev)) ++ drm_crtc_vblank_reset(crtc); ++ + crtc->state = crtc_state; + } + EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset); +diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +index b5fed67c4651f..0c54b7bc19010 100644 +--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c ++++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +@@ -1117,8 +1117,6 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc) + mdp5_crtc_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); +- +- drm_crtc_vblank_reset(crtc); + } + + static const struct drm_crtc_funcs mdp5_crtc_funcs = { +diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c +index fce7e944a280b..6d40914675dad 100644 +--- a/drivers/gpu/drm/omapdrm/omap_crtc.c ++++ b/drivers/gpu/drm/omapdrm/omap_crtc.c +@@ -697,14 +697,16 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, + + static void omap_crtc_reset(struct drm_crtc *crtc) + { ++ struct omap_crtc_state *state; ++ + if (crtc->state) + __drm_atomic_helper_crtc_destroy_state(crtc->state); + + kfree(crtc->state); +- crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL); + +- if (crtc->state) +- crtc->state->crtc = crtc; ++ state = kzalloc(sizeof(*state), GFP_KERNEL); ++ if (state) ++ __drm_atomic_helper_crtc_reset(crtc, &state->base); + } + + static struct drm_crtc_state * +diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c +index cdafd7ef1c320..cc4d754ff8c02 100644 +--- a/drivers/gpu/drm/omapdrm/omap_drv.c ++++ b/drivers/gpu/drm/omapdrm/omap_drv.c +@@ -595,7 +595,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) + { + const struct soc_device_attribute *soc; + struct drm_device *ddev; +- unsigned int i; + int ret; + + DBG("%s", dev_name(dev)); +@@ -642,9 +641,6 @@ static int omapdrm_init(struct omap_drm_private *priv, struct device *dev) + goto err_cleanup_modeset; + } + +- for (i = 0; i < priv->num_pipes; i++) +- drm_crtc_vblank_off(priv->pipes[i].crtc); +- + omap_fbdev_init(ddev); + + drm_kms_helper_poll_init(ddev); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index d73e88ddecd0f..fe86a3e677571 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -975,8 +975,7 @@ static void rcar_du_crtc_reset(struct drm_crtc *crtc) + state->crc.source = VSP1_DU_CRC_NONE; + state->crc.index = 0; + +- crtc->state = &state->state; +- crtc->state->crtc = crtc; ++ __drm_atomic_helper_crtc_reset(crtc, &state->state); + } + + static int rcar_du_crtc_enable_vblank(struct drm_crtc *crtc) +@@ -1271,9 +1270,6 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex, + + drm_crtc_helper_add(crtc, &crtc_helper_funcs); + +- /* Start with vertical blanking interrupt reporting disabled. */ +- drm_crtc_vblank_off(crtc); +- + /* Register the interrupt handler. */ + if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { + /* The IRQ's are associated with the CRTC (sw)index. */ +diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c +index 04d6848d19fcf..da8b9983b7de0 100644 +--- a/drivers/gpu/drm/tegra/dc.c ++++ b/drivers/gpu/drm/tegra/dc.c +@@ -1169,7 +1169,6 @@ static void tegra_crtc_reset(struct drm_crtc *crtc) + tegra_crtc_atomic_destroy_state(crtc, crtc->state); + + __drm_atomic_helper_crtc_reset(crtc, &state->base); +- drm_crtc_vblank_reset(crtc); + } + + static struct drm_crtc_state * +diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c +index 89a226912de85..4d01c4af61cd0 100644 +--- a/drivers/gpu/drm/tidss/tidss_crtc.c ++++ b/drivers/gpu/drm/tidss/tidss_crtc.c +@@ -352,8 +352,7 @@ static void tidss_crtc_reset(struct drm_crtc *crtc) + return; + } + +- crtc->state = &tcrtc->base; +- crtc->state->crtc = crtc; ++ __drm_atomic_helper_crtc_reset(crtc, &tcrtc->base); + } + + static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc) +diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c +index c0240f7e0b198..eec359f61a06d 100644 +--- a/drivers/gpu/drm/tidss/tidss_kms.c ++++ b/drivers/gpu/drm/tidss/tidss_kms.c +@@ -253,7 +253,6 @@ static int tidss_dispc_modeset_init(struct tidss_device *tidss) + int tidss_modeset_init(struct tidss_device *tidss) + { + struct drm_device *ddev = &tidss->ddev; +- unsigned int i; + int ret; + + dev_dbg(tidss->dev, "%s\n", __func__); +@@ -278,10 +277,6 @@ int tidss_modeset_init(struct tidss_device *tidss) + if (ret) + return ret; + +- /* Start with vertical blanking interrupt reporting disabled. */ +- for (i = 0; i < tidss->num_crtcs; ++i) +- drm_crtc_vblank_reset(tidss->crtcs[i]); +- + drm_mode_config_reset(ddev); + + dev_dbg(tidss->dev, "%s done\n", __func__); +-- +2.25.1 + diff --git a/queue-5.8/fbmem-pull-fbcon_update_vcs-out-of-fb_set_var.patch b/queue-5.8/fbmem-pull-fbcon_update_vcs-out-of-fb_set_var.patch new file mode 100644 index 00000000000..944416d2537 --- /dev/null +++ b/queue-5.8/fbmem-pull-fbcon_update_vcs-out-of-fb_set_var.patch @@ -0,0 +1,133 @@ +From e1b6d7f87082551d7c0b89ffed8ace71cc30842e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jul 2020 19:47:14 +0900 +Subject: fbmem: pull fbcon_update_vcs() out of fb_set_var() + +From: Tetsuo Handa + +[ Upstream commit d88ca7e1a27eb2df056bbf37ddef62e1c73d37ea ] + +syzbot is reporting OOB read bug in vc_do_resize() [1] caused by memcpy() +based on outdated old_{rows,row_size} values, for resize_screen() can +recurse into vc_do_resize() which changes vc->vc_{cols,rows} that outdates +old_{rows,row_size} values which were saved before calling resize_screen(). + +Daniel Vetter explained that resize_screen() should not recurse into +fbcon_update_vcs() path due to FBINFO_MISC_USEREVENT being still set +when calling resize_screen(). + +Instead of masking FBINFO_MISC_USEREVENT before calling fbcon_update_vcs(), +we can remove FBINFO_MISC_USEREVENT by calling fbcon_update_vcs() only if +fb_set_var() returned 0. This change assumes that it is harmless to call +fbcon_update_vcs() when fb_set_var() returned 0 without reaching +fb_notifier_call_chain(). + +[1] https://syzkaller.appspot.com/bug?id=c70c88cfd16dcf6e1d3c7f0ab8648b3144b5b25e + +Reported-and-tested-by: syzbot +Suggested-by: Daniel Vetter +Signed-off-by: Tetsuo Handa +Reported-by: kernel test robot for missing #include +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/075b7e37-3278-cd7d-31ab-c5073cfa8e92@i-love.sakura.ne.jp +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/core/fbmem.c | 8 ++------ + drivers/video/fbdev/core/fbsysfs.c | 4 ++-- + drivers/video/fbdev/ps3fb.c | 5 +++-- + include/linux/fb.h | 2 -- + 4 files changed, 7 insertions(+), 12 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index 30e73ec4ad5c8..da7c88ffaa6a8 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -957,7 +957,6 @@ static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, + int + fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) + { +- int flags = info->flags; + int ret = 0; + u32 activate; + struct fb_var_screeninfo old_var; +@@ -1052,9 +1051,6 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) + event.data = &mode; + fb_notifier_call_chain(FB_EVENT_MODE_CHANGE, &event); + +- if (flags & FBINFO_MISC_USEREVENT) +- fbcon_update_vcs(info, activate & FB_ACTIVATE_ALL); +- + return 0; + } + EXPORT_SYMBOL(fb_set_var); +@@ -1105,9 +1101,9 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + return -EFAULT; + console_lock(); + lock_fb_info(info); +- info->flags |= FBINFO_MISC_USEREVENT; + ret = fb_set_var(info, &var); +- info->flags &= ~FBINFO_MISC_USEREVENT; ++ if (!ret) ++ fbcon_update_vcs(info, var.activate & FB_ACTIVATE_ALL); + unlock_fb_info(info); + console_unlock(); + if (!ret && copy_to_user(argp, &var, sizeof(var))) +diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c +index d54c88f88991d..65dae05fff8e6 100644 +--- a/drivers/video/fbdev/core/fbsysfs.c ++++ b/drivers/video/fbdev/core/fbsysfs.c +@@ -91,9 +91,9 @@ static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var) + + var->activate |= FB_ACTIVATE_FORCE; + console_lock(); +- fb_info->flags |= FBINFO_MISC_USEREVENT; + err = fb_set_var(fb_info, var); +- fb_info->flags &= ~FBINFO_MISC_USEREVENT; ++ if (!err) ++ fbcon_update_vcs(fb_info, var->activate & FB_ACTIVATE_ALL); + console_unlock(); + if (err) + return err; +diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c +index 9df78fb772672..203c254f8f6cb 100644 +--- a/drivers/video/fbdev/ps3fb.c ++++ b/drivers/video/fbdev/ps3fb.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -824,12 +825,12 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, + var = info->var; + fb_videomode_to_var(&var, vmode); + console_lock(); +- info->flags |= FBINFO_MISC_USEREVENT; + /* Force, in case only special bits changed */ + var.activate |= FB_ACTIVATE_FORCE; + par->new_mode_id = val; + retval = fb_set_var(info, &var); +- info->flags &= ~FBINFO_MISC_USEREVENT; ++ if (!retval) ++ fbcon_update_vcs(info, var.activate & FB_ACTIVATE_ALL); + console_unlock(); + } + break; +diff --git a/include/linux/fb.h b/include/linux/fb.h +index 3b4b2f0c6994d..b11eb02cad6d3 100644 +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -400,8 +400,6 @@ struct fb_tile_ops { + #define FBINFO_HWACCEL_YPAN 0x2000 /* optional */ + #define FBINFO_HWACCEL_YWRAP 0x4000 /* optional */ + +-#define FBINFO_MISC_USEREVENT 0x10000 /* event request +- from userspace */ + #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ + + /* A driver may set this flag to indicate that it does want a set_par to be +-- +2.25.1 + diff --git a/queue-5.8/series b/queue-5.8/series index 43674b353e0..378e6045fdd 100644 --- a/queue-5.8/series +++ b/queue-5.8/series @@ -243,3 +243,5 @@ usb-typec-tcpm-fix-fix-source-hard-reset-response-for-tda-2.3.1.1-and-tda-2.3.1. io_uring-don-t-recurse-on-tsk-sighand-siglock-with-s.patch io_uring-don-t-use-poll-handler-if-file-can-t-be-non.patch io_uring-make-offset-1-consistent-with-preadv2-pwrit.patch +drm-atomic-helper-reset-vblank-on-crtc-reset.patch +fbmem-pull-fbcon_update_vcs-out-of-fb_set_var.patch