diff options
author | Alan Cox <alan@linux.intel.com> | 2012-03-02 09:59:20 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-08 14:10:27 -0500 |
commit | 4001d7b7fc271052ebff43f327c26dc64806bbdf (patch) | |
tree | 0ed1daaf95b5e1e7ce73589b4b25e88ac0b60461 | |
parent | edab558feba1e2826ae8d65506168d7ccea7aad9 (diff) |
vt: push down the tty lock so we can see what is left to tackle
At this point we have the tty_lock guarding a couple of oddities, plus the
translation and unimap still.
We also extend the console_lock in a couple of spots where coverage is wrong
and switch vcs_open to use the right lock !
[Fixed the locking issue Jiri reported]
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/tty/vt/vc_screen.c | 4 | ||||
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 92 |
2 files changed, 59 insertions, 37 deletions
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 7a367ff5122b..fa7268a93c06 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c | |||
@@ -608,10 +608,10 @@ vcs_open(struct inode *inode, struct file *filp) | |||
608 | unsigned int currcons = iminor(inode) & 127; | 608 | unsigned int currcons = iminor(inode) & 127; |
609 | int ret = 0; | 609 | int ret = 0; |
610 | 610 | ||
611 | tty_lock(); | 611 | console_lock(); |
612 | if(currcons && !vc_cons_allocated(currcons-1)) | 612 | if(currcons && !vc_cons_allocated(currcons-1)) |
613 | ret = -ENXIO; | 613 | ret = -ENXIO; |
614 | tty_unlock(); | 614 | console_unlock(); |
615 | return ret; | 615 | return ret; |
616 | } | 616 | } |
617 | 617 | ||
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 28ca0aa8664f..e05094d76344 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
@@ -281,7 +281,6 @@ int vt_ioctl(struct tty_struct *tty, | |||
281 | 281 | ||
282 | console = vc->vc_num; | 282 | console = vc->vc_num; |
283 | 283 | ||
284 | tty_lock(); | ||
285 | 284 | ||
286 | if (!vc_cons_allocated(console)) { /* impossible? */ | 285 | if (!vc_cons_allocated(console)) { /* impossible? */ |
287 | ret = -ENOIOCTLCMD; | 286 | ret = -ENOIOCTLCMD; |
@@ -299,16 +298,18 @@ int vt_ioctl(struct tty_struct *tty, | |||
299 | 298 | ||
300 | switch (cmd) { | 299 | switch (cmd) { |
301 | case TIOCLINUX: | 300 | case TIOCLINUX: |
301 | tty_lock(); | ||
302 | ret = tioclinux(tty, arg); | 302 | ret = tioclinux(tty, arg); |
303 | tty_unlock(); | ||
303 | break; | 304 | break; |
304 | case KIOCSOUND: | 305 | case KIOCSOUND: |
305 | if (!perm) | 306 | if (!perm) |
306 | goto eperm; | 307 | return -EPERM; |
307 | /* | 308 | /* |
308 | * The use of PIT_TICK_RATE is historic, it used to be | 309 | * The use of PIT_TICK_RATE is historic, it used to be |
309 | * the platform-dependent CLOCK_TICK_RATE between 2.6.12 | 310 | * the platform-dependent CLOCK_TICK_RATE between 2.6.12 |
310 | * and 2.6.36, which was a minor but unfortunate ABI | 311 | * and 2.6.36, which was a minor but unfortunate ABI |
311 | * change. | 312 | * change. kd_mksound is locked by the input layer. |
312 | */ | 313 | */ |
313 | if (arg) | 314 | if (arg) |
314 | arg = PIT_TICK_RATE / arg; | 315 | arg = PIT_TICK_RATE / arg; |
@@ -317,7 +318,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
317 | 318 | ||
318 | case KDMKTONE: | 319 | case KDMKTONE: |
319 | if (!perm) | 320 | if (!perm) |
320 | goto eperm; | 321 | return -EPERM; |
321 | { | 322 | { |
322 | unsigned int ticks, count; | 323 | unsigned int ticks, count; |
323 | 324 | ||
@@ -335,7 +336,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
335 | 336 | ||
336 | case KDGKBTYPE: | 337 | case KDGKBTYPE: |
337 | /* | 338 | /* |
338 | * this is naive. | 339 | * this is naïve. |
339 | */ | 340 | */ |
340 | ucval = KB_101; | 341 | ucval = KB_101; |
341 | ret = put_user(ucval, (char __user *)arg); | 342 | ret = put_user(ucval, (char __user *)arg); |
@@ -353,6 +354,8 @@ int vt_ioctl(struct tty_struct *tty, | |||
353 | /* | 354 | /* |
354 | * KDADDIO and KDDELIO may be able to add ports beyond what | 355 | * KDADDIO and KDDELIO may be able to add ports beyond what |
355 | * we reject here, but to be safe... | 356 | * we reject here, but to be safe... |
357 | * | ||
358 | * These are locked internally via sys_ioperm | ||
356 | */ | 359 | */ |
357 | if (arg < GPFIRST || arg > GPLAST) { | 360 | if (arg < GPFIRST || arg > GPLAST) { |
358 | ret = -EINVAL; | 361 | ret = -EINVAL; |
@@ -375,7 +378,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
375 | struct kbd_repeat kbrep; | 378 | struct kbd_repeat kbrep; |
376 | 379 | ||
377 | if (!capable(CAP_SYS_TTY_CONFIG)) | 380 | if (!capable(CAP_SYS_TTY_CONFIG)) |
378 | goto eperm; | 381 | return -EPERM; |
379 | 382 | ||
380 | if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { | 383 | if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) { |
381 | ret = -EFAULT; | 384 | ret = -EFAULT; |
@@ -399,7 +402,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
399 | * need to restore their engine state. --BenH | 402 | * need to restore their engine state. --BenH |
400 | */ | 403 | */ |
401 | if (!perm) | 404 | if (!perm) |
402 | goto eperm; | 405 | return -EPERM; |
403 | switch (arg) { | 406 | switch (arg) { |
404 | case KD_GRAPHICS: | 407 | case KD_GRAPHICS: |
405 | break; | 408 | break; |
@@ -412,6 +415,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
412 | ret = -EINVAL; | 415 | ret = -EINVAL; |
413 | goto out; | 416 | goto out; |
414 | } | 417 | } |
418 | /* FIXME: this needs the console lock extending */ | ||
415 | if (vc->vc_mode == (unsigned char) arg) | 419 | if (vc->vc_mode == (unsigned char) arg) |
416 | break; | 420 | break; |
417 | vc->vc_mode = (unsigned char) arg; | 421 | vc->vc_mode = (unsigned char) arg; |
@@ -443,7 +447,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
443 | 447 | ||
444 | case KDSKBMODE: | 448 | case KDSKBMODE: |
445 | if (!perm) | 449 | if (!perm) |
446 | goto eperm; | 450 | return -EPERM; |
447 | ret = vt_do_kdskbmode(console, arg); | 451 | ret = vt_do_kdskbmode(console, arg); |
448 | if (ret == 0) | 452 | if (ret == 0) |
449 | tty_ldisc_flush(tty); | 453 | tty_ldisc_flush(tty); |
@@ -512,7 +516,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
512 | case KDSIGACCEPT: | 516 | case KDSIGACCEPT: |
513 | { | 517 | { |
514 | if (!perm || !capable(CAP_KILL)) | 518 | if (!perm || !capable(CAP_KILL)) |
515 | goto eperm; | 519 | return -EPERM; |
516 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) | 520 | if (!valid_signal(arg) || arg < 1 || arg == SIGKILL) |
517 | ret = -EINVAL; | 521 | ret = -EINVAL; |
518 | else { | 522 | else { |
@@ -530,7 +534,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
530 | struct vt_mode tmp; | 534 | struct vt_mode tmp; |
531 | 535 | ||
532 | if (!perm) | 536 | if (!perm) |
533 | goto eperm; | 537 | return -EPERM; |
534 | if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { | 538 | if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) { |
535 | ret = -EFAULT; | 539 | ret = -EFAULT; |
536 | goto out; | 540 | goto out; |
@@ -576,6 +580,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
576 | struct vt_stat __user *vtstat = up; | 580 | struct vt_stat __user *vtstat = up; |
577 | unsigned short state, mask; | 581 | unsigned short state, mask; |
578 | 582 | ||
583 | /* Review: FIXME: Console lock ? */ | ||
579 | if (put_user(fg_console + 1, &vtstat->v_active)) | 584 | if (put_user(fg_console + 1, &vtstat->v_active)) |
580 | ret = -EFAULT; | 585 | ret = -EFAULT; |
581 | else { | 586 | else { |
@@ -593,6 +598,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
593 | * Returns the first available (non-opened) console. | 598 | * Returns the first available (non-opened) console. |
594 | */ | 599 | */ |
595 | case VT_OPENQRY: | 600 | case VT_OPENQRY: |
601 | /* FIXME: locking ? - but then this is a stupid API */ | ||
596 | for (i = 0; i < MAX_NR_CONSOLES; ++i) | 602 | for (i = 0; i < MAX_NR_CONSOLES; ++i) |
597 | if (! VT_IS_IN_USE(i)) | 603 | if (! VT_IS_IN_USE(i)) |
598 | break; | 604 | break; |
@@ -606,7 +612,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
606 | */ | 612 | */ |
607 | case VT_ACTIVATE: | 613 | case VT_ACTIVATE: |
608 | if (!perm) | 614 | if (!perm) |
609 | goto eperm; | 615 | return -EPERM; |
610 | if (arg == 0 || arg > MAX_NR_CONSOLES) | 616 | if (arg == 0 || arg > MAX_NR_CONSOLES) |
611 | ret = -ENXIO; | 617 | ret = -ENXIO; |
612 | else { | 618 | else { |
@@ -625,7 +631,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
625 | struct vt_setactivate vsa; | 631 | struct vt_setactivate vsa; |
626 | 632 | ||
627 | if (!perm) | 633 | if (!perm) |
628 | goto eperm; | 634 | return -EPERM; |
629 | 635 | ||
630 | if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, | 636 | if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, |
631 | sizeof(struct vt_setactivate))) { | 637 | sizeof(struct vt_setactivate))) { |
@@ -653,6 +659,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
653 | if (ret) | 659 | if (ret) |
654 | break; | 660 | break; |
655 | /* Commence switch and lock */ | 661 | /* Commence switch and lock */ |
662 | /* Review set_console locks */ | ||
656 | set_console(vsa.console); | 663 | set_console(vsa.console); |
657 | } | 664 | } |
658 | break; | 665 | break; |
@@ -663,11 +670,14 @@ int vt_ioctl(struct tty_struct *tty, | |||
663 | */ | 670 | */ |
664 | case VT_WAITACTIVE: | 671 | case VT_WAITACTIVE: |
665 | if (!perm) | 672 | if (!perm) |
666 | goto eperm; | 673 | return -EPERM; |
667 | if (arg == 0 || arg > MAX_NR_CONSOLES) | 674 | if (arg == 0 || arg > MAX_NR_CONSOLES) |
668 | ret = -ENXIO; | 675 | ret = -ENXIO; |
669 | else | 676 | else { |
677 | tty_lock(); | ||
670 | ret = vt_waitactive(arg); | 678 | ret = vt_waitactive(arg); |
679 | tty_unlock(); | ||
680 | } | ||
671 | break; | 681 | break; |
672 | 682 | ||
673 | /* | 683 | /* |
@@ -682,16 +692,17 @@ int vt_ioctl(struct tty_struct *tty, | |||
682 | */ | 692 | */ |
683 | case VT_RELDISP: | 693 | case VT_RELDISP: |
684 | if (!perm) | 694 | if (!perm) |
685 | goto eperm; | 695 | return -EPERM; |
686 | 696 | ||
697 | console_lock(); | ||
687 | if (vc->vt_mode.mode != VT_PROCESS) { | 698 | if (vc->vt_mode.mode != VT_PROCESS) { |
699 | console_unlock(); | ||
688 | ret = -EINVAL; | 700 | ret = -EINVAL; |
689 | break; | 701 | break; |
690 | } | 702 | } |
691 | /* | 703 | /* |
692 | * Switching-from response | 704 | * Switching-from response |
693 | */ | 705 | */ |
694 | console_lock(); | ||
695 | if (vc->vt_newvt >= 0) { | 706 | if (vc->vt_newvt >= 0) { |
696 | if (arg == 0) | 707 | if (arg == 0) |
697 | /* | 708 | /* |
@@ -768,7 +779,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
768 | 779 | ||
769 | ushort ll,cc; | 780 | ushort ll,cc; |
770 | if (!perm) | 781 | if (!perm) |
771 | goto eperm; | 782 | return -EPERM; |
772 | if (get_user(ll, &vtsizes->v_rows) || | 783 | if (get_user(ll, &vtsizes->v_rows) || |
773 | get_user(cc, &vtsizes->v_cols)) | 784 | get_user(cc, &vtsizes->v_cols)) |
774 | ret = -EFAULT; | 785 | ret = -EFAULT; |
@@ -779,6 +790,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
779 | 790 | ||
780 | if (vc) { | 791 | if (vc) { |
781 | vc->vc_resize_user = 1; | 792 | vc->vc_resize_user = 1; |
793 | /* FIXME: review v tty lock */ | ||
782 | vc_resize(vc_cons[i].d, cc, ll); | 794 | vc_resize(vc_cons[i].d, cc, ll); |
783 | } | 795 | } |
784 | } | 796 | } |
@@ -792,7 +804,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
792 | struct vt_consize __user *vtconsize = up; | 804 | struct vt_consize __user *vtconsize = up; |
793 | ushort ll,cc,vlin,clin,vcol,ccol; | 805 | ushort ll,cc,vlin,clin,vcol,ccol; |
794 | if (!perm) | 806 | if (!perm) |
795 | goto eperm; | 807 | return -EPERM; |
796 | if (!access_ok(VERIFY_READ, vtconsize, | 808 | if (!access_ok(VERIFY_READ, vtconsize, |
797 | sizeof(struct vt_consize))) { | 809 | sizeof(struct vt_consize))) { |
798 | ret = -EFAULT; | 810 | ret = -EFAULT; |
@@ -848,7 +860,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
848 | 860 | ||
849 | case PIO_FONT: { | 861 | case PIO_FONT: { |
850 | if (!perm) | 862 | if (!perm) |
851 | goto eperm; | 863 | return -EPERM; |
852 | op.op = KD_FONT_OP_SET; | 864 | op.op = KD_FONT_OP_SET; |
853 | op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ | 865 | op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */ |
854 | op.width = 8; | 866 | op.width = 8; |
@@ -889,7 +901,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
889 | case PIO_FONTRESET: | 901 | case PIO_FONTRESET: |
890 | { | 902 | { |
891 | if (!perm) | 903 | if (!perm) |
892 | goto eperm; | 904 | return -EPERM; |
893 | 905 | ||
894 | #ifdef BROKEN_GRAPHICS_PROGRAMS | 906 | #ifdef BROKEN_GRAPHICS_PROGRAMS |
895 | /* With BROKEN_GRAPHICS_PROGRAMS defined, the default | 907 | /* With BROKEN_GRAPHICS_PROGRAMS defined, the default |
@@ -915,7 +927,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
915 | break; | 927 | break; |
916 | } | 928 | } |
917 | if (!perm && op.op != KD_FONT_OP_GET) | 929 | if (!perm && op.op != KD_FONT_OP_GET) |
918 | goto eperm; | 930 | return -EPERM; |
919 | ret = con_font_op(vc, &op); | 931 | ret = con_font_op(vc, &op); |
920 | if (ret) | 932 | if (ret) |
921 | break; | 933 | break; |
@@ -927,50 +939,65 @@ int vt_ioctl(struct tty_struct *tty, | |||
927 | case PIO_SCRNMAP: | 939 | case PIO_SCRNMAP: |
928 | if (!perm) | 940 | if (!perm) |
929 | ret = -EPERM; | 941 | ret = -EPERM; |
930 | else | 942 | else { |
943 | tty_lock(); | ||
931 | ret = con_set_trans_old(up); | 944 | ret = con_set_trans_old(up); |
945 | tty_unlock(); | ||
946 | } | ||
932 | break; | 947 | break; |
933 | 948 | ||
934 | case GIO_SCRNMAP: | 949 | case GIO_SCRNMAP: |
950 | tty_lock(); | ||
935 | ret = con_get_trans_old(up); | 951 | ret = con_get_trans_old(up); |
952 | tty_unlock(); | ||
936 | break; | 953 | break; |
937 | 954 | ||
938 | case PIO_UNISCRNMAP: | 955 | case PIO_UNISCRNMAP: |
939 | if (!perm) | 956 | if (!perm) |
940 | ret = -EPERM; | 957 | ret = -EPERM; |
941 | else | 958 | else { |
959 | tty_lock(); | ||
942 | ret = con_set_trans_new(up); | 960 | ret = con_set_trans_new(up); |
961 | tty_unlock(); | ||
962 | } | ||
943 | break; | 963 | break; |
944 | 964 | ||
945 | case GIO_UNISCRNMAP: | 965 | case GIO_UNISCRNMAP: |
966 | tty_lock(); | ||
946 | ret = con_get_trans_new(up); | 967 | ret = con_get_trans_new(up); |
968 | tty_unlock(); | ||
947 | break; | 969 | break; |
948 | 970 | ||
949 | case PIO_UNIMAPCLR: | 971 | case PIO_UNIMAPCLR: |
950 | { struct unimapinit ui; | 972 | { struct unimapinit ui; |
951 | if (!perm) | 973 | if (!perm) |
952 | goto eperm; | 974 | return -EPERM; |
953 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); | 975 | ret = copy_from_user(&ui, up, sizeof(struct unimapinit)); |
954 | if (ret) | 976 | if (ret) |
955 | ret = -EFAULT; | 977 | ret = -EFAULT; |
956 | else | 978 | else { |
979 | tty_lock(); | ||
957 | con_clear_unimap(vc, &ui); | 980 | con_clear_unimap(vc, &ui); |
981 | tty_unlock(); | ||
982 | } | ||
958 | break; | 983 | break; |
959 | } | 984 | } |
960 | 985 | ||
961 | case PIO_UNIMAP: | 986 | case PIO_UNIMAP: |
962 | case GIO_UNIMAP: | 987 | case GIO_UNIMAP: |
988 | tty_lock(); | ||
963 | ret = do_unimap_ioctl(cmd, up, perm, vc); | 989 | ret = do_unimap_ioctl(cmd, up, perm, vc); |
990 | tty_unlock(); | ||
964 | break; | 991 | break; |
965 | 992 | ||
966 | case VT_LOCKSWITCH: | 993 | case VT_LOCKSWITCH: |
967 | if (!capable(CAP_SYS_TTY_CONFIG)) | 994 | if (!capable(CAP_SYS_TTY_CONFIG)) |
968 | goto eperm; | 995 | return -EPERM; |
969 | vt_dont_switch = 1; | 996 | vt_dont_switch = 1; |
970 | break; | 997 | break; |
971 | case VT_UNLOCKSWITCH: | 998 | case VT_UNLOCKSWITCH: |
972 | if (!capable(CAP_SYS_TTY_CONFIG)) | 999 | if (!capable(CAP_SYS_TTY_CONFIG)) |
973 | goto eperm; | 1000 | return -EPERM; |
974 | vt_dont_switch = 0; | 1001 | vt_dont_switch = 0; |
975 | break; | 1002 | break; |
976 | case VT_GETHIFONTMASK: | 1003 | case VT_GETHIFONTMASK: |
@@ -984,11 +1011,7 @@ int vt_ioctl(struct tty_struct *tty, | |||
984 | ret = -ENOIOCTLCMD; | 1011 | ret = -ENOIOCTLCMD; |
985 | } | 1012 | } |
986 | out: | 1013 | out: |
987 | tty_unlock(); | ||
988 | return ret; | 1014 | return ret; |
989 | eperm: | ||
990 | ret = -EPERM; | ||
991 | goto out; | ||
992 | } | 1015 | } |
993 | 1016 | ||
994 | void reset_vc(struct vc_data *vc) | 1017 | void reset_vc(struct vc_data *vc) |
@@ -1150,8 +1173,6 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
1150 | 1173 | ||
1151 | console = vc->vc_num; | 1174 | console = vc->vc_num; |
1152 | 1175 | ||
1153 | tty_lock(); | ||
1154 | |||
1155 | if (!vc_cons_allocated(console)) { /* impossible? */ | 1176 | if (!vc_cons_allocated(console)) { /* impossible? */ |
1156 | ret = -ENOIOCTLCMD; | 1177 | ret = -ENOIOCTLCMD; |
1157 | goto out; | 1178 | goto out; |
@@ -1180,7 +1201,9 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
1180 | 1201 | ||
1181 | case PIO_UNIMAP: | 1202 | case PIO_UNIMAP: |
1182 | case GIO_UNIMAP: | 1203 | case GIO_UNIMAP: |
1204 | tty_lock(); | ||
1183 | ret = compat_unimap_ioctl(cmd, up, perm, vc); | 1205 | ret = compat_unimap_ioctl(cmd, up, perm, vc); |
1206 | tty_unlock(); | ||
1184 | break; | 1207 | break; |
1185 | 1208 | ||
1186 | /* | 1209 | /* |
@@ -1217,11 +1240,9 @@ long vt_compat_ioctl(struct tty_struct *tty, | |||
1217 | goto fallback; | 1240 | goto fallback; |
1218 | } | 1241 | } |
1219 | out: | 1242 | out: |
1220 | tty_unlock(); | ||
1221 | return ret; | 1243 | return ret; |
1222 | 1244 | ||
1223 | fallback: | 1245 | fallback: |
1224 | tty_unlock(); | ||
1225 | return vt_ioctl(tty, cmd, arg); | 1246 | return vt_ioctl(tty, cmd, arg); |
1226 | } | 1247 | } |
1227 | 1248 | ||
@@ -1407,6 +1428,7 @@ int vt_move_to_console(unsigned int vt, int alloc) | |||
1407 | return -EIO; | 1428 | return -EIO; |
1408 | } | 1429 | } |
1409 | console_unlock(); | 1430 | console_unlock(); |
1431 | /* Review: I don't see why we need tty_lock here FIXME */ | ||
1410 | tty_lock(); | 1432 | tty_lock(); |
1411 | if (vt_waitactive(vt + 1)) { | 1433 | if (vt_waitactive(vt + 1)) { |
1412 | pr_debug("Suspend: Can't switch VCs."); | 1434 | pr_debug("Suspend: Can't switch VCs."); |