Skip to content

Commit 054430e

Browse files
committed
fbcon: fix locking harder
Okay so Alan's patch handled the case where there was no registered fbcon, however the other path entered in set_con2fb_map pit. In there we called fbcon_takeover, but we also took the console lock in a couple of places. So push the console lock out to the callers of set_con2fb_map, this means fbmem and switcheroo needed to take the lock around the fb notifier entry points that lead to this. This should fix the efifb regression seen by Maarten. Tested-by: Maarten Lankhorst <[email protected]> Tested-by: Lu Hua <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent e93a9a8 commit 054430e

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

drivers/gpu/vga/vga_switcheroo.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/fb.h>
2626

2727
#include <linux/pci.h>
28+
#include <linux/console.h>
2829
#include <linux/vga_switcheroo.h>
2930

3031
#include <linux/vgaarb.h>
@@ -337,8 +338,10 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)
337338

338339
if (new_client->fb_info) {
339340
struct fb_event event;
341+
console_lock();
340342
event.info = new_client->fb_info;
341343
fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
344+
console_unlock();
342345
}
343346

344347
ret = vgasr_priv.handler->switchto(new_client->id);

drivers/video/console/fbcon.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
842842
*
843843
* Maps a virtual console @unit to a frame buffer device
844844
* @newidx.
845+
*
846+
* This should be called with the console lock held.
845847
*/
846848
static int set_con2fb_map(int unit, int newidx, int user)
847849
{
@@ -859,15 +861,14 @@ static int set_con2fb_map(int unit, int newidx, int user)
859861

860862
if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
861863
info_idx = newidx;
862-
return fbcon_takeover(0);
864+
return do_fbcon_takeover(0);
863865
}
864866

865867
if (oldidx != -1)
866868
oldinfo = registered_fb[oldidx];
867869

868870
found = search_fb_in_map(newidx);
869871

870-
console_lock();
871872
con2fb_map[unit] = newidx;
872873
if (!err && !found)
873874
err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -894,7 +895,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
894895
if (!search_fb_in_map(info_idx))
895896
info_idx = newidx;
896897

897-
console_unlock();
898898
return err;
899899
}
900900

@@ -3019,6 +3019,7 @@ static inline int fbcon_unbind(void)
30193019
}
30203020
#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
30213021

3022+
/* called with console_lock held */
30223023
static int fbcon_fb_unbind(int idx)
30233024
{
30243025
int i, new_idx = -1, ret = 0;
@@ -3045,6 +3046,7 @@ static int fbcon_fb_unbind(int idx)
30453046
return ret;
30463047
}
30473048

3049+
/* called with console_lock held */
30483050
static int fbcon_fb_unregistered(struct fb_info *info)
30493051
{
30503052
int i, idx;
@@ -3082,6 +3084,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
30823084
return 0;
30833085
}
30843086

3087+
/* called with console_lock held */
30853088
static void fbcon_remap_all(int idx)
30863089
{
30873090
int i;
@@ -3126,6 +3129,7 @@ static inline void fbcon_select_primary(struct fb_info *info)
31263129
}
31273130
#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
31283131

3132+
/* called with console_lock held */
31293133
static int fbcon_fb_registered(struct fb_info *info)
31303134
{
31313135
int ret = 0, i, idx;
@@ -3278,6 +3282,7 @@ static int fbcon_event_notify(struct notifier_block *self,
32783282
ret = fbcon_fb_unregistered(info);
32793283
break;
32803284
case FB_EVENT_SET_CONSOLE_MAP:
3285+
/* called with console lock held */
32813286
con2fb = event->data;
32823287
ret = set_con2fb_map(con2fb->console - 1,
32833288
con2fb->framebuffer, 1);

drivers/video/fbmem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,8 +1177,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
11771177
event.data = &con2fb;
11781178
if (!lock_fb_info(info))
11791179
return -ENODEV;
1180+
console_lock();
11801181
event.info = info;
11811182
ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
1183+
console_unlock();
11821184
unlock_fb_info(info);
11831185
break;
11841186
case FBIOBLANK:

0 commit comments

Comments
 (0)