aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbmem.c
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/fbmem.c
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/fbmem.c')
-rw-r--r--drivers/video/fbmem.c11
1 files changed, 1 insertions, 10 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index cfd9dce1ce0b..b64f061dd447 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1086,13 +1086,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
1086 return -EINVAL; 1086 return -EINVAL;
1087 con2fb.framebuffer = -1; 1087 con2fb.framebuffer = -1;
1088 event.data = &con2fb; 1088 event.data = &con2fb;
1089
1090 if (!lock_fb_info(info))
1091 return -ENODEV;
1092 event.info = info; 1089 event.info = info;
1093 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); 1090 fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
1094 unlock_fb_info(info);
1095
1096 ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; 1091 ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
1097 break; 1092 break;
1098 case FBIOPUT_CON2FBMAP: 1093 case FBIOPUT_CON2FBMAP:
@@ -1109,12 +1104,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
1109 break; 1104 break;
1110 } 1105 }
1111 event.data = &con2fb; 1106 event.data = &con2fb;
1112 if (!lock_fb_info(info))
1113 return -ENODEV;
1114 event.info = info; 1107 event.info = info;
1115 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, 1108 ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
1116 &event);
1117 unlock_fb_info(info);
1118 break; 1109 break;
1119 case FBIOBLANK: 1110 case FBIOBLANK:
1120 if (!lock_fb_info(info)) 1111 if (!lock_fb_info(info))