fbcon: Stop framebuffer operations before hardware is properly initialized
Subsystems (2)
PATCH 2/6 fbcon: Stop framebuffer operations before hardware is properly initialized
Accessing the hardware before it is properly initialized can lead to crashes or screen corruption. This happens when switching to X then back to console. When console comes back from X, the device is in an undefined state. During this window, accessing the hardware is disallowed.
A new field in fbcon_par is added (graphics), which will be set to nonzero just before initialization of the framebuffer and when coming back from KD_GRAPHICS, then unset when an fb_set_var/fb_set_par is done. While this field is set, no accesses to the hardware is done. The consequence of this change is, hopefully, more robust switching between KD_GRAPHICS<-> KD_TEXT.
An added benefit coming from this change is that the MODESWITCHLATE hack is not needed anymore and thus removed. This hack is used by savagefb, rivafb and nvidiafb.
---
drivers/video/console/fbcon.c | 41 ++++++++++++--------------------- drivers/video/console/fbcon.h | 1 drivers/video/nvidia/nvidia.c | 3 +- drivers/video/riva/fbdev.c | 3 -- drivers/video/savage/savagefb_driver.c | 3 -- include/linux/fb.h | 4 --- 6 files changed, 22 insertions(+), 33 deletions(-)
drivers/video/console/fbcon.c +16 -25
@@ -204,8 +204,10 @@static inline int fbcon_is_inactive (struct vc_data *vc,struct fb_info *info) { +struct fbcon_ops *ops = info->fbcon_par; +return (info->state !=FBINFO_STATE_RUNNING || - vc->vc_mode !=KD_TEXT ); + vc->vc_mode !=KD_TEXT || ops->graphics); } static inline int get_color(struct vc_data *vc, struct fb_info *info,
@@ -596,6 +598,8 @@if (info->fbops->fb_set_par) info->fbops->fb_set_par (info); + ops->graphics =0 ; +if (vc)fbcon_set_disp (info, &info->var, vc);else
@@ -763,6 +767,7 @@memset (ops,0 ,sizeof (struct fbcon_ops )); ops->currcon =-1 ; + ops->graphics =1 ; info->fbcon_par = ops;set_blitting_type (vc, info,NULL );
@@ -949,6 +954,7 @@if (CON_IS_VISIBLE (vc) && info->fbops->fb_set_par) info->fbops->fb_set_par (info); + ((struct fbcon_ops *) info->fbcon_par)->graphics =0 ;if ((cap &FBINFO_HWACCEL_COPYAREA ) && !(cap &FBINFO_HWACCEL_DISABLED ))
@@ -1871,7 +1877,6 @@ var.activate =FB_ACTIVATE_NOW |FB_ACTIVATE_FORCE ;fb_set_var (info, &var); - info->flags &= ~FBINFO_MISC_MODESWITCH ; }var_to_display (p, &info->var, info); }
@@ -1884,7 +1889,7 @@struct fb_info *info;struct display *p = &fb_display[vc->vc_num];struct fb_var_screeninfo var; -int i, prev_console, do_set_par =0 ; +int i, prev_console; info = registered_fb[con2fb_map[vc->vc_num]];
@@ -1943,14 +1948,9 @@fb_set_var (info, &var);if (prev_console !=-1 && - registered_fb[con2fb_map[prev_console]] != info) - do_set_par =1 ; - -if (do_set_par || info->flags &FBINFO_MISC_MODESWITCH ) { -if (info->fbops->fb_set_par) - info->fbops->fb_set_par (info); - info->flags &= ~FBINFO_MISC_MODESWITCH ; - } + registered_fb[con2fb_map[prev_console]] != info && + info->fbops->fb_set_par) + info->fbops->fb_set_par (info);set_blitting_type (vc, info, p); ((struct fbcon_ops *)info->fbcon_par)->cursor_reset =1 ;
@@ -2013,29 +2013,20 @@ {struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];struct fbcon_ops *ops = info->fbcon_par; -int active = !fbcon_is_inactive (vc, info);if (mode_switch) {struct fb_var_screeninfo var = info->var; -/* -* HACK ALERT: Some hardware will require reinitializion at this stage, -* others will require it to be done as late as possible. -* For now, we differentiate this with the -* FBINFO_MISC_MODESWITCHLATE bitflag. Worst case will be -* hardware that requires it here and another one later. -* A definitive solution may require fixing X or the VT -* system. -*/ -if (info->flags &FBINFO_MISC_MODESWITCHLATE ) - info->flags |=FBINFO_MISC_MODESWITCH ; -if (!blank && !(info->flags &FBINFO_MISC_MODESWITCHLATE )) { + ops->graphics =1 ; + +if (!blank) { var.activate =FB_ACTIVATE_NOW |FB_ACTIVATE_FORCE ;fb_set_var (info, &var); + ops->graphics =0 ; } } -if (active) { +if (!fbcon_is_inactive (vc, info)) {if (ops->blank_state != blank) { ops->blank_state = blank;fbcon_cursor (vc, blank ?CM_ERASE :CM_DRAW );
drivers/video/console/fbcon.h +1 -0
@@ -67,6 +67,7 @@int cursor_flash;int cursor_reset;int blank_state; +int graphics;char *cursor_data; };/*
drivers/video/nvidia/nvidia.c +2 -1
@@ -1191,6 +1191,7 @@ var->yres_virtual = var->yres; var->xres_virtual = vramlen / var->yres_virtual; var->xres_virtual /= var->bits_per_pixel /8 ; + var->xres_virtual &= ~63 ; pitch = (var->xres_virtual * var->bits_per_pixel +7 ) /8 ; memlen = pitch * var->yres;
@@ -1301,7 +1302,7 @@ | FBINFO_HWACCEL_IMAGEBLIT |FBINFO_HWACCEL_FILLRECT |FBINFO_HWACCEL_COPYAREA - |FBINFO_HWACCEL_YPAN |FBINFO_MISC_MODESWITCHLATE ; + |FBINFO_HWACCEL_YPAN ;fb_videomode_to_modelist (info->monspecs.modedb, info->monspecs.modedb_len, &info->modelist);
drivers/video/riva/fbdev.c +1 -2
@@ -1708,8 +1708,7 @@ | FBINFO_HWACCEL_YPAN |FBINFO_HWACCEL_COPYAREA |FBINFO_HWACCEL_FILLRECT - |FBINFO_HWACCEL_IMAGEBLIT - |FBINFO_MISC_MODESWITCHLATE ; + |FBINFO_HWACCEL_IMAGEBLIT ;/* Accel seems to not work properly on NV30 yet...*/ if ((par->riva.Architecture ==NV_ARCH_30 ) || noaccel) {
drivers/video/savage/savagefb_driver.c +1 -2
@@ -1883,8 +1883,7 @@ info->fbops = &savagefb_ops; info->flags =FBINFO_DEFAULT |FBINFO_HWACCEL_YPAN | -FBINFO_HWACCEL_XPAN | -FBINFO_MISC_MODESWITCHLATE ; +FBINFO_HWACCEL_XPAN ; info->pseudo_palette = par->pseudo_palette;
include/linux/fb.h +1 -3
@@ -702,9 +702,7 @@#define FBINFO_MISC_USEREVENT 0x10000/* event request from userspace */ -#define FBINFO_MISC_MODESWITCH 0x20000/* mode switch */ -#define FBINFO_MISC_MODESWITCHLATE 0x40000/* init hardware later */ -#define FBINFO_MISC_TILEBLITTING 0x80000/* use tile blitting */ +#define FBINFO_MISC_TILEBLITTING 0x20000/* use tile blitting */ struct fb_info {int node;
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
Quoted 12 lines · Antonino A. Daplas
Accessing the hardware before it is properly initialized can lead to crashes or screen corruption. This happens when switching to X then back to console. When console comes back from X, the device is in an undefined state. During this window, accessing the hardware is disallowed.
A new field in
fbcon_paris added (graphics), which will be set to nonzero just before initialization of the framebuffer and when coming back fromKD_GRAPHICS, then unset when an fb_set_var/fb_set_par is done. While this field is set, no accesses to the hardware is done. The consequence of this change is, hopefully, more robust switching between KD_GRAPHICS<->KD_TEXT.
Quoted 3 lines
An added benefit coming from this change is that the MODESWITCHLATE hack is not needed anymore and thus removed. This hack is used by savagefb, rivafb and nvidiafb.
Excellent ! That should fix some nasty issues I've been dealing with as well !
Ben.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click