From 16d06d58cfbe8b61ebd8a53289a9b714d4aa6c46 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 22 Apr 2013 09:59:18 -0700 Subject: [PATCH] 3.4-stable patches added patches: fbcon-fix-locking-harder.patch --- queue-3.4/fbcon-fix-locking-harder.patch | 141 +++++++++++++++++++++++ queue-3.4/series | 1 + 2 files changed, 142 insertions(+) create mode 100644 queue-3.4/fbcon-fix-locking-harder.patch diff --git a/queue-3.4/fbcon-fix-locking-harder.patch b/queue-3.4/fbcon-fix-locking-harder.patch new file mode 100644 index 00000000000..463c68f6b57 --- /dev/null +++ b/queue-3.4/fbcon-fix-locking-harder.patch @@ -0,0 +1,141 @@ +From 054430e773c9a1e26f38e30156eff02dedfffc17 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Fri, 25 Jan 2013 11:38:56 +1000 +Subject: fbcon: fix locking harder + +From: Dave Airlie + +commit 054430e773c9a1e26f38e30156eff02dedfffc17 upstream. + +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 +Tested-by: Lu Hua +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/vga/vga_switcheroo.c | 3 +++ + drivers/video/console/fbcon.c | 11 ++++++++--- + drivers/video/fbmem.c | 2 ++ + 3 files changed, 13 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/vga/vga_switcheroo.c ++++ b/drivers/gpu/vga/vga_switcheroo.c +@@ -26,6 +26,7 @@ + #include + + #include ++#include + #include + + struct vga_switcheroo_client { +@@ -256,8 +257,10 @@ static int vga_switchto_stage2(struct vg + + if (new_client->fb_info) { + struct fb_event event; ++ console_lock(); + event.info = new_client->fb_info; + fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); ++ console_unlock(); + } + + ret = vgasr_priv.handler->switchto(new_client->id); +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -842,6 +842,8 @@ static void con2fb_init_display(struct v + * + * Maps a virtual console @unit to a frame buffer device + * @newidx. ++ * ++ * This should be called with the console lock held. + */ + static int set_con2fb_map(int unit, int newidx, int user) + { +@@ -859,7 +861,7 @@ static int set_con2fb_map(int unit, int + + if (!search_for_mapped_con() || !con_is_bound(&fb_con)) { + info_idx = newidx; +- return fbcon_takeover(0); ++ return do_fbcon_takeover(0); + } + + if (oldidx != -1) +@@ -867,7 +869,6 @@ static int set_con2fb_map(int unit, int + + found = search_fb_in_map(newidx); + +- console_lock(); + con2fb_map[unit] = newidx; + if (!err && !found) + err = con2fb_acquire_newinfo(vc, info, unit, oldidx); +@@ -894,7 +895,6 @@ static int set_con2fb_map(int unit, int + if (!search_fb_in_map(info_idx)) + info_idx = newidx; + +- console_unlock(); + return err; + } + +@@ -3025,6 +3025,7 @@ static inline int fbcon_unbind(void) + } + #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ + ++/* called with console_lock held */ + static int fbcon_fb_unbind(int idx) + { + int i, new_idx = -1, ret = 0; +@@ -3051,6 +3052,7 @@ static int fbcon_fb_unbind(int idx) + return ret; + } + ++/* called with console_lock held */ + static int fbcon_fb_unregistered(struct fb_info *info) + { + int i, idx; +@@ -3088,6 +3090,7 @@ static int fbcon_fb_unregistered(struct + return 0; + } + ++/* called with console_lock held */ + static void fbcon_remap_all(int idx) + { + int i; +@@ -3132,6 +3135,7 @@ static inline void fbcon_select_primary( + } + #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ + ++/* called with console_lock held */ + static int fbcon_fb_registered(struct fb_info *info) + { + int ret = 0, i, idx; +@@ -3284,6 +3288,7 @@ static int fbcon_event_notify(struct not + ret = fbcon_fb_unregistered(info); + break; + case FB_EVENT_SET_CONSOLE_MAP: ++ /* called with console lock held */ + con2fb = event->data; + ret = set_con2fb_map(con2fb->console - 1, + con2fb->framebuffer, 1); +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1168,8 +1168,10 @@ static long do_fb_ioctl(struct fb_info * + event.data = &con2fb; + if (!lock_fb_info(info)) + return -ENODEV; ++ console_lock(); + event.info = info; + ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); ++ console_unlock(); + unlock_fb_info(info); + break; + case FBIOBLANK: diff --git a/queue-3.4/series b/queue-3.4/series index a49ca563dd1..729becb5317 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -17,3 +17,4 @@ ssb-implement-spurious-tone-avoidance.patch crypto-algif-suppress-sending-source-address-information.patch perf-treat-attr.config-as-u64-in-perf_swevent_init.patch perf-x86-fix-offcore_rsp-valid-mask-for-snb-ivb.patch +fbcon-fix-locking-harder.patch -- 2.47.3