Hi Patrice,

On 2/26/21 1:44 PM, Patrice Chotard wrote:
At early U-Boot stage, before relocation, MMU is not yet configured
and disabled. DDR may not be configured with the correct memory
attributes (can be configured in MT_DEVICE instead of MT_MEMORY).

In this case, usage of memcpy_{from, to}io() may leads to synchronous
abort in AARCH64 in case the normal memory address is not 64Bits aligned.

To avoid such situation, forbid usage of normal memory cast to (u64 *) in
case MMU is not enabled.

Signed-off-by: Patrice Chotard <patrice.chot...@foss.st.com>
Cc: mark.kette...@xs4all.nl
---

  arch/arm/cpu/armv8/cache_v8.c | 10 ++++++++++
  arch/arm/include/asm/io.h     | 25 +++++++++++++++----------
  include/cpu_func.h            |  1 +
  3 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 15cecb5e0b..3de18c7675 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -719,6 +719,11 @@ int icache_status(void)
        return (get_sctlr() & CR_I) != 0;
  }
+int mmu_status(void)
+{
+       return (get_sctlr() & CR_M) != 0;
+}
+
  void invalidate_icache_all(void)
  {
        __asm_invalidate_icache_all();
@@ -740,6 +745,11 @@ int icache_status(void)
        return 0;
  }
+int mmu_status(void)
+{
+       return 0;
+}
+
  void invalidate_icache_all(void)
  {
  }
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index df264a170b..36b840378a 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -338,6 +338,7 @@ extern void __readwrite_bug(const char *fn);
/* Optimized copy functions to read from/write to IO sapce */
  #ifdef CONFIG_ARM64
+#include <cpu_func.h>
  /*
   * Copy data from IO memory space to "real" memory space.
   */
@@ -351,11 +352,13 @@ void __memcpy_fromio(void *to, const volatile void 
__iomem *from, size_t count)
                count--;
        }
- while (count >= 8) {
-               *(u64 *)to = __raw_readq(from);
-               from += 8;
-               to += 8;
-               count -= 8;
+       if (mmu_status()) {
+               while (count >= 8) {
+                       *(u64 *)to = __raw_readq(from);
+                       from += 8;
+                       to += 8;
+                       count -= 8;
+               }
        }
while (count) {
@@ -379,11 +382,13 @@ void __memcpy_toio(volatile void __iomem *to, const void 
*from, size_t count)
                count--;
        }
- while (count >= 8) {
-               __raw_writeq(*(u64 *)from, to);
-               from += 8;
-               to += 8;
-               count -= 8;
+       if (mmu_status()) {
+               while (count >= 8) {
+                       __raw_writeq(*(u64 *)from, to);
+                       from += 8;
+                       to += 8;
+                       count -= 8;
+               }
        }
while (count) {
diff --git a/include/cpu_func.h b/include/cpu_func.h
index 8aa825daa4..a8806dd295 100644
--- a/include/cpu_func.h
+++ b/include/cpu_func.h
@@ -59,6 +59,7 @@ int dcache_status(void);
  void dcache_enable(void);
  void dcache_disable(void);
  void mmu_disable(void);
+int mmu_status(void);
/* arch/$(ARCH)/lib/cache.c */
  void enable_caches(void);


Reviewed-by: Patrick Delaunay <patrick.delau...@foss.st.com>

Thanks
Patrick

Reply via email to