mirror of https://github.com/torvalds/linux.git
tty/vt: use guard()s
Having all the new guards, use them in the vt code. This improves readability, makes error handling easier, and marks locked portions of code explicit. A local free_page_ptr __free guard is introduced for __get_free_page/free_page (with proper casts). This could be made public in include/. But I am not sure if there are more possible users, so keeping completely private here. Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org> Link: https://lore.kernel.org/r/20250814072456.182853-16-jirislaby@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2fe16088c3
commit
e730c373b6
|
|
@ -361,10 +361,10 @@ int con_set_trans_old(unsigned char __user * arg)
|
|||
inbuf[i] = UNI_DIRECT_BASE | ch;
|
||||
}
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
memcpy(translations[USER_MAP], inbuf, sizeof(inbuf));
|
||||
update_user_maps();
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -374,13 +374,11 @@ int con_get_trans_old(unsigned char __user * arg)
|
|||
unsigned short *p = translations[USER_MAP];
|
||||
unsigned char outbuf[E_TABSZ];
|
||||
|
||||
console_lock();
|
||||
for (i = 0; i < ARRAY_SIZE(outbuf); i++)
|
||||
{
|
||||
scoped_guard(console_lock)
|
||||
for (i = 0; i < ARRAY_SIZE(outbuf); i++) {
|
||||
ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
|
||||
outbuf[i] = (ch & ~0xff) ? 0 : ch;
|
||||
}
|
||||
console_unlock();
|
||||
|
||||
return copy_to_user(arg, outbuf, sizeof(outbuf)) ? -EFAULT : 0;
|
||||
}
|
||||
|
|
@ -392,10 +390,10 @@ int con_set_trans_new(ushort __user * arg)
|
|||
if (copy_from_user(inbuf, arg, sizeof(inbuf)))
|
||||
return -EFAULT;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
memcpy(translations[USER_MAP], inbuf, sizeof(inbuf));
|
||||
update_user_maps();
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -403,9 +401,8 @@ int con_get_trans_new(ushort __user * arg)
|
|||
{
|
||||
unsigned short outbuf[E_TABSZ];
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
memcpy(outbuf, translations[USER_MAP], sizeof(outbuf));
|
||||
console_unlock();
|
||||
|
||||
return copy_to_user(arg, outbuf, sizeof(outbuf)) ? -EFAULT : 0;
|
||||
}
|
||||
|
|
@ -571,11 +568,8 @@ static int con_do_clear_unimap(struct vc_data *vc)
|
|||
|
||||
int con_clear_unimap(struct vc_data *vc)
|
||||
{
|
||||
int ret;
|
||||
console_lock();
|
||||
ret = con_do_clear_unimap(vc);
|
||||
console_unlock();
|
||||
return ret;
|
||||
guard(console_lock)();
|
||||
return con_do_clear_unimap(vc);
|
||||
}
|
||||
|
||||
static struct uni_pagedict *con_unshare_unimap(struct vc_data *vc,
|
||||
|
|
|
|||
|
|
@ -127,9 +127,8 @@ int sel_loadlut(u32 __user *lut)
|
|||
if (copy_from_user(tmplut, lut, sizeof(inwordLut)))
|
||||
return -EFAULT;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
memcpy(inwordLut, tmplut, sizeof(inwordLut));
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -375,15 +374,9 @@ static int vc_selection(struct vc_data *vc, struct tiocl_selection *v,
|
|||
|
||||
int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&vc_sel.lock);
|
||||
console_lock();
|
||||
ret = vc_selection(vc_cons[fg_console].d, v, tty);
|
||||
console_unlock();
|
||||
mutex_unlock(&vc_sel.lock);
|
||||
|
||||
return ret;
|
||||
guard(mutex)(&vc_sel.lock);
|
||||
guard(console_lock)();
|
||||
return vc_selection(vc_cons[fg_console].d, v, tty);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(set_selection_kernel);
|
||||
|
||||
|
|
@ -409,9 +402,8 @@ int paste_selection(struct tty_struct *tty)
|
|||
const char *bps = bp ? bracketed_paste_start : NULL;
|
||||
const char *bpe = bp ? bracketed_paste_end : NULL;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
poke_blanked_console();
|
||||
console_unlock();
|
||||
|
||||
ld = tty_ldisc_ref_wait(tty);
|
||||
if (!ld)
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
#define HEADER_SIZE 4u
|
||||
#define CON_BUF_SIZE (IS_ENABLED(CONFIG_BASE_SMALL) ? 256 : PAGE_SIZE)
|
||||
|
||||
DEFINE_FREE(free_page_ptr, void *, if (_T) free_page((unsigned long)_T));
|
||||
|
||||
/*
|
||||
* Our minor space:
|
||||
*
|
||||
|
|
@ -72,7 +74,6 @@
|
|||
#define use_unicode(inode) (iminor(inode) & 64)
|
||||
#define use_attributes(inode) (iminor(inode) & 128)
|
||||
|
||||
|
||||
struct vcs_poll_data {
|
||||
struct notifier_block notifier;
|
||||
unsigned int cons_num;
|
||||
|
|
@ -231,15 +232,13 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
|
|||
struct vc_data *vc;
|
||||
int size;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock) {
|
||||
vc = vcs_vc(inode, NULL);
|
||||
if (!vc) {
|
||||
console_unlock();
|
||||
if (!vc)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
size = vcs_size(vc, use_attributes(inode), use_unicode(inode));
|
||||
console_unlock();
|
||||
}
|
||||
if (size < 0)
|
||||
return size;
|
||||
return fixed_size_llseek(file, offset, orig, size);
|
||||
|
|
@ -369,11 +368,10 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
struct vcs_poll_data *poll;
|
||||
unsigned int read;
|
||||
ssize_t ret;
|
||||
char *con_buf;
|
||||
loff_t pos;
|
||||
bool viewed, attr, uni_mode;
|
||||
|
||||
con_buf = (char *) __get_free_page(GFP_KERNEL);
|
||||
char *con_buf __free(free_page_ptr) = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!con_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -382,17 +380,16 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
/* Select the proper current console and verify
|
||||
* sanity of the situation under the console lock.
|
||||
*/
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
|
||||
uni_mode = use_unicode(inode);
|
||||
attr = use_attributes(inode);
|
||||
|
||||
ret = -EINVAL;
|
||||
if (pos < 0)
|
||||
goto unlock_out;
|
||||
return -EINVAL;
|
||||
/* we enforce 32-bit alignment for pos and count in unicode mode */
|
||||
if (uni_mode && (pos | count) & 3)
|
||||
goto unlock_out;
|
||||
return -EINVAL;
|
||||
|
||||
poll = file->private_data;
|
||||
if (count && poll)
|
||||
|
|
@ -468,10 +465,8 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
}
|
||||
*ppos += read;
|
||||
if (read)
|
||||
ret = read;
|
||||
unlock_out:
|
||||
console_unlock();
|
||||
free_page((unsigned long) con_buf);
|
||||
return read;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -591,7 +586,6 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
struct vc_data *vc;
|
||||
char *con_buf;
|
||||
u16 *org0, *org;
|
||||
unsigned int written;
|
||||
int size;
|
||||
|
|
@ -602,7 +596,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
if (use_unicode(inode))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
con_buf = (char *) __get_free_page(GFP_KERNEL);
|
||||
char *con_buf __free(free_page_ptr) = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!con_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -611,22 +605,18 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
/* Select the proper current console and verify
|
||||
* sanity of the situation under the console lock.
|
||||
*/
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
|
||||
attr = use_attributes(inode);
|
||||
ret = -ENXIO;
|
||||
vc = vcs_vc(inode, &viewed);
|
||||
if (!vc)
|
||||
goto unlock_out;
|
||||
return -ENXIO;
|
||||
|
||||
size = vcs_size(vc, attr, false);
|
||||
if (size < 0) {
|
||||
ret = size;
|
||||
goto unlock_out;
|
||||
}
|
||||
ret = -EINVAL;
|
||||
if (size < 0)
|
||||
return size;
|
||||
if (pos < 0 || pos > size)
|
||||
goto unlock_out;
|
||||
return -EINVAL;
|
||||
if (count > size - pos)
|
||||
count = size - pos;
|
||||
written = 0;
|
||||
|
|
@ -651,8 +641,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
*/
|
||||
if (written)
|
||||
break;
|
||||
ret = -EFAULT;
|
||||
goto unlock_out;
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -664,15 +653,13 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
if (!vc) {
|
||||
if (written)
|
||||
break;
|
||||
ret = -ENXIO;
|
||||
goto unlock_out;
|
||||
return -ENXIO;
|
||||
}
|
||||
size = vcs_size(vc, attr, false);
|
||||
if (size < 0) {
|
||||
if (written)
|
||||
break;
|
||||
ret = size;
|
||||
goto unlock_out;
|
||||
return size;
|
||||
}
|
||||
if (pos >= size)
|
||||
break;
|
||||
|
|
@ -702,9 +689,6 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
|||
if (written)
|
||||
vcs_scr_updated(vc);
|
||||
|
||||
unlock_out:
|
||||
console_unlock();
|
||||
free_page((unsigned long) con_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -754,17 +738,17 @@ vcs_open(struct inode *inode, struct file *filp)
|
|||
unsigned int currcons = console(inode);
|
||||
bool attr = use_attributes(inode);
|
||||
bool uni_mode = use_unicode(inode);
|
||||
int ret = 0;
|
||||
|
||||
/* we currently don't support attributes in unicode mode */
|
||||
if (attr && uni_mode)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
console_lock();
|
||||
if(currcons && !vc_cons_allocated(currcons-1))
|
||||
ret = -ENXIO;
|
||||
console_unlock();
|
||||
return ret;
|
||||
guard(console_lock)();
|
||||
|
||||
if (currcons && !vc_cons_allocated(currcons - 1))
|
||||
return -ENXIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vcs_release(struct inode *inode, struct file *file)
|
||||
|
|
|
|||
|
|
@ -1317,12 +1317,9 @@ EXPORT_SYMBOL(__vc_resize);
|
|||
static int vt_resize(struct tty_struct *tty, struct winsize *ws)
|
||||
{
|
||||
struct vc_data *vc = tty->driver_data;
|
||||
int ret;
|
||||
|
||||
console_lock();
|
||||
ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row, false);
|
||||
console_unlock();
|
||||
return ret;
|
||||
guard(console_lock)();
|
||||
return vc_do_resize(tty, vc, ws->ws_col, ws->ws_row, false);
|
||||
}
|
||||
|
||||
struct vc_data *vc_deallocate(unsigned int currcons)
|
||||
|
|
@ -3135,12 +3132,11 @@ static int do_con_write(struct tty_struct *tty, const u8 *buf, int count)
|
|||
if (in_interrupt())
|
||||
return count;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
currcons = vc->vc_num;
|
||||
if (!vc_cons_allocated(currcons)) {
|
||||
/* could this happen? */
|
||||
pr_warn_once("con_write: tty %d not allocated\n", currcons+1);
|
||||
console_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3184,7 +3180,7 @@ static int do_con_write(struct tty_struct *tty, const u8 *buf, int count)
|
|||
con_flush(vc, &draw);
|
||||
console_conditional_schedule();
|
||||
notify_update(vc);
|
||||
console_unlock();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -3199,7 +3195,7 @@ static int do_con_write(struct tty_struct *tty, const u8 *buf, int count)
|
|||
*/
|
||||
static void console_callback(struct work_struct *ignored)
|
||||
{
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
|
||||
if (want_console >= 0) {
|
||||
if (want_console != fg_console &&
|
||||
|
|
@ -3228,8 +3224,6 @@ static void console_callback(struct work_struct *ignored)
|
|||
blank_timer_expired = 0;
|
||||
}
|
||||
notify_update(vc_cons[fg_console].d);
|
||||
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
int set_console(int nr)
|
||||
|
|
@ -3433,9 +3427,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
|
|||
return -EPERM;
|
||||
return paste_selection(tty);
|
||||
case TIOCL_UNBLANKSCREEN:
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
unblank_screen();
|
||||
console_unlock();
|
||||
break;
|
||||
case TIOCL_SELLOADLUT:
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
|
|
@ -3451,9 +3444,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
|
|||
data = vt_get_shift_state();
|
||||
return put_user(data, p);
|
||||
case TIOCL_GETMOUSEREPORTING:
|
||||
console_lock(); /* May be overkill */
|
||||
scoped_guard(console_lock) /* May be overkill */
|
||||
data = mouse_reporting();
|
||||
console_unlock();
|
||||
return put_user(data, p);
|
||||
case TIOCL_SETVESABLANK:
|
||||
return set_vesa_blanking(param);
|
||||
|
|
@ -3484,15 +3476,14 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
|
|||
* Needs the console lock here. Note that lots of other calls
|
||||
* need fixing before the lock is actually useful!
|
||||
*/
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
scrollfront(vc_cons[fg_console].d, lines);
|
||||
console_unlock();
|
||||
break;
|
||||
case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
|
||||
console_lock();
|
||||
scoped_guard(console_lock) {
|
||||
ignore_poke = 1;
|
||||
do_blank_screen(0);
|
||||
console_unlock();
|
||||
}
|
||||
break;
|
||||
case TIOCL_BLANKEDSCREEN:
|
||||
return console_blanked;
|
||||
|
|
@ -3582,9 +3573,8 @@ static void con_flush_chars(struct tty_struct *tty)
|
|||
if (in_interrupt()) /* from flush_to_ldisc */
|
||||
return;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
set_cursor(vc);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3596,22 +3586,20 @@ static int con_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
struct vc_data *vc;
|
||||
int ret;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
ret = vc_allocate(currcons);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
return ret;
|
||||
|
||||
vc = vc_cons[currcons].d;
|
||||
|
||||
/* Still being freed */
|
||||
if (vc->port.tty) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto unlock;
|
||||
}
|
||||
if (vc->port.tty)
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = tty_port_install(&vc->port, driver, tty);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
return ret;
|
||||
|
||||
tty->driver_data = vc;
|
||||
vc->port.tty = tty;
|
||||
|
|
@ -3625,9 +3613,8 @@ static int con_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
tty->termios.c_iflag |= IUTF8;
|
||||
else
|
||||
tty->termios.c_iflag &= ~IUTF8;
|
||||
unlock:
|
||||
console_unlock();
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int con_open(struct tty_struct *tty, struct file *filp)
|
||||
|
|
@ -3646,9 +3633,9 @@ static void con_shutdown(struct tty_struct *tty)
|
|||
{
|
||||
struct vc_data *vc = tty->driver_data;
|
||||
BUG_ON(vc == NULL);
|
||||
console_lock();
|
||||
|
||||
guard(console_lock)();
|
||||
vc->port.tty = NULL;
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
static void con_cleanup(struct tty_struct *tty)
|
||||
|
|
@ -4137,15 +4124,13 @@ static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
|
|||
struct con_driver *con = dev_get_drvdata(dev);
|
||||
int bind = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
|
||||
if (bind)
|
||||
vt_bind(con);
|
||||
else
|
||||
vt_unbind(con);
|
||||
|
||||
console_unlock();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
@ -4155,9 +4140,8 @@ static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
|
|||
struct con_driver *con = dev_get_drvdata(dev);
|
||||
int bind;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
bind = con_is_bound(con->con);
|
||||
console_unlock();
|
||||
|
||||
return sysfs_emit(buf, "%i\n", bind);
|
||||
}
|
||||
|
|
@ -4429,7 +4413,7 @@ static void con_driver_unregister_callback(struct work_struct *ignored)
|
|||
{
|
||||
int i;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
|
||||
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
|
||||
struct con_driver *con_driver = ®istered_con_driver[i];
|
||||
|
|
@ -4454,8 +4438,6 @@ static void con_driver_unregister_callback(struct work_struct *ignored)
|
|||
con_driver->first = 0;
|
||||
con_driver->last = 0;
|
||||
}
|
||||
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4491,9 +4473,8 @@ EXPORT_SYMBOL_GPL(do_take_over_console);
|
|||
*/
|
||||
void give_up_console(const struct consw *csw)
|
||||
{
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
do_unregister_con_driver(csw);
|
||||
console_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(give_up_console);
|
||||
|
||||
|
|
@ -4541,9 +4522,8 @@ static int set_vesa_blanking(u8 __user *mode_user)
|
|||
if (get_user(mode, mode_user))
|
||||
return -EFAULT;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
vesa_blank_mode = (mode <= VESA_BLANK_MAX) ? mode : VESA_NO_BLANKING;
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4729,7 +4709,7 @@ int con_set_cmap(unsigned char __user *arg)
|
|||
if (copy_from_user(colormap, arg, sizeof(colormap)))
|
||||
return -EFAULT;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
for (i = k = 0; i < 16; i++) {
|
||||
default_red[i] = colormap[k++];
|
||||
default_grn[i] = colormap[k++];
|
||||
|
|
@ -4745,7 +4725,6 @@ int con_set_cmap(unsigned char __user *arg)
|
|||
}
|
||||
set_palette(vc_cons[i].d);
|
||||
}
|
||||
console_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4755,13 +4734,12 @@ int con_get_cmap(unsigned char __user *arg)
|
|||
int i, k;
|
||||
unsigned char colormap[3*16];
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
for (i = k = 0; i < 16; i++) {
|
||||
colormap[k++] = default_red[i];
|
||||
colormap[k++] = default_grn[i];
|
||||
colormap[k++] = default_blu[i];
|
||||
}
|
||||
console_unlock();
|
||||
|
||||
if (copy_to_user(arg, colormap, sizeof(colormap)))
|
||||
return -EFAULT;
|
||||
|
|
|
|||
|
|
@ -373,15 +373,13 @@ static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
|
|||
break;
|
||||
}
|
||||
|
||||
case KDSETMODE:
|
||||
case KDSETMODE: {
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
|
||||
console_lock();
|
||||
ret = vt_kdsetmode(vc, arg);
|
||||
console_unlock();
|
||||
return ret;
|
||||
|
||||
guard(console_lock)();
|
||||
return vt_kdsetmode(vc, arg);
|
||||
}
|
||||
case KDGETMODE:
|
||||
return put_user(vc->vc_mode, (int __user *)arg);
|
||||
|
||||
|
|
@ -601,12 +599,10 @@ static int vt_setactivate(struct vt_setactivate __user *sa)
|
|||
|
||||
vsa.console--;
|
||||
vsa.console = array_index_nospec(vsa.console, MAX_NR_CONSOLES);
|
||||
console_lock();
|
||||
scoped_guard(console_lock) {
|
||||
ret = vc_allocate(vsa.console);
|
||||
if (ret) {
|
||||
console_unlock();
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is safe providing we don't drop the console sem between
|
||||
|
|
@ -617,7 +613,7 @@ static int vt_setactivate(struct vt_setactivate __user *sa)
|
|||
nvc->vt_mode.frsig = 0;
|
||||
put_pid(nvc->vt_pid);
|
||||
nvc->vt_pid = get_pid(task_pid(current));
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
/* Commence switch and lock */
|
||||
/* Review set_console locks */
|
||||
|
|
@ -630,19 +626,18 @@ static int vt_setactivate(struct vt_setactivate __user *sa)
|
|||
static int vt_disallocate(unsigned int vc_num)
|
||||
{
|
||||
struct vc_data *vc = NULL;
|
||||
int ret = 0;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock) {
|
||||
if (vt_busy(vc_num))
|
||||
ret = -EBUSY;
|
||||
else if (vc_num)
|
||||
return -EBUSY;
|
||||
if (vc_num)
|
||||
vc = vc_deallocate(vc_num);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
if (vc && vc_num >= MIN_NR_CONSOLES)
|
||||
tty_port_put(&vc->port);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* deallocate all unused consoles, but leave 0 */
|
||||
|
|
@ -651,13 +646,12 @@ static void vt_disallocate_all(void)
|
|||
struct vc_data *vc[MAX_NR_CONSOLES];
|
||||
int i;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
for (i = 1; i < MAX_NR_CONSOLES; i++)
|
||||
if (!vt_busy(i))
|
||||
vc[i] = vc_deallocate(i);
|
||||
else
|
||||
vc[i] = NULL;
|
||||
console_unlock();
|
||||
|
||||
for (i = 1; i < MAX_NR_CONSOLES; i++) {
|
||||
if (vc[i] && i >= MIN_NR_CONSOLES)
|
||||
|
|
@ -703,7 +697,7 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
|
|||
|
||||
if (!vc_cons[i].d)
|
||||
continue;
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
vcp = vc_cons[i].d;
|
||||
if (vcp) {
|
||||
int ret;
|
||||
|
|
@ -718,11 +712,9 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
|
|||
if (ret) {
|
||||
vcp->vc_scan_lines = save_scan_lines;
|
||||
vcp->vc_cell_height = save_cell_height;
|
||||
console_unlock();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -770,7 +762,7 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS)
|
||||
return -EINVAL;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
vc->vt_mode = tmp;
|
||||
/* the frsig is ignored, so we set it to 0 */
|
||||
vc->vt_mode.frsig = 0;
|
||||
|
|
@ -778,7 +770,6 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
vc->vt_pid = get_pid(task_pid(current));
|
||||
/* no switch is required -- saw@shade.msu.ru */
|
||||
vc->vt_newvt = -1;
|
||||
console_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -787,9 +778,8 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
struct vt_mode tmp;
|
||||
int rc;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock)
|
||||
memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
|
||||
console_unlock();
|
||||
|
||||
rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
|
||||
if (rc)
|
||||
|
|
@ -811,12 +801,10 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
return -EFAULT;
|
||||
|
||||
state = 1; /* /dev/tty0 is always open */
|
||||
console_lock(); /* required by vt_in_use() */
|
||||
for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
|
||||
++i, mask <<= 1)
|
||||
scoped_guard(console_lock) /* required by vt_in_use() */
|
||||
for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1)
|
||||
if (vt_in_use(i))
|
||||
state |= mask;
|
||||
console_unlock();
|
||||
return put_user(state, &vtstat->v_state);
|
||||
}
|
||||
|
||||
|
|
@ -824,11 +812,10 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
* Returns the first available (non-opened) console.
|
||||
*/
|
||||
case VT_OPENQRY:
|
||||
console_lock(); /* required by vt_in_use() */
|
||||
scoped_guard(console_lock) /* required by vt_in_use() */
|
||||
for (i = 0; i < MAX_NR_CONSOLES; ++i)
|
||||
if (!vt_in_use(i))
|
||||
break;
|
||||
console_unlock();
|
||||
i = i < MAX_NR_CONSOLES ? (i+1) : -1;
|
||||
return put_user(i, (int __user *)arg);
|
||||
|
||||
|
|
@ -845,11 +832,11 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
|
||||
arg--;
|
||||
arg = array_index_nospec(arg, MAX_NR_CONSOLES);
|
||||
console_lock();
|
||||
scoped_guard(console_lock) {
|
||||
ret = vc_allocate(arg);
|
||||
console_unlock();
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
set_console(arg);
|
||||
break;
|
||||
|
||||
|
|
@ -880,15 +867,13 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
* 2: completed switch-to OK
|
||||
*/
|
||||
case VT_RELDISP:
|
||||
{
|
||||
if (!perm)
|
||||
return -EPERM;
|
||||
|
||||
console_lock();
|
||||
ret = vt_reldisp(vc, arg);
|
||||
console_unlock();
|
||||
|
||||
return ret;
|
||||
|
||||
guard(console_lock)();
|
||||
return vt_reldisp(vc, arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Disallocate memory associated to VT (but leave VT1)
|
||||
|
|
@ -917,7 +902,7 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
get_user(cc, &vtsizes->v_cols))
|
||||
return -EFAULT;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
for (i = 0; i < MAX_NR_CONSOLES; i++) {
|
||||
vc = vc_cons[i].d;
|
||||
|
||||
|
|
@ -926,7 +911,6 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
__vc_resize(vc_cons[i].d, cc, ll, true);
|
||||
}
|
||||
}
|
||||
console_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -996,20 +980,17 @@ void vc_SAK(struct work_struct *work)
|
|||
struct vc_data *vc;
|
||||
struct tty_struct *tty;
|
||||
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
vc = vc_con->d;
|
||||
if (vc) {
|
||||
if (!vc)
|
||||
return;
|
||||
|
||||
/* FIXME: review tty ref counting */
|
||||
tty = vc->port.tty;
|
||||
/*
|
||||
* SAK should also work in all raw modes and reset
|
||||
* them properly.
|
||||
*/
|
||||
/* SAK should also work in all raw modes and reset them properly. */
|
||||
if (tty)
|
||||
__do_SAK(tty);
|
||||
reset_vc(vc);
|
||||
}
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
@ -1287,31 +1268,29 @@ int vt_move_to_console(unsigned int vt, int alloc)
|
|||
{
|
||||
int prev;
|
||||
|
||||
console_lock();
|
||||
scoped_guard(console_lock) {
|
||||
/* Graphics mode - up to X */
|
||||
if (disable_vt_switch) {
|
||||
console_unlock();
|
||||
if (disable_vt_switch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
prev = fg_console;
|
||||
|
||||
if (alloc && vc_allocate(vt)) {
|
||||
/* we can't have a free VC for now. Too bad,
|
||||
* we don't want to mess the screen for now. */
|
||||
console_unlock();
|
||||
/*
|
||||
* We can't have a free VC for now. Too bad, we don't want to mess the
|
||||
* screen for now.
|
||||
*/
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
if (set_console(vt)) {
|
||||
/*
|
||||
* We're unable to switch to the SUSPEND_CONSOLE.
|
||||
* Let the calling function know so it can decide
|
||||
* what to do.
|
||||
* We're unable to switch to the SUSPEND_CONSOLE. Let the calling function
|
||||
* know so it can decide what to do.
|
||||
*/
|
||||
console_unlock();
|
||||
return -EIO;
|
||||
}
|
||||
console_unlock();
|
||||
}
|
||||
if (vt_waitactive(vt + 1)) {
|
||||
pr_debug("Suspend: Can't switch VCs.");
|
||||
return -EINTR;
|
||||
|
|
@ -1328,8 +1307,7 @@ int vt_move_to_console(unsigned int vt, int alloc)
|
|||
*/
|
||||
void pm_set_vt_switch(int do_switch)
|
||||
{
|
||||
console_lock();
|
||||
guard(console_lock)();
|
||||
disable_vt_switch = !do_switch;
|
||||
console_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(pm_set_vt_switch);
|
||||
|
|
|
|||
Loading…
Reference in New Issue