linux-stable/drivers/tty/serial/8250
Maciej W. Rozycki e5227c5109 serial: 8250: Mask out floating 16/32-bit bus bits
Make sure only actual 8 bits of the IIR register are used in determining
the port type in `autoconfig'.

The `serial_in' port accessor returns the `unsigned int' type, meaning
that with UPIO_AU, UPIO_MEM16, UPIO_MEM32, and UPIO_MEM32BE access types
more than 8 bits of data are returned, of which the high order bits will
often come from bus lines that are left floating in the data phase.  For
example with the MIPS Malta board's CBUS UART, where the registers are
aligned on 8-byte boundaries and which uses 32-bit accesses, data as
follows is returned:

YAMON> dump -32 0xbf000900 0x40

BF000900: 1F000942 1F000942 1F000900 1F000900  ...B...B........
BF000910: 1F000901 1F000901 1F000900 1F000900  ................
BF000920: 1F000900 1F000900 1F000960 1F000960  ...........`...`
BF000930: 1F000900 1F000900 1F0009FF 1F0009FF  ................

YAMON>

Evidently high-order 24 bits return values previously driven in the
address phase (the 3 highest order address bits used with the command
above are masked out in the simple virtual address mapping used here and
come out at zeros on the external bus), a common scenario with bus lines
left floating, due to bus capacitance.

Consequently when the value of IIR, mapped at 0x1f000910, is retrieved
in `autoconfig', it comes out at 0x1f0009c1 and when it is right-shifted
by 6 and then assigned to 8-bit `scratch' variable, the value calculated
is 0x27, not one of 0, 1, 2, 3 expected in port type determination.

Fix the issue then, by assigning the value returned from `serial_in' to
`scratch' first, which masks out 24 high-order bits retrieved, and only
then right-shift the resulting 8-bit data quantity, producing the value
of 3 in this case, as expected.  Fix the same issue in `serial_dl_read'.

The problem first appeared with Linux 2.6.9-rc3 which predates our repo
history, but the origin could be identified with the old MIPS/Linux repo
also at: <git://git.kernel.org/pub/scm/linux/kernel/git/ralf/linux.git>
as commit e0d2356c0777 ("Merge with Linux 2.6.9-rc3."), where code in
`serial_in' was updated with this case:

+	case UPIO_MEM32:
+		return readl(up->port.membase + offset);
+

which made it produce results outside the unsigned 8-bit range for the
first time, though obviously it is system dependent what actual values
appear in the high order bits retrieved and it may well have been zeros
in the relevant positions with the system the change originally was
intended for.  It is at that point that code in `autoconf' should have
been updated accordingly, but clearly it was overlooked.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org # v2.6.12+
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106260516220.37803@angie.orcam.me.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-07-21 12:52:14 +02:00
..
8250.h serial: 8250: Use BIT(x) for UART_{CAP,BUG}_* 2021-05-20 17:14:50 +02:00
8250_accent.c
8250_acorn.c
8250_aspeed_vuart.c Merge 5.13-rc4 into tty-next 2021-05-31 09:44:28 +02:00
8250_bcm2835aux.c serial: 8250: Simplify with dev_err_probe() 2020-09-04 17:14:29 +02:00
8250_bcm7271.c serial: 8250: Make symbol 'brcmuart_debugfs_root' static 2021-04-02 16:12:27 +02:00
8250_boca.c
8250_core.c tty/serial: make port of serial8250_register_8250_port const 2021-05-20 16:59:14 +02:00
8250_dma.c
8250_dw.c serial: 8250_dw: Add device HID for new AMD UART controller 2021-05-13 17:08:42 +02:00
8250_dwlib.c
8250_dwlib.h tty: serial: Use the correct style for SPDX License Identifier 2020-03-07 09:52:01 +01:00
8250_early.c tty: serial: 8250: 8250_port: Move prototypes to shared location 2020-11-13 15:28:12 +01:00
8250_em.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
8250_exar.c Linux 5.13-rc6 2021-06-14 09:14:43 +02:00
8250_exar_st16c554.c
8250_fintek.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
8250_fourport.c
8250_fsl.c serial: do not restore interrupt state in sysrq helper 2021-04-22 12:04:26 +02:00
8250_gsc.c remove ioremap_nocache and devm_ioremap_nocache 2020-01-06 09:45:59 +01:00
8250_hp300.c
8250_hub6.c
8250_ingenic.c serial: 8250: Simplify with dev_err_probe() 2020-09-04 17:14:29 +02:00
8250_ioc3.c Fix up remaining devm_ioremap_nocache() in SGI IOC3 8250 UART driver 2020-02-08 14:19:39 -08:00
8250_lpc18xx.c
8250_lpss.c serial: 8250_lpss: Add ->setup() for Elkhart Lake ports 2020-03-06 13:31:19 +01:00
8250_men_mcb.c 8250-men-mcb: fix signed/unsigned confusion 2020-06-27 16:12:45 +02:00
8250_mid.c
8250_mtk.c serial: 8250-mtk: Fix reference leak in mtk8250_probe 2020-11-26 21:19:58 +01:00
8250_of.c serial: 8250: of: Check for CONFIG_SERIAL_8250_BCM7271 2021-05-13 16:22:48 +02:00
8250_omap.c serial: 8250: 8250_omap: Fix possible interrupt storm on K3 SoCs 2021-06-24 14:51:33 +02:00
8250_pci.c serial: 8250: Correct the clock for OxSemi PCIe devices 2021-06-16 09:20:29 +02:00
8250_pnp.c
8250_port.c serial: 8250: Mask out floating 16/32-bit bus bits 2021-07-21 12:52:14 +02:00
8250_pxa.c serial: 8250_pxa: Switch to use platform_get_irq() 2020-06-27 16:12:56 +02:00
8250_tegra.c 8250_tegra: clean up tegra_uart_handle_break 2021-01-07 16:17:31 +01:00
8250_uniphier.c treewide: Use fallthrough pseudo-keyword 2020-08-23 17:36:59 -05:00
Kconfig serial: extend compile-test coverage 2021-04-22 13:12:13 +02:00
Makefile serial: 8250: Add new 8250-core based Broadcom STB driver 2021-03-26 15:18:30 +01:00
serial_cs.c serial_cs: Add Option International GSM-Ready 56K/ISDN modem 2021-06-16 09:20:29 +02:00