aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:53:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:40 -0400
commit04f378b198da233ca0aca341b113dc6579d46123 (patch)
tree696e7bd401125cee71ecaa2047c4273f38732554 /drivers
parente52384426064bca0669a954736206adca7595d48 (diff)
tty: BKL pushdown
- Push the BKL down into the line disciplines - Switch the tty layer to unlocked_ioctl - Introduce a new ctrl_lock spin lock for the control bits - Eliminate much of the lock_kernel use in n_tty - Prepare to (but don't yet) call the drivers with the lock dropped on the paths that historically held the lock BKL now primarily protects open/close/ldisc change in the tty layer [jirislaby@gmail.com: a couple of fixes] Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/n_hdlc.c24
-rw-r--r--drivers/char/n_r3964.c16
-rw-r--r--drivers/char/n_tty.c32
-rw-r--r--drivers/char/pty.c3
-rw-r--r--drivers/char/tty_io.c107
-rw-r--r--drivers/char/tty_ioctl.c6
-rw-r--r--drivers/char/vt.c8
7 files changed, 146 insertions, 50 deletions
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 06803ed5568c..a07c0af4819e 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -578,26 +578,36 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
578 return -EFAULT; 578 return -EFAULT;
579 } 579 }
580 580
581 lock_kernel();
582
581 for (;;) { 583 for (;;) {
582 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) 584 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
585 unlock_kernel();
583 return -EIO; 586 return -EIO;
587 }
584 588
585 n_hdlc = tty2n_hdlc (tty); 589 n_hdlc = tty2n_hdlc (tty);
586 if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || 590 if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
587 tty != n_hdlc->tty) 591 tty != n_hdlc->tty) {
592 unlock_kernel();
588 return 0; 593 return 0;
594 }
589 595
590 rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); 596 rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
591 if (rbuf) 597 if (rbuf)
592 break; 598 break;
593 599
594 /* no data */ 600 /* no data */
595 if (file->f_flags & O_NONBLOCK) 601 if (file->f_flags & O_NONBLOCK) {
602 unlock_kernel();
596 return -EAGAIN; 603 return -EAGAIN;
604 }
597 605
598 interruptible_sleep_on (&tty->read_wait); 606 interruptible_sleep_on (&tty->read_wait);
599 if (signal_pending(current)) 607 if (signal_pending(current)) {
608 unlock_kernel();
600 return -EINTR; 609 return -EINTR;
610 }
601 } 611 }
602 612
603 if (rbuf->count > nr) 613 if (rbuf->count > nr)
@@ -618,7 +628,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
618 kfree(rbuf); 628 kfree(rbuf);
619 else 629 else
620 n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); 630 n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
621 631 unlock_kernel();
622 return ret; 632 return ret;
623 633
624} /* end of n_hdlc_tty_read() */ 634} /* end of n_hdlc_tty_read() */
@@ -661,6 +671,8 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
661 count = maxframe; 671 count = maxframe;
662 } 672 }
663 673
674 lock_kernel();
675
664 add_wait_queue(&tty->write_wait, &wait); 676 add_wait_queue(&tty->write_wait, &wait);
665 set_current_state(TASK_INTERRUPTIBLE); 677 set_current_state(TASK_INTERRUPTIBLE);
666 678
@@ -695,7 +707,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
695 n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); 707 n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
696 n_hdlc_send_frames(n_hdlc,tty); 708 n_hdlc_send_frames(n_hdlc,tty);
697 } 709 }
698 710 unlock_kernel();
699 return error; 711 return error;
700 712
701} /* end of n_hdlc_tty_write() */ 713} /* end of n_hdlc_tty_write() */
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 6b918b80f73e..3f6486e9f1ec 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1075,12 +1075,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1075 1075
1076 TRACE_L("read()"); 1076 TRACE_L("read()");
1077 1077
1078 lock_kernel();
1079
1078 pClient = findClient(pInfo, task_pid(current)); 1080 pClient = findClient(pInfo, task_pid(current));
1079 if (pClient) { 1081 if (pClient) {
1080 pMsg = remove_msg(pInfo, pClient); 1082 pMsg = remove_msg(pInfo, pClient);
1081 if (pMsg == NULL) { 1083 if (pMsg == NULL) {
1082 /* no messages available. */ 1084 /* no messages available. */
1083 if (file->f_flags & O_NONBLOCK) { 1085 if (file->f_flags & O_NONBLOCK) {
1086 unlock_kernel();
1084 return -EAGAIN; 1087 return -EAGAIN;
1085 } 1088 }
1086 /* block until there is a message: */ 1089 /* block until there is a message: */
@@ -1090,8 +1093,10 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1090 1093
1091 /* If we still haven't got a message, we must have been signalled */ 1094 /* If we still haven't got a message, we must have been signalled */
1092 1095
1093 if (!pMsg) 1096 if (!pMsg) {
1097 unlock_kernel();
1094 return -EINTR; 1098 return -EINTR;
1099 }
1095 1100
1096 /* deliver msg to client process: */ 1101 /* deliver msg to client process: */
1097 theMsg.msg_id = pMsg->msg_id; 1102 theMsg.msg_id = pMsg->msg_id;
@@ -1102,12 +1107,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1102 kfree(pMsg); 1107 kfree(pMsg);
1103 TRACE_M("r3964_read - msg kfree %p", pMsg); 1108 TRACE_M("r3964_read - msg kfree %p", pMsg);
1104 1109
1105 if (copy_to_user(buf, &theMsg, count)) 1110 if (copy_to_user(buf, &theMsg, count)) {
1111 unlock_kernel();
1106 return -EFAULT; 1112 return -EFAULT;
1113 }
1107 1114
1108 TRACE_PS("read - return %d", count); 1115 TRACE_PS("read - return %d", count);
1109 return count; 1116 return count;
1110 } 1117 }
1118 unlock_kernel();
1111 return -EPERM; 1119 return -EPERM;
1112} 1120}
1113 1121
@@ -1156,6 +1164,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
1156 pHeader->locks = 0; 1164 pHeader->locks = 0;
1157 pHeader->owner = NULL; 1165 pHeader->owner = NULL;
1158 1166
1167 lock_kernel();
1168
1159 pClient = findClient(pInfo, task_pid(current)); 1169 pClient = findClient(pInfo, task_pid(current));
1160 if (pClient) { 1170 if (pClient) {
1161 pHeader->owner = pClient; 1171 pHeader->owner = pClient;
@@ -1173,6 +1183,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
1173 add_tx_queue(pInfo, pHeader); 1183 add_tx_queue(pInfo, pHeader);
1174 trigger_transmit(pInfo); 1184 trigger_transmit(pInfo);
1175 1185
1186 unlock_kernel();
1187
1176 return 0; 1188 return 0;
1177} 1189}
1178 1190
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 0c09409fa45d..001d9d875387 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -183,22 +183,24 @@ static void reset_buffer_flags(struct tty_struct *tty)
183 * at hangup) or when the N_TTY line discipline internally has to 183 * at hangup) or when the N_TTY line discipline internally has to
184 * clean the pending queue (for example some signals). 184 * clean the pending queue (for example some signals).
185 * 185 *
186 * FIXME: tty->ctrl_status is not spinlocked and relies on 186 * Locking: ctrl_lock
187 * lock_kernel() still.
188 */ 187 */
189 188
190static void n_tty_flush_buffer(struct tty_struct *tty) 189static void n_tty_flush_buffer(struct tty_struct *tty)
191{ 190{
191 unsigned long flags;
192 /* clear everything and unthrottle the driver */ 192 /* clear everything and unthrottle the driver */
193 reset_buffer_flags(tty); 193 reset_buffer_flags(tty);
194 194
195 if (!tty->link) 195 if (!tty->link)
196 return; 196 return;
197 197
198 spin_lock_irqsave(&tty->ctrl_lock, flags);
198 if (tty->link->packet) { 199 if (tty->link->packet) {
199 tty->ctrl_status |= TIOCPKT_FLUSHREAD; 200 tty->ctrl_status |= TIOCPKT_FLUSHREAD;
200 wake_up_interruptible(&tty->link->read_wait); 201 wake_up_interruptible(&tty->link->read_wait);
201 } 202 }
203 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
202} 204}
203 205
204/** 206/**
@@ -264,7 +266,7 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty)
264 * relevant in the world today. If you ever need them, add them here. 266 * relevant in the world today. If you ever need them, add them here.
265 * 267 *
266 * Called from both the receive and transmit sides and can be called 268 * Called from both the receive and transmit sides and can be called
267 * re-entrantly. Relies on lock_kernel() still. 269 * re-entrantly. Relies on lock_kernel() for tty->column state.
268 */ 270 */
269 271
270static int opost(unsigned char c, struct tty_struct *tty) 272static int opost(unsigned char c, struct tty_struct *tty)
@@ -275,6 +277,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
275 if (!space) 277 if (!space)
276 return -1; 278 return -1;
277 279
280 lock_kernel();
278 if (O_OPOST(tty)) { 281 if (O_OPOST(tty)) {
279 switch (c) { 282 switch (c) {
280 case '\n': 283 case '\n':
@@ -323,6 +326,7 @@ static int opost(unsigned char c, struct tty_struct *tty)
323 } 326 }
324 } 327 }
325 tty->driver->put_char(tty, c); 328 tty->driver->put_char(tty, c);
329 unlock_kernel();
326 return 0; 330 return 0;
327} 331}
328 332
@@ -337,7 +341,8 @@ static int opost(unsigned char c, struct tty_struct *tty)
337 * the simple cases normally found and helps to generate blocks of 341 * the simple cases normally found and helps to generate blocks of
338 * symbols for the console driver and thus improve performance. 342 * symbols for the console driver and thus improve performance.
339 * 343 *
340 * Called from write_chan under the tty layer write lock. 344 * Called from write_chan under the tty layer write lock. Relies
345 * on lock_kernel for the tty->column state.
341 */ 346 */
342 347
343static ssize_t opost_block(struct tty_struct *tty, 348static ssize_t opost_block(struct tty_struct *tty,
@@ -353,6 +358,7 @@ static ssize_t opost_block(struct tty_struct *tty,
353 if (nr > space) 358 if (nr > space)
354 nr = space; 359 nr = space;
355 360
361 lock_kernel();
356 for (i = 0, cp = buf; i < nr; i++, cp++) { 362 for (i = 0, cp = buf; i < nr; i++, cp++) {
357 switch (*cp) { 363 switch (*cp) {
358 case '\n': 364 case '\n':
@@ -387,6 +393,7 @@ break_out:
387 if (tty->driver->flush_chars) 393 if (tty->driver->flush_chars)
388 tty->driver->flush_chars(tty); 394 tty->driver->flush_chars(tty);
389 i = tty->driver->write(tty, buf, i); 395 i = tty->driver->write(tty, buf, i);
396 unlock_kernel();
390 return i; 397 return i;
391} 398}
392 399
@@ -1194,6 +1201,11 @@ extern ssize_t redirected_tty_write(struct file *, const char __user *,
1194 * Perform job control management checks on this file/tty descriptor 1201 * Perform job control management checks on this file/tty descriptor
1195 * and if appropriate send any needed signals and return a negative 1202 * and if appropriate send any needed signals and return a negative
1196 * error code if action should be taken. 1203 * error code if action should be taken.
1204 *
1205 * FIXME:
1206 * Locking: None - redirected write test is safe, testing
1207 * current->signal should possibly lock current->sighand
1208 * pgrp locking ?
1197 */ 1209 */
1198 1210
1199static int job_control(struct tty_struct *tty, struct file *file) 1211static int job_control(struct tty_struct *tty, struct file *file)
@@ -1246,6 +1258,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file,
1246 ssize_t size; 1258 ssize_t size;
1247 long timeout; 1259 long timeout;
1248 unsigned long flags; 1260 unsigned long flags;
1261 int packet;
1249 1262
1250do_it_again: 1263do_it_again:
1251 1264
@@ -1289,16 +1302,19 @@ do_it_again:
1289 if (mutex_lock_interruptible(&tty->atomic_read_lock)) 1302 if (mutex_lock_interruptible(&tty->atomic_read_lock))
1290 return -ERESTARTSYS; 1303 return -ERESTARTSYS;
1291 } 1304 }
1305 packet = tty->packet;
1292 1306
1293 add_wait_queue(&tty->read_wait, &wait); 1307 add_wait_queue(&tty->read_wait, &wait);
1294 while (nr) { 1308 while (nr) {
1295 /* First test for status change. */ 1309 /* First test for status change. */
1296 if (tty->packet && tty->link->ctrl_status) { 1310 if (packet && tty->link->ctrl_status) {
1297 unsigned char cs; 1311 unsigned char cs;
1298 if (b != buf) 1312 if (b != buf)
1299 break; 1313 break;
1314 spin_lock_irqsave(&tty->link->ctrl_lock, flags);
1300 cs = tty->link->ctrl_status; 1315 cs = tty->link->ctrl_status;
1301 tty->link->ctrl_status = 0; 1316 tty->link->ctrl_status = 0;
1317 spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
1302 if (tty_put_user(tty, cs, b++)) { 1318 if (tty_put_user(tty, cs, b++)) {
1303 retval = -EFAULT; 1319 retval = -EFAULT;
1304 b--; 1320 b--;
@@ -1333,6 +1349,7 @@ do_it_again:
1333 retval = -ERESTARTSYS; 1349 retval = -ERESTARTSYS;
1334 break; 1350 break;
1335 } 1351 }
1352 /* FIXME: does n_tty_set_room need locking ? */
1336 n_tty_set_room(tty); 1353 n_tty_set_room(tty);
1337 timeout = schedule_timeout(timeout); 1354 timeout = schedule_timeout(timeout);
1338 continue; 1355 continue;
@@ -1340,7 +1357,7 @@ do_it_again:
1340 __set_current_state(TASK_RUNNING); 1357 __set_current_state(TASK_RUNNING);
1341 1358
1342 /* Deal with packet mode. */ 1359 /* Deal with packet mode. */
1343 if (tty->packet && b == buf) { 1360 if (packet && b == buf) {
1344 if (tty_put_user(tty, TIOCPKT_DATA, b++)) { 1361 if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
1345 retval = -EFAULT; 1362 retval = -EFAULT;
1346 b--; 1363 b--;
@@ -1388,6 +1405,8 @@ do_it_again:
1388 break; 1405 break;
1389 } else { 1406 } else {
1390 int uncopied; 1407 int uncopied;
1408 /* The copy function takes the read lock and handles
1409 locking internally for this case */
1391 uncopied = copy_from_read_buf(tty, &b, &nr); 1410 uncopied = copy_from_read_buf(tty, &b, &nr);
1392 uncopied += copy_from_read_buf(tty, &b, &nr); 1411 uncopied += copy_from_read_buf(tty, &b, &nr);
1393 if (uncopied) { 1412 if (uncopied) {
@@ -1429,7 +1448,6 @@ do_it_again:
1429 goto do_it_again; 1448 goto do_it_again;
1430 1449
1431 n_tty_set_room(tty); 1450 n_tty_set_room(tty);
1432
1433 return retval; 1451 return retval;
1434} 1452}
1435 1453
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 706ff34728f1..6288356b769d 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -181,6 +181,7 @@ static int pty_set_lock(struct tty_struct *tty, int __user * arg)
181static void pty_flush_buffer(struct tty_struct *tty) 181static void pty_flush_buffer(struct tty_struct *tty)
182{ 182{
183 struct tty_struct *to = tty->link; 183 struct tty_struct *to = tty->link;
184 unsigned long flags;
184 185
185 if (!to) 186 if (!to)
186 return; 187 return;
@@ -189,8 +190,10 @@ static void pty_flush_buffer(struct tty_struct *tty)
189 to->ldisc.flush_buffer(to); 190 to->ldisc.flush_buffer(to);
190 191
191 if (to->packet) { 192 if (to->packet) {
193 spin_lock_irqsave(&tty->ctrl_lock, flags);
192 tty->ctrl_status |= TIOCPKT_FLUSHWRITE; 194 tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
193 wake_up_interruptible(&to->read_wait); 195 wake_up_interruptible(&to->read_wait);
196 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
194 } 197 }
195} 198}
196 199
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 2fa6856706ab..0b0354bc28d6 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -152,8 +152,7 @@ ssize_t redirected_tty_write(struct file *, const char __user *,
152static unsigned int tty_poll(struct file *, poll_table *); 152static unsigned int tty_poll(struct file *, poll_table *);
153static int tty_open(struct inode *, struct file *); 153static int tty_open(struct inode *, struct file *);
154static int tty_release(struct inode *, struct file *); 154static int tty_release(struct inode *, struct file *);
155int tty_ioctl(struct inode *inode, struct file *file, 155long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
156 unsigned int cmd, unsigned long arg);
157#ifdef CONFIG_COMPAT 156#ifdef CONFIG_COMPAT
158static long tty_compat_ioctl(struct file *file, unsigned int cmd, 157static long tty_compat_ioctl(struct file *file, unsigned int cmd,
159 unsigned long arg); 158 unsigned long arg);
@@ -1205,7 +1204,7 @@ EXPORT_SYMBOL_GPL(tty_find_polling_driver);
1205 * not in the foreground, send a SIGTTOU. If the signal is blocked or 1204 * not in the foreground, send a SIGTTOU. If the signal is blocked or
1206 * ignored, go ahead and perform the operation. (POSIX 7.2) 1205 * ignored, go ahead and perform the operation. (POSIX 7.2)
1207 * 1206 *
1208 * Locking: none 1207 * Locking: none - FIXME: review this
1209 */ 1208 */
1210 1209
1211int tty_check_change(struct tty_struct *tty) 1210int tty_check_change(struct tty_struct *tty)
@@ -1247,8 +1246,8 @@ static unsigned int hung_up_tty_poll(struct file *filp, poll_table *wait)
1247 return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM; 1246 return POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDNORM | POLLWRNORM;
1248} 1247}
1249 1248
1250static int hung_up_tty_ioctl(struct inode *inode, struct file *file, 1249static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
1251 unsigned int cmd, unsigned long arg) 1250 unsigned long arg)
1252{ 1251{
1253 return cmd == TIOCSPGRP ? -ENOTTY : -EIO; 1252 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
1254} 1253}
@@ -1264,7 +1263,7 @@ static const struct file_operations tty_fops = {
1264 .read = tty_read, 1263 .read = tty_read,
1265 .write = tty_write, 1264 .write = tty_write,
1266 .poll = tty_poll, 1265 .poll = tty_poll,
1267 .ioctl = tty_ioctl, 1266 .unlocked_ioctl = tty_ioctl,
1268 .compat_ioctl = tty_compat_ioctl, 1267 .compat_ioctl = tty_compat_ioctl,
1269 .open = tty_open, 1268 .open = tty_open,
1270 .release = tty_release, 1269 .release = tty_release,
@@ -1277,7 +1276,7 @@ static const struct file_operations ptmx_fops = {
1277 .read = tty_read, 1276 .read = tty_read,
1278 .write = tty_write, 1277 .write = tty_write,
1279 .poll = tty_poll, 1278 .poll = tty_poll,
1280 .ioctl = tty_ioctl, 1279 .unlocked_ioctl = tty_ioctl,
1281 .compat_ioctl = tty_compat_ioctl, 1280 .compat_ioctl = tty_compat_ioctl,
1282 .open = ptmx_open, 1281 .open = ptmx_open,
1283 .release = tty_release, 1282 .release = tty_release,
@@ -1290,7 +1289,7 @@ static const struct file_operations console_fops = {
1290 .read = tty_read, 1289 .read = tty_read,
1291 .write = redirected_tty_write, 1290 .write = redirected_tty_write,
1292 .poll = tty_poll, 1291 .poll = tty_poll,
1293 .ioctl = tty_ioctl, 1292 .unlocked_ioctl = tty_ioctl,
1294 .compat_ioctl = tty_compat_ioctl, 1293 .compat_ioctl = tty_compat_ioctl,
1295 .open = tty_open, 1294 .open = tty_open,
1296 .release = tty_release, 1295 .release = tty_release,
@@ -1302,7 +1301,7 @@ static const struct file_operations hung_up_tty_fops = {
1302 .read = hung_up_tty_read, 1301 .read = hung_up_tty_read,
1303 .write = hung_up_tty_write, 1302 .write = hung_up_tty_write,
1304 .poll = hung_up_tty_poll, 1303 .poll = hung_up_tty_poll,
1305 .ioctl = hung_up_tty_ioctl, 1304 .unlocked_ioctl = hung_up_tty_ioctl,
1306 .compat_ioctl = hung_up_tty_compat_ioctl, 1305 .compat_ioctl = hung_up_tty_compat_ioctl,
1307 .release = tty_release, 1306 .release = tty_release,
1308}; 1307};
@@ -1626,16 +1625,17 @@ void disassociate_ctty(int on_exit)
1626 struct tty_struct *tty; 1625 struct tty_struct *tty;
1627 struct pid *tty_pgrp = NULL; 1626 struct pid *tty_pgrp = NULL;
1628 1627
1629 lock_kernel();
1630 1628
1631 mutex_lock(&tty_mutex); 1629 mutex_lock(&tty_mutex);
1632 tty = get_current_tty(); 1630 tty = get_current_tty();
1633 if (tty) { 1631 if (tty) {
1634 tty_pgrp = get_pid(tty->pgrp); 1632 tty_pgrp = get_pid(tty->pgrp);
1635 mutex_unlock(&tty_mutex); 1633 mutex_unlock(&tty_mutex);
1634 lock_kernel();
1636 /* XXX: here we race, there is nothing protecting tty */ 1635 /* XXX: here we race, there is nothing protecting tty */
1637 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) 1636 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
1638 tty_vhangup(tty); 1637 tty_vhangup(tty);
1638 unlock_kernel();
1639 } else if (on_exit) { 1639 } else if (on_exit) {
1640 struct pid *old_pgrp; 1640 struct pid *old_pgrp;
1641 spin_lock_irq(&current->sighand->siglock); 1641 spin_lock_irq(&current->sighand->siglock);
@@ -1648,7 +1648,6 @@ void disassociate_ctty(int on_exit)
1648 put_pid(old_pgrp); 1648 put_pid(old_pgrp);
1649 } 1649 }
1650 mutex_unlock(&tty_mutex); 1650 mutex_unlock(&tty_mutex);
1651 unlock_kernel();
1652 return; 1651 return;
1653 } 1652 }
1654 if (tty_pgrp) { 1653 if (tty_pgrp) {
@@ -1683,7 +1682,6 @@ void disassociate_ctty(int on_exit)
1683 read_lock(&tasklist_lock); 1682 read_lock(&tasklist_lock);
1684 session_clear_tty(task_session(current)); 1683 session_clear_tty(task_session(current));
1685 read_unlock(&tasklist_lock); 1684 read_unlock(&tasklist_lock);
1686 unlock_kernel();
1687} 1685}
1688 1686
1689/** 1687/**
@@ -1693,8 +1691,10 @@ void disassociate_ctty(int on_exit)
1693void no_tty(void) 1691void no_tty(void)
1694{ 1692{
1695 struct task_struct *tsk = current; 1693 struct task_struct *tsk = current;
1694 lock_kernel();
1696 if (tsk->signal->leader) 1695 if (tsk->signal->leader)
1697 disassociate_ctty(0); 1696 disassociate_ctty(0);
1697 unlock_kernel();
1698 proc_clear_tty(tsk); 1698 proc_clear_tty(tsk);
1699} 1699}
1700 1700
@@ -1714,19 +1714,24 @@ void no_tty(void)
1714 * but not always. 1714 * but not always.
1715 * 1715 *
1716 * Locking: 1716 * Locking:
1717 * Broken. Relies on BKL which is unsafe here. 1717 * Uses the tty control lock internally
1718 */ 1718 */
1719 1719
1720void stop_tty(struct tty_struct *tty) 1720void stop_tty(struct tty_struct *tty)
1721{ 1721{
1722 if (tty->stopped) 1722 unsigned long flags;
1723 spin_lock_irqsave(&tty->ctrl_lock, flags);
1724 if (tty->stopped) {
1725 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1723 return; 1726 return;
1727 }
1724 tty->stopped = 1; 1728 tty->stopped = 1;
1725 if (tty->link && tty->link->packet) { 1729 if (tty->link && tty->link->packet) {
1726 tty->ctrl_status &= ~TIOCPKT_START; 1730 tty->ctrl_status &= ~TIOCPKT_START;
1727 tty->ctrl_status |= TIOCPKT_STOP; 1731 tty->ctrl_status |= TIOCPKT_STOP;
1728 wake_up_interruptible(&tty->link->read_wait); 1732 wake_up_interruptible(&tty->link->read_wait);
1729 } 1733 }
1734 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1730 if (tty->driver->stop) 1735 if (tty->driver->stop)
1731 (tty->driver->stop)(tty); 1736 (tty->driver->stop)(tty);
1732} 1737}
@@ -1743,19 +1748,24 @@ EXPORT_SYMBOL(stop_tty);
1743 * driver start method is invoked and the line discipline woken. 1748 * driver start method is invoked and the line discipline woken.
1744 * 1749 *
1745 * Locking: 1750 * Locking:
1746 * Broken. Relies on BKL which is unsafe here. 1751 * ctrl_lock
1747 */ 1752 */
1748 1753
1749void start_tty(struct tty_struct *tty) 1754void start_tty(struct tty_struct *tty)
1750{ 1755{
1751 if (!tty->stopped || tty->flow_stopped) 1756 unsigned long flags;
1757 spin_lock_irqsave(&tty->ctrl_lock, flags);
1758 if (!tty->stopped || tty->flow_stopped) {
1759 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1752 return; 1760 return;
1761 }
1753 tty->stopped = 0; 1762 tty->stopped = 0;
1754 if (tty->link && tty->link->packet) { 1763 if (tty->link && tty->link->packet) {
1755 tty->ctrl_status &= ~TIOCPKT_STOP; 1764 tty->ctrl_status &= ~TIOCPKT_STOP;
1756 tty->ctrl_status |= TIOCPKT_START; 1765 tty->ctrl_status |= TIOCPKT_START;
1757 wake_up_interruptible(&tty->link->read_wait); 1766 wake_up_interruptible(&tty->link->read_wait);
1758 } 1767 }
1768 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1759 if (tty->driver->start) 1769 if (tty->driver->start)
1760 (tty->driver->start)(tty); 1770 (tty->driver->start)(tty);
1761 /* If we have a running line discipline it may need kicking */ 1771 /* If we have a running line discipline it may need kicking */
@@ -1799,13 +1809,11 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
1799 /* We want to wait for the line discipline to sort out in this 1809 /* We want to wait for the line discipline to sort out in this
1800 situation */ 1810 situation */
1801 ld = tty_ldisc_ref_wait(tty); 1811 ld = tty_ldisc_ref_wait(tty);
1802 lock_kernel();
1803 if (ld->read) 1812 if (ld->read)
1804 i = (ld->read)(tty, file, buf, count); 1813 i = (ld->read)(tty, file, buf, count);
1805 else 1814 else
1806 i = -EIO; 1815 i = -EIO;
1807 tty_ldisc_deref(ld); 1816 tty_ldisc_deref(ld);
1808 unlock_kernel();
1809 if (i > 0) 1817 if (i > 0)
1810 inode->i_atime = current_fs_time(inode->i_sb); 1818 inode->i_atime = current_fs_time(inode->i_sb);
1811 return i; 1819 return i;
@@ -1893,9 +1901,7 @@ static inline ssize_t do_tty_write(
1893 ret = -EFAULT; 1901 ret = -EFAULT;
1894 if (copy_from_user(tty->write_buf, buf, size)) 1902 if (copy_from_user(tty->write_buf, buf, size))
1895 break; 1903 break;
1896 lock_kernel();
1897 ret = write(tty, file, tty->write_buf, size); 1904 ret = write(tty, file, tty->write_buf, size);
1898 unlock_kernel();
1899 if (ret <= 0) 1905 if (ret <= 0)
1900 break; 1906 break;
1901 written += ret; 1907 written += ret;
@@ -3070,10 +3076,13 @@ static int fionbio(struct file *file, int __user *p)
3070 if (get_user(nonblock, p)) 3076 if (get_user(nonblock, p))
3071 return -EFAULT; 3077 return -EFAULT;
3072 3078
3079 /* file->f_flags is still BKL protected in the fs layer - vomit */
3080 lock_kernel();
3073 if (nonblock) 3081 if (nonblock)
3074 file->f_flags |= O_NONBLOCK; 3082 file->f_flags |= O_NONBLOCK;
3075 else 3083 else
3076 file->f_flags &= ~O_NONBLOCK; 3084 file->f_flags &= ~O_NONBLOCK;
3085 unlock_kernel();
3077 return 0; 3086 return 0;
3078} 3087}
3079 3088
@@ -3162,7 +3171,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
3162 * Set the process group of the tty to the session passed. Only 3171 * Set the process group of the tty to the session passed. Only
3163 * permitted where the tty session is our session. 3172 * permitted where the tty session is our session.
3164 * 3173 *
3165 * Locking: None 3174 * Locking: RCU
3166 */ 3175 */
3167 3176
3168static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) 3177static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
@@ -3237,10 +3246,16 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
3237static int tiocsetd(struct tty_struct *tty, int __user *p) 3246static int tiocsetd(struct tty_struct *tty, int __user *p)
3238{ 3247{
3239 int ldisc; 3248 int ldisc;
3249 int ret;
3240 3250
3241 if (get_user(ldisc, p)) 3251 if (get_user(ldisc, p))
3242 return -EFAULT; 3252 return -EFAULT;
3243 return tty_set_ldisc(tty, ldisc); 3253
3254 lock_kernel();
3255 ret = tty_set_ldisc(tty, ldisc);
3256 unlock_kernel();
3257
3258 return ret;
3244} 3259}
3245 3260
3246/** 3261/**
@@ -3258,16 +3273,21 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
3258 3273
3259static int send_break(struct tty_struct *tty, unsigned int duration) 3274static int send_break(struct tty_struct *tty, unsigned int duration)
3260{ 3275{
3276 int retval = -EINTR;
3277
3278 lock_kernel();
3261 if (tty_write_lock(tty, 0) < 0) 3279 if (tty_write_lock(tty, 0) < 0)
3262 return -EINTR; 3280 goto out;
3263 tty->driver->break_ctl(tty, -1); 3281 tty->driver->break_ctl(tty, -1);
3264 if (!signal_pending(current)) 3282 if (!signal_pending(current))
3265 msleep_interruptible(duration); 3283 msleep_interruptible(duration);
3266 tty->driver->break_ctl(tty, 0); 3284 tty->driver->break_ctl(tty, 0);
3267 tty_write_unlock(tty); 3285 tty_write_unlock(tty);
3268 if (signal_pending(current)) 3286 if (!signal_pending(current))
3269 return -EINTR; 3287 retval = 0;
3270 return 0; 3288out:
3289 unlock_kernel();
3290 return retval;
3271} 3291}
3272 3292
3273/** 3293/**
@@ -3287,7 +3307,9 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
3287 int retval = -EINVAL; 3307 int retval = -EINVAL;
3288 3308
3289 if (tty->driver->tiocmget) { 3309 if (tty->driver->tiocmget) {
3310 lock_kernel();
3290 retval = tty->driver->tiocmget(tty, file); 3311 retval = tty->driver->tiocmget(tty, file);
3312 unlock_kernel();
3291 3313
3292 if (retval >= 0) 3314 if (retval >= 0)
3293 retval = put_user(retval, p); 3315 retval = put_user(retval, p);
@@ -3337,7 +3359,9 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
3337 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3359 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3338 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3360 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3339 3361
3362 lock_kernel();
3340 retval = tty->driver->tiocmset(tty, file, set, clear); 3363 retval = tty->driver->tiocmset(tty, file, set, clear);
3364 unlock_kernel();
3341 } 3365 }
3342 return retval; 3366 return retval;
3343} 3367}
@@ -3345,20 +3369,18 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int
3345/* 3369/*
3346 * Split this up, as gcc can choke on it otherwise.. 3370 * Split this up, as gcc can choke on it otherwise..
3347 */ 3371 */
3348int tty_ioctl(struct inode *inode, struct file *file, 3372long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3349 unsigned int cmd, unsigned long arg)
3350{ 3373{
3351 struct tty_struct *tty, *real_tty; 3374 struct tty_struct *tty, *real_tty;
3352 void __user *p = (void __user *)arg; 3375 void __user *p = (void __user *)arg;
3353 int retval; 3376 int retval;
3354 struct tty_ldisc *ld; 3377 struct tty_ldisc *ld;
3378 struct inode *inode = file->f_dentry->d_inode;
3355 3379
3356 tty = (struct tty_struct *)file->private_data; 3380 tty = (struct tty_struct *)file->private_data;
3357 if (tty_paranoia_check(tty, inode, "tty_ioctl")) 3381 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
3358 return -EINVAL; 3382 return -EINVAL;
3359 3383
3360 /* CHECKME: is this safe as one end closes ? */
3361
3362 real_tty = tty; 3384 real_tty = tty;
3363 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 3385 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
3364 tty->driver->subtype == PTY_TYPE_MASTER) 3386 tty->driver->subtype == PTY_TYPE_MASTER)
@@ -3367,13 +3389,19 @@ int tty_ioctl(struct inode *inode, struct file *file,
3367 /* 3389 /*
3368 * Break handling by driver 3390 * Break handling by driver
3369 */ 3391 */
3392
3393 retval = -EINVAL;
3394
3370 if (!tty->driver->break_ctl) { 3395 if (!tty->driver->break_ctl) {
3371 switch (cmd) { 3396 switch (cmd) {
3372 case TIOCSBRK: 3397 case TIOCSBRK:
3373 case TIOCCBRK: 3398 case TIOCCBRK:
3374 if (tty->driver->ioctl) 3399 if (tty->driver->ioctl) {
3375 return tty->driver->ioctl(tty, file, cmd, arg); 3400 lock_kernel();
3376 return -EINVAL; 3401 retval = tty->driver->ioctl(tty, file, cmd, arg);
3402 unlock_kernel();
3403 }
3404 return retval;
3377 3405
3378 /* These two ioctl's always return success; even if */ 3406 /* These two ioctl's always return success; even if */
3379 /* the driver doesn't support them. */ 3407 /* the driver doesn't support them. */
@@ -3381,7 +3409,9 @@ int tty_ioctl(struct inode *inode, struct file *file,
3381 case TCSBRKP: 3409 case TCSBRKP:
3382 if (!tty->driver->ioctl) 3410 if (!tty->driver->ioctl)
3383 return 0; 3411 return 0;
3412 lock_kernel();
3384 retval = tty->driver->ioctl(tty, file, cmd, arg); 3413 retval = tty->driver->ioctl(tty, file, cmd, arg);
3414 unlock_kernel();
3385 if (retval == -ENOIOCTLCMD) 3415 if (retval == -ENOIOCTLCMD)
3386 retval = 0; 3416 retval = 0;
3387 return retval; 3417 return retval;
@@ -3401,7 +3431,9 @@ int tty_ioctl(struct inode *inode, struct file *file,
3401 if (retval) 3431 if (retval)
3402 return retval; 3432 return retval;
3403 if (cmd != TIOCCBRK) { 3433 if (cmd != TIOCCBRK) {
3434 lock_kernel();
3404 tty_wait_until_sent(tty, 0); 3435 tty_wait_until_sent(tty, 0);
3436 unlock_kernel();
3405 if (signal_pending(current)) 3437 if (signal_pending(current))
3406 return -EINTR; 3438 return -EINTR;
3407 } 3439 }
@@ -3451,11 +3483,15 @@ int tty_ioctl(struct inode *inode, struct file *file,
3451 * Break handling 3483 * Break handling
3452 */ 3484 */
3453 case TIOCSBRK: /* Turn break on, unconditionally */ 3485 case TIOCSBRK: /* Turn break on, unconditionally */
3486 lock_kernel();
3454 tty->driver->break_ctl(tty, -1); 3487 tty->driver->break_ctl(tty, -1);
3488 unlock_kernel();
3455 return 0; 3489 return 0;
3456 3490
3457 case TIOCCBRK: /* Turn break off, unconditionally */ 3491 case TIOCCBRK: /* Turn break off, unconditionally */
3492 lock_kernel();
3458 tty->driver->break_ctl(tty, 0); 3493 tty->driver->break_ctl(tty, 0);
3494 unlock_kernel();
3459 return 0; 3495 return 0;
3460 case TCSBRK: /* SVID version: non-zero arg --> no break */ 3496 case TCSBRK: /* SVID version: non-zero arg --> no break */
3461 /* non-zero arg means wait for all output data 3497 /* non-zero arg means wait for all output data
@@ -3485,14 +3521,18 @@ int tty_ioctl(struct inode *inode, struct file *file,
3485 break; 3521 break;
3486 } 3522 }
3487 if (tty->driver->ioctl) { 3523 if (tty->driver->ioctl) {
3524 lock_kernel();
3488 retval = (tty->driver->ioctl)(tty, file, cmd, arg); 3525 retval = (tty->driver->ioctl)(tty, file, cmd, arg);
3526 unlock_kernel();
3489 if (retval != -ENOIOCTLCMD) 3527 if (retval != -ENOIOCTLCMD)
3490 return retval; 3528 return retval;
3491 } 3529 }
3492 ld = tty_ldisc_ref_wait(tty); 3530 ld = tty_ldisc_ref_wait(tty);
3493 retval = -EINVAL; 3531 retval = -EINVAL;
3494 if (ld->ioctl) { 3532 if (ld->ioctl) {
3533 lock_kernel();
3495 retval = ld->ioctl(tty, file, cmd, arg); 3534 retval = ld->ioctl(tty, file, cmd, arg);
3535 unlock_kernel();
3496 if (retval == -ENOIOCTLCMD) 3536 if (retval == -ENOIOCTLCMD)
3497 retval = -EINVAL; 3537 retval = -EINVAL;
3498 } 3538 }
@@ -3770,6 +3810,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
3770 mutex_init(&tty->atomic_read_lock); 3810 mutex_init(&tty->atomic_read_lock);
3771 mutex_init(&tty->atomic_write_lock); 3811 mutex_init(&tty->atomic_write_lock);
3772 spin_lock_init(&tty->read_lock); 3812 spin_lock_init(&tty->read_lock);
3813 spin_lock_init(&tty->ctrl_lock);
3773 INIT_LIST_HEAD(&tty->tty_files); 3814 INIT_LIST_HEAD(&tty->tty_files);
3774 INIT_WORK(&tty->SAK_work, do_SAK_work); 3815 INIT_WORK(&tty->SAK_work, do_SAK_work);
3775} 3816}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index f95a80b2265f..d6353d89b451 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -395,6 +395,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
395 int canon_change; 395 int canon_change;
396 struct ktermios old_termios = *tty->termios; 396 struct ktermios old_termios = *tty->termios;
397 struct tty_ldisc *ld; 397 struct tty_ldisc *ld;
398 unsigned long flags;
398 399
399 /* 400 /*
400 * Perform the actual termios internal changes under lock. 401 * Perform the actual termios internal changes under lock.
@@ -429,11 +430,13 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
429 STOP_CHAR(tty) == '\023' && 430 STOP_CHAR(tty) == '\023' &&
430 START_CHAR(tty) == '\021'); 431 START_CHAR(tty) == '\021');
431 if (old_flow != new_flow) { 432 if (old_flow != new_flow) {
433 spin_lock_irqsave(&tty->ctrl_lock, flags);
432 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP); 434 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
433 if (new_flow) 435 if (new_flow)
434 tty->ctrl_status |= TIOCPKT_DOSTOP; 436 tty->ctrl_status |= TIOCPKT_DOSTOP;
435 else 437 else
436 tty->ctrl_status |= TIOCPKT_NOSTOP; 438 tty->ctrl_status |= TIOCPKT_NOSTOP;
439 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
437 wake_up_interruptible(&tty->link->read_wait); 440 wake_up_interruptible(&tty->link->read_wait);
438 } 441 }
439 } 442 }
@@ -905,6 +908,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
905 unsigned int cmd, unsigned long arg) 908 unsigned int cmd, unsigned long arg)
906{ 909{
907 struct tty_struct *real_tty; 910 struct tty_struct *real_tty;
911 unsigned long flags;
908 int retval; 912 int retval;
909 913
910 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 914 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
@@ -963,6 +967,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
963 return -ENOTTY; 967 return -ENOTTY;
964 if (get_user(pktmode, (int __user *) arg)) 968 if (get_user(pktmode, (int __user *) arg))
965 return -EFAULT; 969 return -EFAULT;
970 spin_lock_irqsave(&tty->ctrl_lock, flags);
966 if (pktmode) { 971 if (pktmode) {
967 if (!tty->packet) { 972 if (!tty->packet) {
968 tty->packet = 1; 973 tty->packet = 1;
@@ -970,6 +975,7 @@ int n_tty_ioctl(struct tty_struct *tty, struct file *file,
970 } 975 }
971 } else 976 } else
972 tty->packet = 0; 977 tty->packet = 0;
978 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
973 return 0; 979 return 0;
974 } 980 }
975 default: 981 default:
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1c2660477135..e64f0bf3624e 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2541,6 +2541,9 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2541 if (get_user(type, p)) 2541 if (get_user(type, p))
2542 return -EFAULT; 2542 return -EFAULT;
2543 ret = 0; 2543 ret = 0;
2544
2545 lock_kernel();
2546
2544 switch (type) 2547 switch (type)
2545 { 2548 {
2546 case TIOCL_SETSEL: 2549 case TIOCL_SETSEL:
@@ -2560,7 +2563,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2560 ret = sel_loadlut(p); 2563 ret = sel_loadlut(p);
2561 break; 2564 break;
2562 case TIOCL_GETSHIFTSTATE: 2565 case TIOCL_GETSHIFTSTATE:
2563 2566
2564 /* 2567 /*
2565 * Make it possible to react to Shift+Mousebutton. 2568 * Make it possible to react to Shift+Mousebutton.
2566 * Note that 'shift_state' is an undocumented 2569 * Note that 'shift_state' is an undocumented
@@ -2615,6 +2618,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2615 ret = -EINVAL; 2618 ret = -EINVAL;
2616 break; 2619 break;
2617 } 2620 }
2621 unlock_kernel();
2618 return ret; 2622 return ret;
2619} 2623}
2620 2624
@@ -3829,7 +3833,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
3829 goto out; 3833 goto out;
3830 3834
3831 c = (font.width+7)/8 * 32 * font.charcount; 3835 c = (font.width+7)/8 * 32 * font.charcount;
3832 3836
3833 if (op->data && font.charcount > op->charcount) 3837 if (op->data && font.charcount > op->charcount)
3834 rc = -ENOSPC; 3838 rc = -ENOSPC;
3835 if (!(op->flags & KD_FONT_FLAG_OLD)) { 3839 if (!(op->flags & KD_FONT_FLAG_OLD)) {