Skip to content

Commit 7d22af6

Browse files
committed
Merge tag 'tty-5.8-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty into master
Pull tty/serial/fbcon fixes from Greg KH: "Here are some small tty and serial and fbcon fixes for 5.8-rc7 to resolve some reported issues. The fbcon fix is in here as it was simpler to take it this way (and it was acked by the maintainer) as it was related to the vt console fix as well, both of which resolve syzbot-found issues in the console handling code. The other serial driver fixes are for small issues reported in the -rc releases. All of these have been in linux-next with no reported issues" * tag 'tty-5.8-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: serial: exar: Fix GPIO configuration for Sealevel cards based on XR17V35X fbdev: Detect integer underflow at "struct fbcon_ops"->clear_margins. serial: 8250_mtk: Fix high-speed baud rates clamping serial: 8250: fix null-ptr-deref in serial8250_start_tx() serial: tegra: drop bogus NULL tty-port checks serial: tegra: fix CREAD handling for PIO tty: xilinx_uartps: Really fix id assignment vt: Reject zero-sized screen buffer size.
2 parents 17f50e2 + 5fdbe13 commit 7d22af6

File tree

10 files changed

+69
-32
lines changed

10 files changed

+69
-32
lines changed

drivers/tty/serial/8250/8250_core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ static void __init serial8250_isa_init_ports(void)
524524
*/
525525
up->mcr_mask = ~ALPHA_KLUDGE_MCR;
526526
up->mcr_force = ALPHA_KLUDGE_MCR;
527+
serial8250_set_defaults(up);
527528
}
528529

529530
/* chain base port ops to support Remote Supervisor Adapter */
@@ -547,7 +548,6 @@ static void __init serial8250_isa_init_ports(void)
547548
port->membase = old_serial_port[i].iomem_base;
548549
port->iotype = old_serial_port[i].io_type;
549550
port->regshift = old_serial_port[i].iomem_reg_shift;
550-
serial8250_set_defaults(up);
551551

552552
port->irqflags |= irqflag;
553553
if (serial8250_isa_config != NULL)

drivers/tty/serial/8250/8250_exar.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,17 @@ static void setup_gpio(struct pci_dev *pcidev, u8 __iomem *p)
326326
* devices will export them as GPIOs, so we pre-configure them safely
327327
* as inputs.
328328
*/
329-
u8 dir = pcidev->vendor == PCI_VENDOR_ID_EXAR ? 0xff : 0x00;
329+
330+
u8 dir = 0x00;
331+
332+
if ((pcidev->vendor == PCI_VENDOR_ID_EXAR) &&
333+
(pcidev->subsystem_vendor != PCI_VENDOR_ID_SEALEVEL)) {
334+
// Configure GPIO as inputs for Commtech adapters
335+
dir = 0xff;
336+
} else {
337+
// Configure GPIO as outputs for SeaLevel adapters
338+
dir = 0x00;
339+
}
330340

331341
writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
332342
writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);

drivers/tty/serial/8250/8250_mtk.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,21 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
306306
}
307307
#endif
308308

309+
/*
310+
* Store the requested baud rate before calling the generic 8250
311+
* set_termios method. Standard 8250 port expects bauds to be
312+
* no higher than (uartclk / 16) so the baud will be clamped if it
313+
* gets out of that bound. Mediatek 8250 port supports speed
314+
* higher than that, therefore we'll get original baud rate back
315+
* after calling the generic set_termios method and recalculate
316+
* the speed later in this method.
317+
*/
318+
baud = tty_termios_baud_rate(termios);
319+
309320
serial8250_do_set_termios(port, termios, old);
310321

322+
tty_termios_encode_baud_rate(termios, baud, baud);
323+
311324
/*
312325
* Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)
313326
*
@@ -339,6 +352,11 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
339352
*/
340353
spin_lock_irqsave(&port->lock, flags);
341354

355+
/*
356+
* Update the per-port timeout.
357+
*/
358+
uart_update_timeout(port, termios->c_cflag, baud);
359+
342360
/* set DLAB we have cval saved in up->lcr from the call to the core */
343361
serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB);
344362
serial_dl_write(up, quot);

drivers/tty/serial/serial-tegra.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ static void tegra_uart_handle_tx_pio(struct tegra_uart_port *tup)
635635
}
636636

