The memcpy() routine can use post-indexed memory access instructions on ARM that would trigger data aborts under KVM. To fix this, use memcpy_fromio/memcpy_toio or the (read|write)[bwlq] family of functions, as these are safe to call on MMIO addresses. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- drivers/mtd/nor/cfi_flash.c | 2 +- drivers/mtd/nor/cfi_flash.h | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nor/cfi_flash.c b/drivers/mtd/nor/cfi_flash.c index 2cb3d5538fbd..ea2373a01827 100644 --- a/drivers/mtd/nor/cfi_flash.c +++ b/drivers/mtd/nor/cfi_flash.c @@ -892,7 +892,7 @@ static int cfi_mtd_read(struct mtd_info *mtd, loff_t from, size_t len, { struct flash_info *info = container_of(mtd, struct flash_info, mtd); - memcpy(buf, info->base + from, len); + memcpy_fromio(buf, info->base + from, len); *retlen = len; return 0; diff --git a/drivers/mtd/nor/cfi_flash.h b/drivers/mtd/nor/cfi_flash.h index 5d3053f97156..a80a979f8c0f 100644 --- a/drivers/mtd/nor/cfi_flash.h +++ b/drivers/mtd/nor/cfi_flash.h @@ -260,7 +260,11 @@ static inline void flash_write32(u32 value, void *addr) static inline void flash_write64(u64 value, void *addr) { - memcpy((void *)addr, &value, 8); +#if BITS_PER_LONG >= 64 + __raw_writeq(value, addr); +#else + memcpy_toio(addr, &value, 8); +#endif } static inline u8 flash_read8(void *addr) @@ -280,8 +284,13 @@ static inline u32 flash_read32(void *addr) static inline u64 flash_read64(void *addr) { - /* No architectures currently implement readq() */ - return *(volatile u64 *)addr; + u64 value; +#if BITS_PER_LONG >= 64 + value = __raw_readq(addr); +#else + memcpy_fromio(&value, addr, 8); +#endif + return value; } /* -- 2.39.5