ARM: 9474/1: io: avoid KASAN instrumentation of raw halfword I/O

commit d59ed80371 upstream.

For CPUs before ARMv6, __raw_readw() and __raw_writew() are implemented
as C volatile halfword accesses so the compiler can generate an access
sequence that is safe for those machines. With KASAN enabled, those C
accesses are instrumented as normal memory accesses.

That is not valid for MMIO. On ARM926/VersatilePB with KASAN enabled,
PL011 probing traps in __asan_store2() while registering the UART, because
the instrumented writew() tries to check KASAN shadow for an MMIO address.

Keep the existing volatile halfword access, but move the ARMv5 definitions
into __no_kasan_or_inline functions so raw MMIO halfword accesses are not
instrumented by KASAN. The ARMv6-and-newer inline assembly path is
unchanged.

Fixes: 421015713b ("ARM: 9017/2: Enable KASan for ARM")
Cc: stable@vger.kernel.org # v5.11+
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Karl Mehltretter
2026-06-19 13:39:33 +02:00
committed by Greg Kroah-Hartman
parent c35c0763af
commit b6290cc96d
+13 -2
View File
@@ -56,8 +56,19 @@ void __raw_readsl(const volatile void __iomem *addr, void *data, int longlen);
* the bus. Rather than special-case the machine, just let the compiler
* generate the access for CPUs prior to ARMv6.
*/
#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
#define __raw_writew(v,a) ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
#define __raw_writew __raw_writew
static __no_kasan_or_inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
__chk_io_ptr(addr);
*(volatile unsigned short __force *)addr = val;
}
#define __raw_readw __raw_readw
static __no_kasan_or_inline u16 __raw_readw(const volatile void __iomem *addr)
{
__chk_io_ptr(addr);
return *(const volatile unsigned short __force *)addr;
}
#else
/*
* When running under a hypervisor, we want to avoid I/O accesses with