637637
static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup,
638-
struct tty_port *tty)
638+
struct tty_port *port)
639639
{
640640
do {
641641
char flag = TTY_NORMAL;
@@ -653,16 +653,18 @@ static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup,
653653
ch = (unsigned char) tegra_uart_read(tup, UART_RX);
654654
tup->uport.icount.rx++;
655655

656-
if (!uart_handle_sysrq_char(&tup->uport, ch) && tty)
657-
tty_insert_flip_char(tty, ch, flag);
656+
if (uart_handle_sysrq_char(&tup->uport, ch))
657+
continue;
658658

659659
if (tup->uport.ignore_status_mask & UART_LSR_DR)
660660
continue;
661+
662+
tty_insert_flip_char(port, ch, flag);
661663
} while (1);
662664
}
663665

664666
static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup,
665-
struct tty_port *tty,
667+
struct tty_port *port,
666668
unsigned int count)
667669
{
668670
int copied;
@@ -672,17 +674,13 @@ static void tegra_uart_copy_rx_to_tty(struct tegra_uart_port *tup,
672674
return;
673675

674676
tup->uport.icount.rx += count;
675-
if (!tty) {
676-
dev_err(tup->uport.dev, "No tty port\n");
677-
return;
678-
}
679677

680678
if (tup->uport.ignore_status_mask & UART_LSR_DR)
681679
return;
682680

683681
dma_sync_single_for_cpu(tup->uport.dev, tup->rx_dma_buf_phys,
684682
count, DMA_FROM_DEVICE);
685-
copied = tty_insert_flip_string(tty,
683+
copied = tty_insert_flip_string(port,
686684
((unsigned char *)(tup->rx_dma_buf_virt)), count);
687685
if (copied != count) {
688686
WARN_ON(1);

drivers/tty/serial/xilinx_uartps.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,8 +1580,10 @@ static int cdns_uart_probe(struct platform_device *pdev)
15801580
* If register_console() don't assign value, then console_port pointer
15811581
* is cleanup.
15821582
*/
1583-
if (!console_port)
1583+
if (!console_port) {
1584+
cdns_uart_console.index = id;
15841585
console_port = port;
1586+
}
15851587
#endif
15861588

15871589
rc = uart_add_one_port(&cdns_uart_uart_driver, port);
@@ -1594,8 +1596,10 @@ static int cdns_uart_probe(struct platform_device *pdev)
15941596
#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
15951597
/* This is not port which is used for console that's why clean it up */
15961598
if (console_port == port &&
1597-
!(cdns_uart_uart_driver.cons->flags & CON_ENABLED))
1599+
!(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) {
15981600
console_port = NULL;
1601+
cdns_uart_console.index = -1;
1602+
}
15991603
#endif
16001604

16011605
cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,

drivers/tty/vt/vt.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,10 +1092,19 @@ static const struct tty_port_operations vc_port_ops = {
10921092
.destruct = vc_port_destruct,
10931093
};
10941094

1095+
/*
1096+
* Change # of rows and columns (0 means unchanged/the size of fg_console)
1097+
* [this is to be used together with some user program
1098+
* like resize that changes the hardware videomode]
1099+
*/
1100+
#define VC_MAXCOL (32767)
1101+
#define VC_MAXROW (32767)
1102+
10951103
int vc_allocate(unsigned int currcons) /* return 0 on success */
10961104
{
10971105
struct vt_notifier_param param;
10981106
struct vc_data *vc;
1107+
int err;
10991108

11001109
WARN_CONSOLE_UNLOCKED();
11011110

@@ -1125,6 +1134,11 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
11251134
if (!*vc->vc_uni_pagedir_loc)
11261135
con_set_default_unimap(vc);
11271136

1137+
err = -EINVAL;
1138+
if (vc->vc_cols > VC_MAXCOL || vc->vc_rows > VC_MAXROW ||
1139+
vc->vc_screenbuf_size > KMALLOC_MAX_SIZE || !vc->vc_screenbuf_size)
1140+
goto err_free;
1141+
err = -ENOMEM;
11281142
vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL);
11291143
if (!vc->vc_screenbuf)
11301144
goto err_free;
@@ -1143,7 +1157,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
11431157
visual_deinit(vc);
11441158
kfree(vc);
11451159
vc_cons[currcons].d = NULL;
1146-
return -ENOMEM;
1160+
return err;
11471161
}
11481162

11491163
static inline int resize_screen(struct vc_data *vc, int width, int height,
@@ -1158,14 +1172,6 @@ static inline int resize_screen(struct vc_data *vc, int width, int height,
11581172
return err;
11591173
}
11601174

1161-
/*
1162-
* Change # of rows and columns (0 means unchanged/the size of fg_console)
1163-
* [this is to be used together with some user program
1164-
* like resize that changes the hardware videomode]
1165-
*/
1166-
#define VC_RESIZE_MAXCOL (32767)
1167-
#define VC_RESIZE_MAXROW (32767)
1168-
11691175
/**
11701176
* vc_do_resize - resizing method for the tty
11711177
* @tty: tty being resized
@@ -1201,7 +1207,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
12011207
user = vc->vc_resize_user;
12021208
vc->vc_resize_user = 0;
12031209

1204-
if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
1210+
if (cols > VC_MAXCOL || lines > VC_MAXROW)
12051211
return -EINVAL;
12061212

12071213
new_cols = (cols ? cols : vc->vc_cols);
@@ -1212,7 +1218,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
12121218
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
12131219
return 0;
12141220

1215-
if (new_screen_size > KMALLOC_MAX_SIZE)
1221+
if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size)
12161222
return -EINVAL;
12171223
newscreen = kzalloc(new_screen_size, GFP_USER);
12181224
if (!newscreen)
@@ -3393,6 +3399,7 @@ static int __init con_init(void)
33933399
INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
33943400
tty_port_init(&vc->port);
33953401
visual_init(vc, currcons, 1);
3402+
/* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */
33963403
vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
33973404
vc_init(vc, vc->vc_rows, vc->vc_cols,
33983405
currcons || !vc->vc_sw->con_save_screen);

drivers/video/fbdev/core/bitblit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,15 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info,
216216
region.color = color;
217217
region.rop = ROP_COPY;
218218

219-
if (rw && !bottom_only) {
219+
if ((int) rw > 0 && !bottom_only) {
220220
region.dx = info->var.xoffset + rs;
221221
region.dy = 0;
222222
region.width = rw;
223223
region.height = info->var.yres_virtual;
224224
info->fbops->fb_fillrect(info, &region);
225225
}
226226

227-
if (bh) {
227+
if ((int) bh > 0) {
228228
region.dx = info->var.xoffset;
229229
region.dy = info->var.yoffset + bs;
230230
region.width = rs;

drivers/video/fbdev/core/fbcon_ccw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,15 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
201201
region.color = color;
202202
region.rop = ROP_COPY;
203203

204-
if (rw && !bottom_only) {
204+
if ((int) rw > 0 && !bottom_only) {
205205
region.dx = 0;
206206
region.dy = info->var.yoffset;
207207
region.height = rw;
208208
region.width = info->var.xres_virtual;
209209
info->fbops->fb_fillrect(info, &region);
210210
}
211211

212-
if (bh) {
212+
if ((int) bh > 0) {
213213
region.dx = info->var.xoffset + bs;
214214
region.dy = 0;
215215
region.height = info->var.yres_virtual;

drivers/video/fbdev/core/fbcon_cw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,15 +184,15 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
184184
region.color = color;
185185
region.rop = ROP_COPY;
186186

187-
if (rw && !bottom_only) {
187+
if ((int) rw > 0 && !bottom_only) {
188188
region.dx = 0;
189189
region.dy = info->var.yoffset + rs;
190190
region.height = rw;
191191
region.width = info->var.xres_virtual;
192192
info->fbops->fb_fillrect(info, &region);
193193
}
194194

195-
if (bh) {
195+
if ((int) bh > 0) {
196196
region.dx = info->var.xoffset;
197197
region.dy = info->var.yoffset;
198198
region.height = info->var.yres;

drivers/video/fbdev/core/fbcon_ud.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,15 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
231231
region.color = color;
232232
region.rop = ROP_COPY;
233233

234-
if (rw && !bottom_only) {
234+
if ((int) rw > 0 && !bottom_only) {
235235
region.dy = 0;
236236
region.dx = info->var.xoffset;
237237
region.width = rw;
238238
region.height = info->var.yres_virtual;
239239
info->fbops->fb_fillrect(info, &region);
240240
}
241241

242-
if (bh) {
242+
if ((int) bh > 0) {
243243
region.dy = info->var.yoffset;
244244
region.dx = info->var.xoffset;
245245
region.height = bh;

0 commit comments

Comments
 (0)