aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/backlight
diff options
context:
space:
mode:
authorAndrea Righi <righi.andrea@gmail.com>2009-03-31 18:25:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:29 -0400
commit66c1ca019078220dc1bf968f2bb18421100ef147 (patch)
treeb01d28d74bab9d9e3f0f24841a80a272d6f6520a /drivers/video/backlight
parent8636a9240cc93efa6b36f4cfe6253e0574f832c6 (diff)
fbmem: fix fb_info->lock and mm->mmap_sem circular locking dependency
Fix a circular locking dependency in the frame buffer console driver pushing down the mutex fb_info->lock. Circular locking dependecies occur calling the blocking fb_notifier_call_chain() with fb_info->lock held. Notifier callbacks can try to acquire mm->mmap_sem, while fb_mmap() acquires the locks in the reverse order mm->mmap_sem => fb_info->lock. Tested-by: Andrey Borzenkov <arvidjaar@mail.ru> Signed-off-by: Andrea Righi <righi.andrea@gmail.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> 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>
Diffstat (limited to 'drivers/video/backlight')
-rw-r--r--drivers/video/backlight/backlight.c3
-rw-r--r--drivers/video/backlight/lcd.c3
2 files changed, 6 insertions, 0 deletions
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 157057c79ca3..dd37cbcaf8ce 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -35,6 +35,8 @@ static int fb_notifier_callback(struct notifier_block *self,
35 return 0; 35 return 0;
36 36
37 bd = container_of(self, struct backlight_device, fb_notif); 37 bd = container_of(self, struct backlight_device, fb_notif);
38 if (!lock_fb_info(evdata->info))
39 return -ENODEV;
38 mutex_lock(&bd->ops_lock); 40 mutex_lock(&bd->ops_lock);
39 if (bd->ops) 41 if (bd->ops)
40 if (!bd->ops->check_fb || 42 if (!bd->ops->check_fb ||
@@ -47,6 +49,7 @@ static int fb_notifier_callback(struct notifier_block *self,
47 backlight_update_status(bd); 49 backlight_update_status(bd);
48 } 50 }
49 mutex_unlock(&bd->ops_lock); 51 mutex_unlock(&bd->ops_lock);
52 unlock_fb_info(evdata->info);
50 return 0; 53 return 0;
51} 54}
52 55
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470106c..0bb13df0fa89 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -40,6 +40,8 @@ static int fb_notifier_callback(struct notifier_block *self,
40 if (!ld->ops) 40 if (!ld->ops)
41 return 0; 41 return 0;
42 42
43 if (!lock_fb_info(evdata->info))
44 return -ENODEV;
43 mutex_lock(&ld->ops_lock); 45 mutex_lock(&ld->ops_lock);
44 if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) { 46 if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
45 if (event == FB_EVENT_BLANK) { 47 if (event == FB_EVENT_BLANK) {
@@ -51,6 +53,7 @@ static int fb_notifier_callback(struct notifier_block *self,
51 } 53 }
52 } 54 }
53 mutex_unlock(&ld->ops_lock); 55 mutex_unlock(&ld->ops_lock);
56 unlock_fb_info(evdata->info);
54 return 0; 57 return 0;
55} 58}
56 59