diff mbox series

[v2,2/2] arm64: Update memcpy_{from, to}io() helpers

Message ID 20210719112135.v2.2.I43db93d122a7c13b1505b1f565127780cad729ef@changeid
State Accepted
Commit 268f6ac1f95c1734e7eea369e93062e52c4aa04a
Delegated to: Tom Rini
Headers show
Series arm64: Update memcpy_{from, to}io() helpers | expand

Commit Message

Patrick Delaunay July 19, 2021, 9:21 a.m. UTC
From: Patrice Chotard <patrice.chotard@foss.st.com>

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.chotard@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Cc: mark.kettenis@xs4all.nl
Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

(no changes since v1)

 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(-)

Comments

Tom Rini July 29, 2021, 4:49 p.m. UTC | #1
On Mon, Jul 19, 2021 at 11:21:51AM +0200, Patrick Delaunay wrote:

> From: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> 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.chotard@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Cc: mark.kettenis@xs4all.nl
> Signed-off-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Applied to u-boot/master, thanks!
diff mbox series

Patch

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 c3a66f0405..23cd5eca39 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);