Re: [PATCH] add delay between port write and port read

From: Mikulas Patocka (mpatocka@xxxxxxxxxx)
Date: Tue Feb 19 2019 - 08:44:40 EST




On Tue, 19 Feb 2019, Mikulas Patocka wrote:

> The patches cd0e00c106722eca40b38ebf11cf134c01901086 and
> 92d7223a74235054f2aa7227d207d9c57f84dca0 fix a theoretical issue where the
> code didn't follow the specification. Unfortunatelly, they also reduce
> timing when port write is followed by a port read.
>
> These reduced timing cause hang on boot on the Avanti platform when
> probing serial ports. This patch adds memory barrier after the outb, outw,
> outl functions, so that there is delay between port write and subsequent
> port read - just like before.
>
> Fixes: cd0e00c10672 ("alpha: io: reorder barriers to guarantee writeX() and iowriteX() ordering")
> Cc: stable@xxxxxxxxxxxxxxx # v4.17+

you can also add:

Tested-by: Mikulas Patocka <mpatocka@xxxxxxxxxx>

> ---
> arch/alpha/kernel/io.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> Index: linux-stable/arch/alpha/kernel/io.c
> ===================================================================
> --- linux-stable.orig/arch/alpha/kernel/io.c 2019-02-19 14:06:03.000000000 +0100
> +++ linux-stable/arch/alpha/kernel/io.c 2019-02-19 14:12:29.000000000 +0100
> @@ -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);
> @@ -336,6 +339,7 @@ void iowrite8_rep(void __iomem *port, co
> void outsb(unsigned long port, const void *src, unsigned long count)
> {
> iowrite8_rep(ioport_map(port, 1), src, count);
> + mb();
> }
>
> EXPORT_SYMBOL(iowrite8_rep);
> @@ -376,6 +380,7 @@ void iowrite16_rep(void __iomem *port, c
> void outsw(unsigned long port, const void *src, unsigned long count)
> {
> iowrite16_rep(ioport_map(port, 2), src, count);
> + mb();
> }
>
> EXPORT_SYMBOL(iowrite16_rep);
> @@ -408,6 +413,7 @@ void iowrite32_rep(void __iomem *port, c
> void outsl(unsigned long port, const void *src, unsigned long count)
> {
> iowrite32_rep(ioport_map(port, 4), src, count);
> + mb();
> }
>
> EXPORT_SYMBOL(iowrite32_rep);
>