Commit 7429799b authored by Ben Hutchings's avatar Ben Hutchings

fbcon: fix locking harder (Closes: #704933)

svn path=/dists/sid/linux/; revision=19975
parent 0f9c18bf
......@@ -67,6 +67,7 @@ linux (3.2.43-1) UNRELEASED; urgency=low
- drm/i915: Don't clobber crtc->fb when queue_flip fails
* [rt] Update to 3.2.42-rt62
* debugfs: Document change of default mode
* fbcon: fix locking harder (Closes: #704933)
-- Ben Hutchings <ben@decadent.org.uk> Wed, 27 Mar 2013 14:10:40 +0000
......
From: Dave Airlie <airlied@gmail.com>
Date: Fri, 25 Jan 2013 11:38:56 +1000
Subject: fbcon: fix locking harder
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 <maarten.lankhorst@canonical.com>
Tested-by: Lu Hua <huax.lu@intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
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 <linux/fb.h>
#include <linux/pci.h>
+#include <linux/console.h>
#include <linux/vga_switcheroo.h>
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
@@ -843,6 +843,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)
{
@@ -860,7 +862,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)
@@ -868,7 +870,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);
@@ -895,7 +896,6 @@ static int set_con2fb_map(int unit, int
if (!search_fb_in_map(info_idx))
info_idx = newidx;
- console_unlock();
return err;
}
@@ -3026,6 +3026,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;
@@ -3052,6 +3053,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;
@@ -3089,6 +3091,7 @@ static int fbcon_fb_unregistered(struct
return 0;
}
+/* called with console_lock held */
static void fbcon_remap_all(int idx)
{
int i;
@@ -3133,6 +3136,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;
@@ -3285,6 +3289,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
@@ -1154,8 +1154,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:
......@@ -630,3 +630,4 @@ features/all/input-mt/Input-cypress_ps2-fix-trackpadi-found-in-Dell-XPS12.patch
debian/skb-avoid-abi-change-in-3.2.42.patch
debian/tracing-avoid-abi-change-in-3.2.42.patch
debian/inet_frag-avoid-abi-change-in-3.2.42.patch
bugfix/all/fbcon-fix-locking-harder.patch
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment