Skip to contentSkip to conversation

shield fbdev operations with console semaphore

PATCH New Benjamin Herrenschmidt 1 participant 1 message Feb 15, 2004 Framebuffer layer

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 shield fbdev operations with console semaphore

Hi Andrew !

This patch fixes the fbdev ioctl's and fbcon cursor management with the console semaphore, which is the best we can do at this point in 2.6, thus fixing a bunch of races where we could have, for example, tried to blit while changing mode, etc..

Ben.

# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet

#   2004/02/15 15:39:51+11:00 [email protected] 
#   Shield a bunch of fbdev operations with console semaphore
#   (and small cleanup of timer code)
# 
# drivers/video/fbmem.c
#   2004/02/15 15:36:49+11:00 [email protected] +16 -4
#   Shield a bunch of fbdev operations with console semaphore
#   (and small cleanup of timer code)
# 
# drivers/video/console/fbcon.c
#   2004/02/15 15:36:49+11:00 [email protected] +4 -3
#   Shield a bunch of fbdev operations with console semaphore
#   (and small cleanup of timer code)
# 
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c	Sun Feb 15 17:04:36 2004
+++ b/drivers/video/console/fbcon.c	Sun Feb 15 17:04:36 2004
@@ -198,8 +198,10 @@
 	/* Test to see if the cursor is erased but still on */
 	if (!info || (info->cursor.rop == ROP_COPY))
 		return;
+	acquire_console_sem();
 	info->cursor.enable ^= 1;
 	info->fbops->fb_cursor(info, &info->cursor);
+	release_console_sem();
 }

#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC)
@@ -226,8 +228,7 @@
struct fb_info *info = (struct fb_info *) dev_addr;

schedule_work(&info->queue);
- cursor_timer.expires = jiffies + HZ / 5;
- add_timer(&cursor_timer);
+ mod_timer(&cursor_timer, jiffies + HZ/5);
}

int __init fb_console_setup(char *this_opt)
@@ -676,7 +677,7 @@
if (!info->queue.func) {
INIT_WORK(&info->queue, fb_flashcursor, info);

- cursor_timer.expires = jiffies + HZ / 50;
+ cursor_timer.expires = jiffies + HZ / 5;
cursor_timer.data = (unsigned long ) info; add_timer(&cursor_timer);
}

drivers/video/fbmem.c +16 -4
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/linux_logo.h>
 #include <linux/proc_fs.h>
+#include <linux/console.h>
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
 #endif
@@ -979,7 +980,7 @@
 	struct fb_con2fbmap con2fb;
 #endif
 	struct fb_cmap cmap;
-	int i;
+	int i, rc;
 	
 	if (!fb)
 		return -ENODEV;
@@ -990,7 +991,9 @@
 	case FBIOPUT_VSCREENINFO:
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
+		acquire_console_sem();
 		i = fb_set_var(info, &var);
+		release_console_sem();
 		if (i) return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
@@ -1009,13 +1012,19 @@
 	case FBIOPAN_DISPLAY:
 		if (copy_from_user(&var, (void *) arg, sizeof(var)))
 			return -EFAULT;
-		if ((i = fb_pan_display(info, &var)))
+		acquire_console_sem();
+		i = fb_pan_display(info, &var);
+		release_console_sem();
+		if (i)
 			return i;
 		if (copy_to_user((void *) arg, &var, sizeof(var)))
 			return -EFAULT;
 		return 0;
 	case FBIO_CURSOR:
-		return (fb_cursor(info, (struct fb_cursor *) arg));
+		acquire_console_sem();
+		rc = fb_cursor(info, (struct fb_cursor *) arg);
+		release_console_sem();
+		return rc;
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
 	case FBIOGET_CON2FBMAP:
 		if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
@@ -1045,7 +1054,10 @@
 		return 0;
 #endif	/* CONFIG_FRAMEBUFFER_CONSOLE */
 	case FBIOBLANK:
-		return fb_blank(info, arg);
+		acquire_console_sem();
+		i = fb_blank(info, arg);
+		release_console_sem();
+		return i;
 	default:
 		if (fb->fb_ioctl == NULL)
 			return -EINVAL;