diff options
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r-- | drivers/tty/vt/keyboard.c | 62 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 27 |
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"); |