summaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-09-01 09:51:16 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2021-09-01 09:51:16 -0700
commit7c314bdfb64e4bb8d2f829376ed56ce663483752 (patch)
treece846e0c4e8c8138258dd00c1f15aad7368fafbb /drivers/tty/vt
parentebf435d3b51b22340ef047aad0c2936ec4833ab2 (diff)
parent2e5f3a69b6fcd52a64ce3d746c6ee8390b6cabe8 (diff)
downloadlinux-stable-7c314bdfb64e4bb8d2f829376ed56ce663483752.tar.gz
linux-stable-7c314bdfb64e4bb8d2f829376ed56ce663483752.tar.bz2
linux-stable-7c314bdfb64e4bb8d2f829376ed56ce663483752.zip
Merge tag 'tty-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty / serial updates from Greg KH: "Here is the "big" set of tty/serial driver patches for 5.15-rc1 Nothing major in here at all, just some driver updates and more cleanups on old tty apis and code that needed it that includes: - tty.h cleanup of things that didn't belong in it - other tty cleanups by Jiri - driver cleanups - rs485 support added to amba-pl011 driver - dts updates - stm32 serial driver updates - other minor fixes and driver updates All have been in linux-next for a while with no reported problems" * tag 'tty-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (83 commits) tty: serial: uartlite: Use read_poll_timeout for a polling loop tty: serial: uartlite: Use constants in early_uartlite_putc tty: Fix data race between tiocsti() and flush_to_ldisc() serial: vt8500: Use of_device_get_match_data serial: tegra: Use of_device_get_match_data serial: 8250_ingenic: Use of_device_get_match_data tty: serial: linflexuart: Remove redundant check to simplify the code tty: serial: fsl_lpuart: do software reset for imx7ulp and imx8qxp tty: serial: fsl_lpuart: enable two stop bits for lpuart32 tty: serial: fsl_lpuart: fix the wrong mapbase value mxser: use semi-colons instead of commas tty: moxa: use semi-colons instead of commas tty: serial: fsl_lpuart: check dma_tx_in_progress in tx dma callback tty: replace in_irq() with in_hardirq() serial: sh-sci: fix break handling for sysrq serial: stm32: use devm_platform_get_and_ioremap_resource() serial: stm32: use the defined variable to simplify code Revert "arm pl011 serial: support multi-irq request" tty: serial: samsung: Add Exynos850 SoC data tty: serial: samsung: Fix driver data macros style ...
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r--drivers/tty/vt/keyboard.c62
-rw-r--r--drivers/tty/vt/vt.c27
2 files changed, 53 insertions, 36 deletions
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 4b0d69042ceb..c7fbbcdcc346 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -1171,9 +1171,9 @@ static inline unsigned char getleds(void)
*
* Check the status of a keyboard led flag and report it back
*/
-int vt_get_leds(int console, int flag)
+int vt_get_leds(unsigned int console, int flag)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
int ret;
unsigned long flags;
@@ -1193,9 +1193,9 @@ EXPORT_SYMBOL_GPL(vt_get_leds);
* Set the LEDs on a console. This is a wrapper for the VT layer
* so that we can keep kbd knowledge internal
*/
-void vt_set_led_state(int console, int leds)
+void vt_set_led_state(unsigned int console, int leds)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
setledstate(kb, leds);
}
@@ -1212,9 +1212,9 @@ void vt_set_led_state(int console, int leds)
* don't hold the lock. We probably need to split out an LED lock
* but not during an -rc release!
*/
-void vt_kbd_con_start(int console)
+void vt_kbd_con_start(unsigned int console)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
unsigned long flags;
spin_lock_irqsave(&led_lock, flags);
clr_vc_kbd_led(kb, VC_SCROLLOCK);
@@ -1229,9 +1229,9 @@ void vt_kbd_con_start(int console)
* Handle console stop. This is a wrapper for the VT layer
* so that we can keep kbd knowledge internal
*/
-void vt_kbd_con_stop(int console)
+void vt_kbd_con_stop(unsigned int console)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
unsigned long flags;
spin_lock_irqsave(&led_lock, flags);
set_vc_kbd_led(kb, VC_SCROLLOCK);
@@ -1377,7 +1377,7 @@ static void kbd_rawcode(unsigned char data)
{
struct vc_data *vc = vc_cons[fg_console].d;
- kbd = kbd_table + vc->vc_num;
+ kbd = &kbd_table[vc->vc_num];
if (kbd->kbdmode == VC_RAW)
put_queue(vc, data);
}
@@ -1400,7 +1400,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw)
tty->driver_data = vc;
}
- kbd = kbd_table + vc->vc_num;
+ kbd = &kbd_table[vc->vc_num];
#ifdef CONFIG_SPARC
if (keycode == KEY_STOP)
@@ -1825,9 +1825,9 @@ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm)
* Update the keyboard mode bits while holding the correct locks.
* Return 0 for success or an error code.
*/
-int vt_do_kdskbmode(int console, unsigned int arg)
+int vt_do_kdskbmode(unsigned int console, unsigned int arg)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
int ret = 0;
unsigned long flags;
@@ -1865,9 +1865,9 @@ int vt_do_kdskbmode(int console, unsigned int arg)
* Update the keyboard meta bits while holding the correct locks.
* Return 0 for success or an error code.
*/
-int vt_do_kdskbmeta(int console, unsigned int arg)
+int vt_do_kdskbmeta(unsigned int console, unsigned int arg)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
int ret = 0;
unsigned long flags;
@@ -2008,9 +2008,9 @@ out:
}
int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
- int console)
+ unsigned int console)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
struct kbentry kbe;
if (copy_from_user(&kbe, user_kbe, sizeof(struct kbentry)))
@@ -2097,9 +2097,9 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
return ret;
}
-int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
+int vt_do_kdskled(unsigned int console, int cmd, unsigned long arg, int perm)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
unsigned long flags;
unsigned char ucval;
@@ -2139,9 +2139,9 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
return -ENOIOCTLCMD;
}
-int vt_do_kdgkbmode(int console)
+int vt_do_kdgkbmode(unsigned int console)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
/* This is a spot read so needs no locking */
switch (kb->kbdmode) {
case VC_RAW:
@@ -2163,9 +2163,9 @@ int vt_do_kdgkbmode(int console)
*
* Report the meta flag status of this console
*/
-int vt_do_kdgkbmeta(int console)
+int vt_do_kdgkbmeta(unsigned int console)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
/* Again a spot read so no locking */
return vc_kbd_mode(kb, VC_META) ? K_ESCPREFIX : K_METABIT;
}
@@ -2176,7 +2176,7 @@ int vt_do_kdgkbmeta(int console)
*
* Restore the unicode console state to its default
*/
-void vt_reset_unicode(int console)
+void vt_reset_unicode(unsigned int console)
{
unsigned long flags;
@@ -2204,9 +2204,9 @@ int vt_get_shift_state(void)
* Reset the keyboard bits for a console as part of a general console
* reset event
*/
-void vt_reset_keyboard(int console)
+void vt_reset_keyboard(unsigned int console)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
unsigned long flags;
spin_lock_irqsave(&kbd_event_lock, flags);
@@ -2234,9 +2234,9 @@ void vt_reset_keyboard(int console)
* caller must be sure that there are no synchronization needs
*/
-int vt_get_kbd_mode_bit(int console, int bit)
+int vt_get_kbd_mode_bit(unsigned int console, int bit)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
return vc_kbd_mode(kb, bit);
}
@@ -2249,9 +2249,9 @@ int vt_get_kbd_mode_bit(int console, int bit)
* caller must be sure that there are no synchronization needs
*/
-void vt_set_kbd_mode_bit(int console, int bit)
+void vt_set_kbd_mode_bit(unsigned int console, int bit)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
unsigned long flags;
spin_lock_irqsave(&kbd_event_lock, flags);
@@ -2268,9 +2268,9 @@ void vt_set_kbd_mode_bit(int console, int bit)
* caller must be sure that there are no synchronization needs
*/
-void vt_clr_kbd_mode_bit(int console, int bit)
+void vt_clr_kbd_mode_bit(unsigned int console, int bit)
{
- struct kbd_struct *kb = kbd_table + console;
+ struct kbd_struct *kb = &kbd_table[console];
unsigned long flags;
spin_lock_irqsave(&kbd_event_lock, flags);
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index cb72393f92d3..7359c3e80d63 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1219,8 +1219,25 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
new_row_size = new_cols << 1;
new_screen_size = new_row_size * new_rows;
- if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
- return 0;
+ if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) {
+ /*
+ * This function is being called here to cover the case
+ * where the userspace calls the FBIOPUT_VSCREENINFO twice,
+ * passing the same fb_var_screeninfo containing the fields
+ * yres/xres equal to a number non-multiple of vc_font.height
+ * and yres_virtual/xres_virtual equal to number lesser than the
+ * vc_font.height and yres/xres.
+ * In the second call, the struct fb_var_screeninfo isn't
+ * being modified by the underlying driver because of the
+ * if above, and this causes the fbcon_display->vrows to become
+ * negative and it eventually leads to out-of-bound
+ * access by the imageblit function.
+ * To give the correct values to the struct and to not have
+ * to deal with possible errors from the code below, we call
+ * the resize_screen here as well.
+ */
+ return resize_screen(vc, new_cols, new_rows, user);
+ }
if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size)
return -EINVAL;
@@ -3582,8 +3599,9 @@ int __init vty_init(const struct file_operations *console_fops)
vcs_init();
- console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
- if (!console_driver)
+ console_driver = tty_alloc_driver(MAX_NR_CONSOLES, TTY_DRIVER_REAL_RAW |
+ TTY_DRIVER_RESET_TERMIOS);
+ if (IS_ERR(console_driver))
panic("Couldn't allocate console driver\n");
console_driver->name = "tty";
@@ -3594,7 +3612,6 @@ int __init vty_init(const struct file_operations *console_fops)
console_driver->init_termios = tty_std_termios;
if (default_utf8)
console_driver->init_termios.c_iflag |= IUTF8;
- console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
tty_set_operations(console_driver, &con_ops);
if (tty_register_driver(console_driver))
panic("Couldn't register console driver\n");