Commit 2ddce3fd0acbdc1be684fb5f919ae3d2e9518aac
Committed by
Linus Torvalds
1 parent
a690606d1f
Exists in
master
and in
4 other branches
fbcon: only unbind from console if successfully registered
Attempting to unload a framebuffer module calls unregister_framebuffer() which in turn gets fbcon to release it. If fbcon has no framebuffers linked to a console, it will also unbind itself from the console driver. However, if fbcon never registered itself as a console driver, the unbind will fail causing the framebuffer device entry to persist. In most cases this failure will result in an oops when attempting to access the now non-existent device. This patch ensures that the fbcon unbind request will succeed even if a bind was never done. It tracks if a successful bind ever occurred & will only attempt to unbind if needed. If there never was a bind, it simply returns with no error. Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk> Cc: Krzysztof Helt <krzysztof.h1@poczta.fm> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 10 additions and 0 deletions Side-by-side Diff
drivers/video/console/fbcon.c
... | ... | @@ -114,6 +114,7 @@ |
114 | 114 | static int fbcon_is_default = 1; |
115 | 115 | static int fbcon_has_exited; |
116 | 116 | static int primary_device = -1; |
117 | +static int fbcon_has_console_bind; | |
117 | 118 | |
118 | 119 | #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY |
119 | 120 | static int map_override; |
... | ... | @@ -544,6 +545,8 @@ |
544 | 545 | con2fb_map[i] = -1; |
545 | 546 | } |
546 | 547 | info_idx = -1; |
548 | + } else { | |
549 | + fbcon_has_console_bind = 1; | |
547 | 550 | } |
548 | 551 | |
549 | 552 | return err; |
... | ... | @@ -2949,6 +2952,10 @@ |
2949 | 2952 | |
2950 | 2953 | ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, |
2951 | 2954 | fbcon_is_default); |
2955 | + | |
2956 | + if (!ret) | |
2957 | + fbcon_has_console_bind = 0; | |
2958 | + | |
2952 | 2959 | return ret; |
2953 | 2960 | } |
2954 | 2961 | #else |
... | ... | @@ -2961,6 +2968,9 @@ |
2961 | 2968 | static int fbcon_fb_unbind(int idx) |
2962 | 2969 | { |
2963 | 2970 | int i, new_idx = -1, ret = 0; |
2971 | + | |
2972 | + if (!fbcon_has_console_bind) | |
2973 | + return 0; | |
2964 | 2974 | |
2965 | 2975 | for (i = first_fb_vc; i <= last_fb_vc; i++) { |
2966 | 2976 | if (con2fb_map[i] != idx && |