diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 718e010fcb0485..09baef4ccc39ae 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -50,25 +50,25 @@ static const char serial21285_name[] = "Footbridge UART"; static bool is_enabled(struct uart_port *port, int bit) { - unsigned long private_data = (unsigned long)port->private_data; + unsigned long *private_data = (unsigned long *)&port->private_data; - if (test_bit(bit, &private_data)) + if (test_bit(bit, private_data)) return true; return false; } static void enable(struct uart_port *port, int bit) { - unsigned long private_data = (unsigned long)port->private_data; + unsigned long *private_data = (unsigned long *)&port->private_data; - set_bit(bit, &private_data); + set_bit(bit, private_data); } static void disable(struct uart_port *port, int bit) { - unsigned long private_data = (unsigned long)port->private_data; + unsigned long *private_data = (unsigned long *)&port->private_data; - clear_bit(bit, &private_data); + clear_bit(bit, private_data); } #define is_tx_enabled(port) is_enabled(port, tx_enabled_bit) diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c index ff4b88c637d0e3..bd047e1f9bea71 100644 --- a/drivers/tty/serial/fsl_lpuart.c +++ b/drivers/tty/serial/fsl_lpuart.c @@ -314,9 +314,10 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids); /* Forward declare this for the dma callbacks*/ static void lpuart_dma_tx_complete(void *arg); -static inline bool is_ls1028a_lpuart(struct lpuart_port *sport) +static inline bool is_layerscape_lpuart(struct lpuart_port *sport) { - return sport->devtype == LS1028A_LPUART; + return (sport->devtype == LS1021A_LPUART || + sport->devtype == LS1028A_LPUART); } static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport) @@ -1701,11 +1702,11 @@ static int lpuart32_startup(struct uart_port *port) UARTFIFO_FIFOSIZE_MASK); /* - * The LS1028A has a fixed length of 16 words. Although it supports the - * RX/TXSIZE fields their encoding is different. Eg the reference manual - * states 0b101 is 16 words. + * The LS1021A and LS1028A have a fixed FIFO depth of 16 words. + * Although they support the RX/TXSIZE fields, their encoding is + * different. Eg the reference manual states 0b101 is 16 words. */ - if (is_ls1028a_lpuart(sport)) { + if (is_layerscape_lpuart(sport)) { sport->rxfifo_size = 16; sport->txfifo_size = 16; sport->port.fifosize = sport->txfifo_size; diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 0db53b5b3acf6b..78acc270e39ac6 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -743,8 +743,13 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) return; if ((unsigned)value < ARRAY_SIZE(func_table)) { + unsigned long flags; + + spin_lock_irqsave(&func_buf_lock, flags); if (func_table[value]) puts_queue(vc, func_table[value]); + spin_unlock_irqrestore(&func_buf_lock, flags); + } else pr_err("k_fn called with value=%d\n", value); } @@ -1991,13 +1996,11 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, #undef s #undef v -/* FIXME: This one needs untangling and locking */ +/* FIXME: This one needs untangling */ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) { struct kbsentry *kbs; - char *p; u_char *q; - u_char __user *up; int sz, fnw_sz; int delta; char *first_free, *fj, *fnw; @@ -2023,23 +2026,19 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm) i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC); switch (cmd) { - case KDGKBSENT: - sz = sizeof(kbs->kb_string) - 1; /* sz should have been - a struct member */ - up = user_kdgkb->kb_string; - p = func_table[i]; - if(p) - for ( ; *p && sz; p++, sz--) - if (put_user(*p, up++)) { - ret = -EFAULT; - goto reterr; - } - if (put_user('\0', up)) { - ret = -EFAULT; - goto reterr; - } - kfree(kbs); - return ((p && *p) ? -EOVERFLOW : 0); + case KDGKBSENT: { + /* size should have been a struct member */ + ssize_t len = sizeof(user_kdgkb->kb_string); + + spin_lock_irqsave(&func_buf_lock, flags); + len = strlcpy(kbs->kb_string, func_table[i] ? : "", len); + spin_unlock_irqrestore(&func_buf_lock, flags); + + ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string, + len + 1) ? -EFAULT : 0; + + goto reterr; + } case KDSKBSENT: if (!perm) { ret = -EPERM; diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 0a33b8ababe38f..2321775ef09827 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -549,7 +549,7 @@ static int vt_io_fontreset(struct console_font_op *op) } static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, - struct vc_data *vc) + bool perm, struct vc_data *vc) { struct unimapdesc tmp; @@ -557,9 +557,11 @@ static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, return -EFAULT; switch (cmd) { case PIO_UNIMAP: + if (!perm) + return -EPERM; return con_set_unimap(vc, tmp.entry_ct, tmp.entries); case GIO_UNIMAP: - if (fg_console != vc->vc_num) + if (!perm && fg_console != vc->vc_num) return -EPERM; return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries); @@ -639,10 +641,7 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up, case PIO_UNIMAP: case GIO_UNIMAP: - if (!perm) - return -EPERM; - - return do_unimap_ioctl(cmd, up, vc); + return do_unimap_ioctl(cmd, up, perm, vc); default: return -ENOIOCTLCMD;