[Nouveau] [PATCH] fbcon: Disable accelerated scrolling

Sam Ravnborg
Wed, 28 Oct 2020 18:50:29 -0000

Hi Daniel.

On Wed, Oct 28, 2020 at 05:06:00PM +0100, Daniel Vetter
wrote:
> So ever since syzbot discovered fbcon, we have solid proof that it's
> full of bugs. And often the solution is to just delete code and remove
> features, e.g.  50145474f6ef ("fbcon: remove soft scrollback
code").
>
> Now the problem is that most modern-ish drivers really only treat
> fbcon as an dumb kernel console until userspace takes over, and Oops
> printer for some emergencies. Looking at drm drivers and the basic
> vesa/efi fbdev drivers shows that only 3 drivers support any kind of
> acceleration:
>
> - nouveau, seems to be enabled by default
> - omapdrm, when a DMM remapper exists using remapper rewriting for
>   y/xpanning
> - gma500, but that is getting deleted now for the GTT remapper trick,
>   and the accelerated copyarea never set the FBINFO_HWACCEL_COPYAREA
>   flag, so unused (and could be deleted already I think).
>
> No other driver supportes accelerated fbcon. And fbcon is the only
> user of this accel code (it's not exposed as uapi through ioctls),
> which means we could garbage collect fairly enormous amounts of code
> if we kill this.
>
> Plus because syzbot only runs on virtual hardware, and none of the
> drivers for that have acceleration, we'd remove a huge gap in testing.
> And there's no other even remotely comprehensive testing aside from
> syzbot.
>
> This patch here just disables the acceleration code by always
> redrawing when scrolling. The plan is that once this has been merged
> for well over a year in released kernels, we can start to go around
> and delete a lot of code.

See below for a warning fix.

Some figures from trying to toss accel code out from a few fbdev drivers:

 drivers/video/fbdev/cirrusfb.c | 300 +----------------------------------------
 1 file changed, 4 insertions(+), 296 deletions(-)

 drivers/video/fbdev/aty/radeon_accel.c | 174 ---------------------------------
 drivers/video/fbdev/aty/radeon_base.c  |  43 ++------
 drivers/video/fbdev/aty/radeon_pm.c    |   7 --
 drivers/video/fbdev/aty/radeonfb.h     |   3 -
 4 files changed, 7 insertions(+), 220 deletions(-)

This may open up the discussion if the right course of action would be
to drop the drivers in favour of drm counterparts - but thats another
story.

	Sam

> @@ -1961,7 +1963,6 @@ static void updatescrollmode(struct fbcon_display *p,
>  {
>  	struct fbcon_ops *ops = info->fbcon_par;
>  	int fh = vc->vc_font.height;
> -	int cap = info->flags;
>  	u16 t = 0;
>  	int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
>  				  info->fix.xpanstep);
> @@ -1969,37 +1970,12 @@ static void updatescrollmode(struct fbcon_display
*p,
>  	int yres = FBCON_SWAP(ops->rotate, info->var.yres,
info->var.xres);
>  	int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
>  				   info->var.xres_virtual);
> -	int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
> -		divides(ypan, vc->vc_font.height) && vyres > yres;
> -	int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
> -		divides(ywrap, vc->vc_font.height) &&
> -		divides(vc->vc_font.height, vyres) &&
> -		divides(vc->vc_font.height, yres);
> -	int reading_fast = cap & FBINFO_READS_FAST;
> -	int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
> -		!(cap & FBINFO_HWACCEL_DISABLED);
> -	int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
> -		!(cap & FBINFO_HWACCEL_DISABLED);

Some bot will likely tell you that this causes warnings.
At least it did in my sparc64 build.

Fix:

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 398914e035e9..e8b009c621d8 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -2150,10 +2150,6 @@ static void updatescrollmode(struct fbcon_display *p,
 {
 	struct fbcon_ops *ops = info->fbcon_par;
 	int fh = vc->vc_font.height;
-	u16 t = 0;
-	int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
-				  info->fix.xpanstep);
-	int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
 	int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
 	int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
 				   info->var.xres_virtual);