aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/vt_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/vt_ioctl.c')
-rw-r--r--drivers/char/vt_ioctl.c482
1 files changed, 431 insertions, 51 deletions
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 95189f288f8c..29c651ab0d78 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -16,6 +16,8 @@
16#include <linux/tty.h> 16#include <linux/tty.h>
17#include <linux/timer.h> 17#include <linux/timer.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/compat.h>
20#include <linux/module.h>
19#include <linux/kd.h> 21#include <linux/kd.h>
20#include <linux/vt.h> 22#include <linux/vt.h>
21#include <linux/string.h> 23#include <linux/string.h>
@@ -62,6 +64,133 @@ extern struct tty_driver *console_driver;
62static void complete_change_console(struct vc_data *vc); 64static void complete_change_console(struct vc_data *vc);
63 65
64/* 66/*
67 * User space VT_EVENT handlers
68 */
69
70struct vt_event_wait {
71 struct list_head list;
72 struct vt_event event;
73 int done;
74};
75
76static LIST_HEAD(vt_events);
77static DEFINE_SPINLOCK(vt_event_lock);
78static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
79
80/**
81 * vt_event_post
82 * @event: the event that occurred
83 * @old: old console
84 * @new: new console
85 *
86 * Post an VT event to interested VT handlers
87 */
88
89void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
90{
91 struct list_head *pos, *head;
92 unsigned long flags;
93 int wake = 0;
94
95 spin_lock_irqsave(&vt_event_lock, flags);
96 head = &vt_events;
97
98 list_for_each(pos, head) {
99 struct vt_event_wait *ve = list_entry(pos,
100 struct vt_event_wait, list);
101 if (!(ve->event.event & event))
102 continue;
103 ve->event.event = event;
104 /* kernel view is consoles 0..n-1, user space view is
105 console 1..n with 0 meaning current, so we must bias */
106 ve->event.old = old + 1;
107 ve->event.new = new + 1;
108 wake = 1;
109 ve->done = 1;
110 }
111 spin_unlock_irqrestore(&vt_event_lock, flags);
112 if (wake)
113 wake_up_interruptible(&vt_event_waitqueue);
114}
115
116/**
117 * vt_event_wait - wait for an event
118 * @vw: our event
119 *
120 * Waits for an event to occur which completes our vt_event_wait
121 * structure. On return the structure has wv->done set to 1 for success
122 * or 0 if some event such as a signal ended the wait.
123 */
124
125static void vt_event_wait(struct vt_event_wait *vw)
126{
127 unsigned long flags;
128 /* Prepare the event */
129 INIT_LIST_HEAD(&vw->list);
130 vw->done = 0;
131 /* Queue our event */
132 spin_lock_irqsave(&vt_event_lock, flags);
133 list_add(&vw->list, &vt_events);
134 spin_unlock_irqrestore(&vt_event_lock, flags);
135 /* Wait for it to pass */
136 wait_event_interruptible(vt_event_waitqueue, vw->done);
137 /* Dequeue it */
138 spin_lock_irqsave(&vt_event_lock, flags);
139 list_del(&vw->list);
140 spin_unlock_irqrestore(&vt_event_lock, flags);
141}
142
143/**
144 * vt_event_wait_ioctl - event ioctl handler
145 * @arg: argument to ioctl
146 *
147 * Implement the VT_WAITEVENT ioctl using the VT event interface
148 */
149
150static int vt_event_wait_ioctl(struct vt_event __user *event)
151{
152 struct vt_event_wait vw;
153
154 if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
155 return -EFAULT;
156 /* Highest supported event for now */
157 if (vw.event.event & ~VT_MAX_EVENT)
158 return -EINVAL;
159
160 vt_event_wait(&vw);
161 /* If it occurred report it */
162 if (vw.done) {
163 if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
164 return -EFAULT;
165 return 0;
166 }
167 return -EINTR;
168}
169
170/**
171 * vt_waitactive - active console wait
172 * @event: event code
173 * @n: new console
174 *
175 * Helper for event waits. Used to implement the legacy
176 * event waiting ioctls in terms of events
177 */
178
179int vt_waitactive(int n)
180{
181 struct vt_event_wait vw;
182 do {
183 if (n == fg_console + 1)
184 break;
185 vw.event.event = VT_EVENT_SWITCH;
186 vt_event_wait(&vw);
187 if (vw.done == 0)
188 return -EINTR;
189 } while (vw.event.new != n);
190 return 0;
191}
192
193/*
65 * these are the valid i/o ports we're allowed to change. they map all the 194 * these are the valid i/o ports we're allowed to change. they map all the
66 * video ports 195 * video ports
67 */ 196 */
@@ -360,6 +489,8 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_
360 return 0; 489 return 0;
361} 490}
362 491
492
493
363/* 494/*
364 * We handle the console-specific ioctl's here. We allow the 495 * We handle the console-specific ioctl's here. We allow the
365 * capability to modify any console, not just the fg_console. 496 * capability to modify any console, not just the fg_console.
@@ -842,6 +973,41 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
842 } 973 }
843 break; 974 break;
844 975
976 case VT_SETACTIVATE:
977 {
978 struct vt_setactivate vsa;
979
980 if (!perm)
981 goto eperm;
982
983 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
984 sizeof(struct vt_setactivate)))
985 return -EFAULT;
986 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
987 ret = -ENXIO;
988 else {
989 vsa.console--;
990 acquire_console_sem();
991 ret = vc_allocate(vsa.console);
992 if (ret == 0) {
993 struct vc_data *nvc;
994 /* This is safe providing we don't drop the
995 console sem between vc_allocate and
996 finishing referencing nvc */
997 nvc = vc_cons[vsa.console].d;
998 nvc->vt_mode = vsa.mode;
999 nvc->vt_mode.frsig = 0;
1000 put_pid(nvc->vt_pid);
1001 nvc->vt_pid = get_pid(task_pid(current));
1002 }
1003 release_console_sem();
1004 if (ret)
1005 break;
1006 /* Commence switch and lock */
1007 set_console(arg);
1008 }
1009 }
1010
845 /* 1011 /*
846 * wait until the specified VT has been activated 1012 * wait until the specified VT has been activated
847 */ 1013 */
@@ -851,7 +1017,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
851 if (arg == 0 || arg > MAX_NR_CONSOLES) 1017 if (arg == 0 || arg > MAX_NR_CONSOLES)
852 ret = -ENXIO; 1018 ret = -ENXIO;
853 else 1019 else
854 ret = vt_waitactive(arg - 1); 1020 ret = vt_waitactive(arg);
855 break; 1021 break;
856 1022
857 /* 1023 /*
@@ -1159,6 +1325,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
1159 ret = put_user(vc->vc_hi_font_mask, 1325 ret = put_user(vc->vc_hi_font_mask,
1160 (unsigned short __user *)arg); 1326 (unsigned short __user *)arg);
1161 break; 1327 break;
1328 case VT_WAITEVENT:
1329 ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
1330 break;
1162 default: 1331 default:
1163 ret = -ENOIOCTLCMD; 1332 ret = -ENOIOCTLCMD;
1164 } 1333 }
@@ -1170,54 +1339,6 @@ eperm:
1170 goto out; 1339 goto out;
1171} 1340}
1172 1341
1173/*
1174 * Sometimes we want to wait until a particular VT has been activated. We
1175 * do it in a very simple manner. Everybody waits on a single queue and
1176 * get woken up at once. Those that are satisfied go on with their business,
1177 * while those not ready go back to sleep. Seems overkill to add a wait
1178 * to each vt just for this - usually this does nothing!
1179 */
1180static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
1181
1182/*
1183 * Sleeps until a vt is activated, or the task is interrupted. Returns
1184 * 0 if activation, -EINTR if interrupted by a signal handler.
1185 */
1186int vt_waitactive(int vt)
1187{
1188 int retval;
1189 DECLARE_WAITQUEUE(wait, current);
1190
1191 add_wait_queue(&vt_activate_queue, &wait);
1192 for (;;) {
1193 retval = 0;
1194
1195 /*
1196 * Synchronize with redraw_screen(). By acquiring the console
1197 * semaphore we make sure that the console switch is completed
1198 * before we return. If we didn't wait for the semaphore, we
1199 * could return at a point where fg_console has already been
1200 * updated, but the console switch hasn't been completed.
1201 */
1202 acquire_console_sem();
1203 set_current_state(TASK_INTERRUPTIBLE);
1204 if (vt == fg_console) {
1205 release_console_sem();
1206 break;
1207 }
1208 release_console_sem();
1209 retval = -ERESTARTNOHAND;
1210 if (signal_pending(current))
1211 break;
1212 schedule();
1213 }
1214 remove_wait_queue(&vt_activate_queue, &wait);
1215 __set_current_state(TASK_RUNNING);
1216 return retval;
1217}
1218
1219#define vt_wake_waitactive() wake_up(&vt_activate_queue)
1220
1221void reset_vc(struct vc_data *vc) 1342void reset_vc(struct vc_data *vc)
1222{ 1343{
1223 vc->vc_mode = KD_TEXT; 1344 vc->vc_mode = KD_TEXT;
@@ -1256,12 +1377,216 @@ void vc_SAK(struct work_struct *work)
1256 release_console_sem(); 1377 release_console_sem();
1257} 1378}
1258 1379
1380#ifdef CONFIG_COMPAT
1381
1382struct compat_consolefontdesc {
1383 unsigned short charcount; /* characters in font (256 or 512) */
1384 unsigned short charheight; /* scan lines per character (1-32) */
1385 compat_caddr_t chardata; /* font data in expanded form */
1386};
1387
1388static inline int
1389compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
1390 int perm, struct console_font_op *op)
1391{
1392 struct compat_consolefontdesc cfdarg;
1393 int i;
1394
1395 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
1396 return -EFAULT;
1397
1398 switch (cmd) {
1399 case PIO_FONTX:
1400 if (!perm)
1401 return -EPERM;
1402 op->op = KD_FONT_OP_SET;
1403 op->flags = KD_FONT_FLAG_OLD;
1404 op->width = 8;
1405 op->height = cfdarg.charheight;
1406 op->charcount = cfdarg.charcount;
1407 op->data = compat_ptr(cfdarg.chardata);
1408 return con_font_op(vc_cons[fg_console].d, op);
1409 case GIO_FONTX:
1410 op->op = KD_FONT_OP_GET;
1411 op->flags = KD_FONT_FLAG_OLD;
1412 op->width = 8;
1413 op->height = cfdarg.charheight;
1414 op->charcount = cfdarg.charcount;
1415 op->data = compat_ptr(cfdarg.chardata);
1416 i = con_font_op(vc_cons[fg_console].d, op);
1417 if (i)
1418 return i;
1419 cfdarg.charheight = op->height;
1420 cfdarg.charcount = op->charcount;
1421 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
1422 return -EFAULT;
1423 return 0;
1424 }
1425 return -EINVAL;
1426}
1427
1428struct compat_console_font_op {
1429 compat_uint_t op; /* operation code KD_FONT_OP_* */
1430 compat_uint_t flags; /* KD_FONT_FLAG_* */
1431 compat_uint_t width, height; /* font size */
1432 compat_uint_t charcount;
1433 compat_caddr_t data; /* font data with height fixed to 32 */
1434};
1435
1436static inline int
1437compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
1438 int perm, struct console_font_op *op, struct vc_data *vc)
1439{
1440 int i;
1441
1442 if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
1443 return -EFAULT;
1444 if (!perm && op->op != KD_FONT_OP_GET)
1445 return -EPERM;
1446 op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
1447 op->flags |= KD_FONT_FLAG_OLD;
1448 i = con_font_op(vc, op);
1449 if (i)
1450 return i;
1451 ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
1452 if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
1453 return -EFAULT;
1454 return 0;
1455}
1456
1457struct compat_unimapdesc {
1458 unsigned short entry_ct;
1459 compat_caddr_t entries;
1460};
1461
1462static inline int
1463compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
1464 int perm, struct vc_data *vc)
1465{
1466 struct compat_unimapdesc tmp;
1467 struct unipair __user *tmp_entries;
1468
1469 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1470 return -EFAULT;
1471 tmp_entries = compat_ptr(tmp.entries);
1472 if (tmp_entries)
1473 if (!access_ok(VERIFY_WRITE, tmp_entries,
1474 tmp.entry_ct*sizeof(struct unipair)))
1475 return -EFAULT;
1476 switch (cmd) {
1477 case PIO_UNIMAP:
1478 if (!perm)
1479 return -EPERM;
1480 return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
1481 case GIO_UNIMAP:
1482 if (!perm && fg_console != vc->vc_num)
1483 return -EPERM;
1484 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
1485 }
1486 return 0;
1487}
1488
1489long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
1490 unsigned int cmd, unsigned long arg)
1491{
1492 struct vc_data *vc = tty->driver_data;
1493 struct console_font_op op; /* used in multiple places here */
1494 struct kbd_struct *kbd;
1495 unsigned int console;
1496 void __user *up = (void __user *)arg;
1497 int perm;
1498 int ret = 0;
1499
1500 console = vc->vc_num;
1501
1502 lock_kernel();
1503
1504 if (!vc_cons_allocated(console)) { /* impossible? */
1505 ret = -ENOIOCTLCMD;
1506 goto out;
1507 }
1508
1509 /*
1510 * To have permissions to do most of the vt ioctls, we either have
1511 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
1512 */
1513 perm = 0;
1514 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1515 perm = 1;
1516
1517 kbd = kbd_table + console;
1518 switch (cmd) {
1519 /*
1520 * these need special handlers for incompatible data structures
1521 */
1522 case PIO_FONTX:
1523 case GIO_FONTX:
1524 ret = compat_fontx_ioctl(cmd, up, perm, &op);
1525 break;
1526
1527 case KDFONTOP:
1528 ret = compat_kdfontop_ioctl(up, perm, &op, vc);
1529 break;
1530
1531 case PIO_UNIMAP:
1532 case GIO_UNIMAP:
1533 ret = do_unimap_ioctl(cmd, up, perm, vc);
1534 break;
1535
1536 /*
1537 * all these treat 'arg' as an integer
1538 */
1539 case KIOCSOUND:
1540 case KDMKTONE:
1541#ifdef CONFIG_X86
1542 case KDADDIO:
1543 case KDDELIO:
1544#endif
1545 case KDSETMODE:
1546 case KDMAPDISP:
1547 case KDUNMAPDISP:
1548 case KDSKBMODE:
1549 case KDSKBMETA:
1550 case KDSKBLED:
1551 case KDSETLED:
1552 case KDSIGACCEPT:
1553 case VT_ACTIVATE:
1554 case VT_WAITACTIVE:
1555 case VT_RELDISP:
1556 case VT_DISALLOCATE:
1557 case VT_RESIZE:
1558 case VT_RESIZEX:
1559 goto fallback;
1560
1561 /*
1562 * the rest has a compatible data structure behind arg,
1563 * but we have to convert it to a proper 64 bit pointer.
1564 */
1565 default:
1566 arg = (unsigned long)compat_ptr(arg);
1567 goto fallback;
1568 }
1569out:
1570 unlock_kernel();
1571 return ret;
1572
1573fallback:
1574 unlock_kernel();
1575 return vt_ioctl(tty, file, cmd, arg);
1576}
1577
1578
1579#endif /* CONFIG_COMPAT */
1580
1581
1259/* 1582/*
1260 * Performs the back end of a vt switch 1583 * Performs the back end of a vt switch. Called under the console
1584 * semaphore.
1261 */ 1585 */
1262static void complete_change_console(struct vc_data *vc) 1586static void complete_change_console(struct vc_data *vc)
1263{ 1587{
1264 unsigned char old_vc_mode; 1588 unsigned char old_vc_mode;
1589 int old = fg_console;
1265 1590
1266 last_console = fg_console; 1591 last_console = fg_console;
1267 1592
@@ -1325,7 +1650,7 @@ static void complete_change_console(struct vc_data *vc)
1325 /* 1650 /*
1326 * Wake anyone waiting for their VT to activate 1651 * Wake anyone waiting for their VT to activate
1327 */ 1652 */
1328 vt_wake_waitactive(); 1653 vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
1329 return; 1654 return;
1330} 1655}
1331 1656
@@ -1398,3 +1723,58 @@ void change_console(struct vc_data *new_vc)
1398 1723
1399 complete_change_console(new_vc); 1724 complete_change_console(new_vc);
1400} 1725}
1726
1727/* Perform a kernel triggered VT switch for suspend/resume */
1728
1729static int disable_vt_switch;
1730
1731int vt_move_to_console(unsigned int vt, int alloc)
1732{
1733 int prev;
1734
1735 acquire_console_sem();
1736 /* Graphics mode - up to X */
1737 if (disable_vt_switch) {
1738 release_console_sem();
1739 return 0;
1740 }
1741 prev = fg_console;
1742
1743 if (alloc && vc_allocate(vt)) {
1744 /* we can't have a free VC for now. Too bad,
1745 * we don't want to mess the screen for now. */
1746 release_console_sem();
1747 return -ENOSPC;
1748 }
1749
1750 if (set_console(vt)) {
1751 /*
1752 * We're unable to switch to the SUSPEND_CONSOLE.
1753 * Let the calling function know so it can decide
1754 * what to do.
1755 */
1756 release_console_sem();
1757 return -EIO;
1758 }
1759 release_console_sem();
1760 if (vt_waitactive(vt + 1)) {
1761 pr_debug("Suspend: Can't switch VCs.");
1762 return -EINTR;
1763 }
1764 return prev;
1765}
1766
1767/*
1768 * Normally during a suspend, we allocate a new console and switch to it.
1769 * When we resume, we switch back to the original console. This switch
1770 * can be slow, so on systems where the framebuffer can handle restoration
1771 * of video registers anyways, there's little point in doing the console
1772 * switch. This function allows you to disable it by passing it '0'.
1773 */
1774void pm_set_vt_switch(int do_switch)
1775{
1776 acquire_console_sem();
1777 disable_vt_switch = !do_switch;
1778 release_console_sem();
1779}
1780EXPORT_SYMBOL(pm_set_vt_switch);