On Sat, Mar 14, 2026, at 04:06, Daniel Palmer wrote:
> virtio-mmio registers are always little endian even on machines
> where peripheral registers are normally big endian.
>
> At least on nommu, non-coldfire, m68k (see: arch/m68k/include/asm/io_no.h)
> readl() and friends are defined to the raw versions. So the value from
> the bus is returned as is.
>
> Since virtio-mmio is a bit special and will always be little endian
> even if that is different to the machine's convention use the raw
> accessors and do the endian swap, where needed, in house.
>
> There are some places in the code where the little endian values are
> actually wanted and we currently swap those back again. If we don't
> swap them in the first place maybe that saves some unneeded swapping?
>
> Signed-off-by: Daniel Palmer <[email protected]>

I don't think this is safe to do in portable code

> -
> +/*
> + * The virtio registers are always little endian, even on machines
> + * where everything else is big endian. readl()/write() could use the
> + * value from the bus as-is or endian swap it from little endian.
> + * To avoid confusion use the raw accessors and do the swap here.
> + */
> +#define virtio_mmio_readl(addr)              le32_to_cpu(__raw_readl(addr))
> +#define virtio_mmio_writel(value, addr)      
> __raw_writel(cpu_to_le32(value), addr)

The __raw accessors are not well-defined across architectures and
don't technically guarantee anything about the access beyond being
usable as part of a memory access to byte data behind a bridge.
In particular using these for MMIO registers (real or emulated)
misses the bits about

 - atomicity of the access
 - emulating them from virtualization host
 - actual endianess
 - ordering against memory or MMIO accesses

I think a better approach would be to change the dragonball
specific device drivers to just use iowrite32_be/ioread32_be
instead of writel/readl, and make the behavior consistent
with the rest of Linux (including io_mm.h and coldfire),
using the generic definition:

diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index 516371d5587a..c39db8798ef2 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -96,15 +96,6 @@ static inline void writel(u32 value, volatile void __iomem 
*addr)
                __raw_writel(swab32(value), addr);
 }
 
-#else
-
-#define readb __raw_readb
-#define readw __raw_readw
-#define readl __raw_readl
-#define writeb __raw_writeb
-#define writew __raw_writew
-#define writel __raw_writel
-
 #endif /* IOMEMBASE */
 
 #if defined(CONFIG_PCI)

Can you try if this works?

   Arnd

Reply via email to