[PATCH v4] alpha: add a barrier after outb, outw and outl
From: Mikulas Patocka <mpatocka@redhat.com>
Date: 2020-05-07 15:46:50
Also in:
linux-rtc, linux-serial
The patch 92d7223a74235054f2aa7227d207d9c57f84dca0 ("alpha: io: reorder
barriers to guarantee writeX() and iowriteX() ordering #2") broke boot on
the Alpha Avanti platform.
The patch changes timing between accesses to the ISA bus, in particular,
it reduces the time between "write" access and a subsequent "read" access.
This causes lock-up when accessing the real time clock and serial ports.
This patch fixes the bug by adding a memory barrier after the functions
that access the ISA ports - outb, outw, outl. The barrier causes that
there is some delay between the write to an IO port and a subsequent read.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Fixes: 92d7223a7423 ("alpha: io: reorder barriers to guarantee writeX() and iowriteX() ordering #2")
Cc: stable@vger.kernel.org # v4.17+
---
arch/alpha/include/asm/io.h | 3 +++
arch/alpha/kernel/io.c | 3 +++
2 files changed, 6 insertions(+)
Index: linux-stable/arch/alpha/include/asm/io.h
===================================================================--- linux-stable.orig/arch/alpha/include/asm/io.h 2020-05-07 17:36:58.000000000 +0200
+++ linux-stable/arch/alpha/include/asm/io.h 2020-05-07 17:36:58.000000000 +0200@@ -347,11 +347,13 @@ extern inline u16 inw(unsigned long port extern inline void outb(u8 b, unsigned long port) { iowrite8(b, ioport_map(port, 1)); + mb(); } extern inline void outw(u16 b, unsigned long port) { iowrite16(b, ioport_map(port, 2)); + mb(); } #endif
@@ -377,6 +379,7 @@ extern inline u32 inl(unsigned long port extern inline void outl(u32 b, unsigned long port) { iowrite32(b, ioport_map(port, 4)); + mb(); } #endif
Index: linux-stable/arch/alpha/kernel/io.c ===================================================================
--- linux-stable.orig/arch/alpha/kernel/io.c 2020-05-07 17:36:58.000000000 +0200
+++ linux-stable/arch/alpha/kernel/io.c 2020-05-07 17:36:58.000000000 +0200@@ -78,16 +78,19 @@ u32 inl(unsigned long port) void outb(u8 b, unsigned long port) { iowrite8(b, ioport_map(port, 1)); + mb(); } void outw(u16 b, unsigned long port) { iowrite16(b, ioport_map(port, 2)); + mb(); } void outl(u32 b, unsigned long port) { iowrite32(b, ioport_map(port, 4)); + mb(); } EXPORT_SYMBOL(inb);