diff options
Diffstat (limited to 'drivers/char/vt_ioctl.c')
-rw-r--r-- | drivers/char/vt_ioctl.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c6f6f4209739..c799b7f7bbb3 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -770,6 +770,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
770 | /* | 770 | /* |
771 | * Switching-from response | 771 | * Switching-from response |
772 | */ | 772 | */ |
773 | acquire_console_sem(); | ||
773 | if (vc->vt_newvt >= 0) { | 774 | if (vc->vt_newvt >= 0) { |
774 | if (arg == 0) | 775 | if (arg == 0) |
775 | /* | 776 | /* |
@@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
784 | * complete the switch. | 785 | * complete the switch. |
785 | */ | 786 | */ |
786 | int newvt; | 787 | int newvt; |
787 | acquire_console_sem(); | ||
788 | newvt = vc->vt_newvt; | 788 | newvt = vc->vt_newvt; |
789 | vc->vt_newvt = -1; | 789 | vc->vt_newvt = -1; |
790 | i = vc_allocate(newvt); | 790 | i = vc_allocate(newvt); |
@@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
798 | * other console switches.. | 798 | * other console switches.. |
799 | */ | 799 | */ |
800 | complete_change_console(vc_cons[newvt].d); | 800 | complete_change_console(vc_cons[newvt].d); |
801 | release_console_sem(); | ||
802 | } | 801 | } |
803 | } | 802 | } |
804 | 803 | ||
@@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
810 | /* | 809 | /* |
811 | * If it's just an ACK, ignore it | 810 | * If it's just an ACK, ignore it |
812 | */ | 811 | */ |
813 | if (arg != VT_ACKACQ) | 812 | if (arg != VT_ACKACQ) { |
813 | release_console_sem(); | ||
814 | return -EINVAL; | 814 | return -EINVAL; |
815 | } | ||
815 | } | 816 | } |
817 | release_console_sem(); | ||
816 | 818 | ||
817 | return 0; | 819 | return 0; |
818 | 820 | ||
@@ -1208,15 +1210,18 @@ void change_console(struct vc_data *new_vc) | |||
1208 | /* | 1210 | /* |
1209 | * Send the signal as privileged - kill_pid() will | 1211 | * Send the signal as privileged - kill_pid() will |
1210 | * tell us if the process has gone or something else | 1212 | * tell us if the process has gone or something else |
1211 | * is awry | 1213 | * is awry. |
1214 | * | ||
1215 | * We need to set vt_newvt *before* sending the signal or we | ||
1216 | * have a race. | ||
1212 | */ | 1217 | */ |
1218 | vc->vt_newvt = new_vc->vc_num; | ||
1213 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { | 1219 | if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) { |
1214 | /* | 1220 | /* |
1215 | * It worked. Mark the vt to switch to and | 1221 | * It worked. Mark the vt to switch to and |
1216 | * return. The process needs to send us a | 1222 | * return. The process needs to send us a |
1217 | * VT_RELDISP ioctl to complete the switch. | 1223 | * VT_RELDISP ioctl to complete the switch. |
1218 | */ | 1224 | */ |
1219 | vc->vt_newvt = new_vc->vc_num; | ||
1220 | return; | 1225 | return; |
1221 | } | 1226 | } |
1222 | 1227 | ||