vt: push down tioclinux cases
Alan Cox [Fri, 2 Mar 2012 14:59:37 +0000 (14:59 +0000)]
Some of this ventures into selection which is still a complete lost cause. We
are not making it any worse. It's completely busted anyway.

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

drivers/tty/vt/selection.c
drivers/tty/vt/vt.c
drivers/tty/vt/vt_ioctl.c

index 738e45a..2a50916 100644 (file)
@@ -75,7 +75,7 @@ clear_selection(void) {
 
 /*
  * User settable table: what characters are to be considered alphabetic?
- * 256 bits
+ * 256 bits. FIXME: Needs a locking model.
  */
 static u32 inwordLut[8]={
   0x00000000, /* control chars     */
@@ -307,7 +307,8 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
  * queue of the tty associated with the current console.
  * Invoked by ioctl().
  *
- * Locking: always called with BTM from vt_ioctl
+ * Locking: called without locks. Calls the ldisc wrongly with
+ * unsafe methods,
  */
 int paste_selection(struct tty_struct *tty)
 {
@@ -322,13 +323,12 @@ int paste_selection(struct tty_struct *tty)
        poke_blanked_console();
        console_unlock();
 
+       /* FIXME: wtf is this supposed to achieve ? */
        ld = tty_ldisc_ref(tty);
-       if (!ld) {
-               tty_unlock();
+       if (!ld)
                ld = tty_ldisc_ref_wait(tty);
-               tty_lock();
-       }
 
+       /* FIXME: this is completely unsafe */
        add_wait_queue(&vc->paste_wait, &wait);
        while (sel_buffer && sel_buffer_lth > pasted) {
                set_current_state(TASK_INTERRUPTIBLE);
index ce2b823..ab7385e 100644 (file)
@@ -2637,11 +2637,15 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
                        ret = __put_user(data, p);
                        break;
                case TIOCL_GETMOUSEREPORTING:
+                       console_lock(); /* May be overkill */
                        data = mouse_reporting();
+                       console_unlock();
                        ret = __put_user(data, p);
                        break;
                case TIOCL_SETVESABLANK:
+                       console_lock();
                        ret = set_vesa_blanking(p);
+                       console_unlock();
                        break;
                case TIOCL_GETKMSGREDIRECT:
                        data = vt_get_kmsg_redirect();
@@ -2658,13 +2662,21 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
                        }
                        break;
                case TIOCL_GETFGCONSOLE:
+                       /* No locking needed as this is a transiently
+                          correct return anyway if the caller hasn't
+                          disabled switching */
                        ret = fg_console;
                        break;
                case TIOCL_SCROLLCONSOLE:
                        if (get_user(lines, (s32 __user *)(p+4))) {
                                ret = -EFAULT;
                        } else {
+                               /* Need the console lock here. Note that lots
+                                  of other calls need fixing before the lock
+                                  is actually useful ! */
+                               console_lock();
                                scrollfront(vc_cons[fg_console].d, lines);
+                               console_unlock();
                                ret = 0;
                        }
                        break;
index e05094d..c6720be 100644 (file)
@@ -298,9 +298,7 @@ int vt_ioctl(struct tty_struct *tty,
  
        switch (cmd) {
        case TIOCLINUX:
-               tty_lock();
                ret = tioclinux(tty, arg);
-               tty_unlock();
                break;
        case KIOCSOUND:
                if (!perm)