aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2021-07-23 09:43:12 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-27 12:17:20 +0200
commit0524513afe45a4a79f418c0377160b7712cab78a (patch)
treeeab43a3f41c183818029805709a1abbf6625ef21 /drivers/tty/hvc
parenthvsi: don't panic on tty_register_driver failure (diff)
downloadlinux-dev-0524513afe45a4a79f418c0377160b7712cab78a.tar.xz
linux-dev-0524513afe45a4a79f418c0377160b7712cab78a.zip
tty: don't store semi-state into tty drivers
When a tty driver pointer is used as a return value of struct console's device() hook, don't store a semi-state into global variable which holds the tty driver. It could mean console::device() would return a bogus value. This is important esp. after the next patch where we switch from alloc_tty_driver to tty_alloc_driver. tty_alloc_driver returns ERR_PTR in case of error and that might have unexpected results as the code doesn't expect this. Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com> Cc: Helge Deller <deller@gmx.de> Cc: Chris Zankel <chris@zankel.net> Cc: Max Filippov <jcmvbkbc@gmail.com> Cc: Laurentiu Tudor <laurentiu.tudor@nxp.com> Cc: Felipe Balbi <balbi@kernel.org> Reviewed-by: Max Filippov <jcmvbkbc@gmail.com> Acked-by: Helge Deller <deller@gmx.de> # parisc Signed-off-by: Jiri Slaby <jslaby@suse.cz> Link: https://lore.kernel.org/r/20210723074317.32690-4-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/hvsi.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index f0bc8e780051..bfde7b1936a5 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -1038,29 +1038,30 @@ static const struct tty_operations hvsi_ops = {
static int __init hvsi_init(void)
{
+ struct tty_driver *driver;
int i, ret;
- hvsi_driver = alloc_tty_driver(hvsi_count);
- if (!hvsi_driver)
+ driver = alloc_tty_driver(hvsi_count);
+ if (!driver)
return -ENOMEM;
- hvsi_driver->driver_name = "hvsi";
- hvsi_driver->name = "hvsi";
- hvsi_driver->major = HVSI_MAJOR;
- hvsi_driver->minor_start = HVSI_MINOR;
- hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM;
- hvsi_driver->init_termios = tty_std_termios;
- hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
- hvsi_driver->init_termios.c_ispeed = 9600;
- hvsi_driver->init_termios.c_ospeed = 9600;
- hvsi_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(hvsi_driver, &hvsi_ops);
+ driver->driver_name = "hvsi";
+ driver->name = "hvsi";
+ driver->major = HVSI_MAJOR;
+ driver->minor_start = HVSI_MINOR;
+ driver->type = TTY_DRIVER_TYPE_SYSTEM;
+ driver->init_termios = tty_std_termios;
+ driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
+ driver->init_termios.c_ispeed = 9600;
+ driver->init_termios.c_ospeed = 9600;
+ driver->flags = TTY_DRIVER_REAL_RAW;
+ tty_set_operations(driver, &hvsi_ops);
for (i=0; i < hvsi_count; i++) {
struct hvsi_struct *hp = &hvsi_ports[i];
int ret = 1;
- tty_port_link_device(&hp->port, hvsi_driver, i);
+ tty_port_link_device(&hp->port, driver, i);
ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp);
if (ret)
@@ -1069,12 +1070,14 @@ static int __init hvsi_init(void)
}
hvsi_wait = wait_for_state; /* irqs active now */
- ret = tty_register_driver(hvsi_driver);
+ ret = tty_register_driver(driver);
if (ret) {
pr_err("Couldn't register hvsi console driver\n");
goto err_free_irq;
}
+ hvsi_driver = driver;
+
printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count);
return 0;
@@ -1085,7 +1088,7 @@ err_free_irq:
free_irq(hp->virq, hp);
}
- tty_driver_kref_put(hvsi_driver);
+ tty_driver_kref_put(driver);
return ret;
}