Skip to content

Commit 2754a42

Browse files
committed
Merge tag 'tty-5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial fixes from Greg KH: "Here are some small TTY and Serial driver fixes for reported issues for 5.10-rc2. They include: - vt ioctl bugfix for reported problems - fsl_lpuart serial driver fix - 21285 serial driver bugfix All have been in linux-next with no reported issues" * tag 'tty-5.10-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: vt_ioctl: fix GIO_UNIMAP regression vt: keyboard, extend func_buf_lock to readers vt: keyboard, simplify vt_kdgkbsent tty: serial: fsl_lpuart: LS1021A has a FIFO size of 16 words, like LS1028A tty: serial: 21285: fix lockup on open
2 parents 9b5ff3c + d546547 commit 2754a42

4 files changed

Lines changed: 37 additions & 38 deletions

File tree

drivers/tty/serial/21285.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,25 +50,25 @@ static const char serial21285_name[] = "Footbridge UART";
5050

5151
static bool is_enabled(struct uart_port *port, int bit)
5252
{
53-
unsigned long private_data = (unsigned long)port->private_data;
53+
unsigned long *private_data = (unsigned long *)&port->private_data;
5454

55-
if (test_bit(bit, &private_data))
55+
if (test_bit(bit, private_data))
5656
return true;
5757
return false;
5858
}
5959

6060
static void enable(struct uart_port *port, int bit)
6161
{
62-
unsigned long private_data = (unsigned long)port->private_data;
62+
unsigned long *private_data = (unsigned long *)&port->private_data;
6363

64-
set_bit(bit, &private_data);
64+
set_bit(bit, private_data);
6565
}
6666

6767
static void disable(struct uart_port *port, int bit)
6868
{
69-
unsigned long private_data = (unsigned long)port->private_data;
69+
unsigned long *private_data = (unsigned long *)&port->private_data;
7070

71-
clear_bit(bit, &private_data);
71+
clear_bit(bit, private_data);
7272
}
7373

7474
#define is_tx_enabled(port) is_enabled(port, tx_enabled_bit)

drivers/tty/serial/fsl_lpuart.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,10 @@ MODULE_DEVICE_TABLE(of, lpuart_dt_ids);
314314
/* Forward declare this for the dma callbacks*/
315315
static void lpuart_dma_tx_complete(void *arg);
316316

317-
static inline bool is_ls1028a_lpuart(struct lpuart_port *sport)
317+
static inline bool is_layerscape_lpuart(struct lpuart_port *sport)
318318
{
319-
return sport->devtype == LS1028A_LPUART;
319+
return (sport->devtype == LS1021A_LPUART ||
320+
sport->devtype == LS1028A_LPUART);
320321
}
321322

322323
static inline bool is_imx8qxp_lpuart(struct lpuart_port *sport)
@@ -1701,11 +1702,11 @@ static int lpuart32_startup(struct uart_port *port)
17011702
UARTFIFO_FIFOSIZE_MASK);
17021703

17031704
/*
1704-
* The LS1028A has a fixed length of 16 words. Although it supports the
1705-
* RX/TXSIZE fields their encoding is different. Eg the reference manual
1706-
* states 0b101 is 16 words.
1705+
* The LS1021A and LS1028A have a fixed FIFO depth of 16 words.
1706+
* Although they support the RX/TXSIZE fields, their encoding is
1707+
* different. Eg the reference manual states 0b101 is 16 words.
17071708
*/
1708-
if (is_ls1028a_lpuart(sport)) {
1709+
if (is_layerscape_lpuart(sport)) {
17091710
sport->rxfifo_size = 16;
17101711
sport->txfifo_size = 16;
17111712
sport->port.fifosize = sport->txfifo_size;

drivers/tty/vt/keyboard.c

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,13 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
743743
return;
744744

745745
if ((unsigned)value < ARRAY_SIZE(func_table)) {
746+
unsigned long flags;
747+
748+
spin_lock_irqsave(&func_buf_lock, flags);
746749
if (func_table[value])
747750
puts_queue(vc, func_table[value]);
751+
spin_unlock_irqrestore(&func_buf_lock, flags);
752+
748753
} else
749754
pr_err("k_fn called with value=%d\n", value);
750755
}
@@ -1991,13 +1996,11 @@ int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
19911996
#undef s
19921997
#undef v
19931998

1994-
/* FIXME: This one needs untangling and locking */
1999+
/* FIXME: This one needs untangling */
19952000
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
19962001
{
19972002
struct kbsentry *kbs;
1998-
char *p;
19992003
u_char *q;
2000-
u_char __user *up;
20012004
int sz, fnw_sz;
20022005
int delta;
20032006
char *first_free, *fj, *fnw;
@@ -2023,23 +2026,19 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
20232026
i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
20242027

20252028
switch (cmd) {
2026-
case KDGKBSENT:
2027-
sz = sizeof(kbs->kb_string) - 1; /* sz should have been
2028-
a struct member */
2029-
up = user_kdgkb->kb_string;
2030-
p = func_table[i];
2031-
if(p)
2032-
for ( ; *p && sz; p++, sz--)
2033-
if (put_user(*p, up++)) {
2034-
ret = -EFAULT;
2035-
goto reterr;
2036-
}
2037-
if (put_user('\0', up)) {
2038-
ret = -EFAULT;
2039-
goto reterr;
2040-
}
2041-
kfree(kbs);
2042-
return ((p && *p) ? -EOVERFLOW : 0);
2029+
case KDGKBSENT: {
2030+
/* size should have been a struct member */
2031+
ssize_t len = sizeof(user_kdgkb->kb_string);
2032+
2033+
spin_lock_irqsave(&func_buf_lock, flags);
2034+
len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
2035+
spin_unlock_irqrestore(&func_buf_lock, flags);
2036+
2037+
ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
2038+
len + 1) ? -EFAULT : 0;
2039+
2040+
goto reterr;
2041+
}
20432042
case KDSKBSENT:
20442043
if (!perm) {
20452044
ret = -EPERM;

drivers/tty/vt/vt_ioctl.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -549,17 +549,19 @@ static int vt_io_fontreset(struct console_font_op *op)
549549
}
550550

551551
static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
552-
struct vc_data *vc)
552+
bool perm, struct vc_data *vc)
553553
{
554554
struct unimapdesc tmp;
555555

556556
if (copy_from_user(&tmp, user_ud, sizeof tmp))
557557
return -EFAULT;
558558
switch (cmd) {
559559
case PIO_UNIMAP:
560+
if (!perm)
561+
return -EPERM;
560562
return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
561563
case GIO_UNIMAP:
562-
if (fg_console != vc->vc_num)
564+
if (!perm && fg_console != vc->vc_num)
563565
return -EPERM;
564566
return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
565567
tmp.entries);
@@ -639,10 +641,7 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
639641

640642
case PIO_UNIMAP:
641643
case GIO_UNIMAP:
642-
if (!perm)
643-
return -EPERM;
644-
645-
return do_unimap_ioctl(cmd, up, vc);
644+
return do_unimap_ioctl(cmd, up, perm, vc);
646645

647646
default:
648647
return -ENOIOCTLCMD;

0 commit comments

Comments
 (0)