[openwrt/openwrt] generic: MIPS: Add barriers between dcache & icache flushes

LEDE Commits lede-commits at lists.infradead.org
Sat Mar 4 04:09:49 PST 2023


blocktrron pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/26bc8f68767e1ec6e33a84ef397e4c38d5968462

commit 26bc8f68767e1ec6e33a84ef397e4c38d5968462
Author: David Bauer <mail at david-bauer.net>
AuthorDate: Thu Mar 2 16:53:59 2023 +0100

    generic: MIPS: Add barriers between dcache & icache flushes
    
    This fixes spurious boot-errors with some ath79 MIPS 74Kc boards such
    as the AC Lite as well as Archer C7 v2.
    
    The missing barrier leads to the icache flush being executed before the
    dcache writeback, which results in the CPU executing the dummy infinite
    loop in tlbmiss_handler_setup_pgd.
    
    Applying this patch from upstream ensures the dcache is written back
    before flushing the icache.
    
    Signed-off-by: David Bauer <mail at david-bauer.net>
---
 ...dd-barriers-between-dcache-icache-flushes.patch | 71 ++++++++++++++++++++++
 ...dd-barriers-between-dcache-icache-flushes.patch | 71 ++++++++++++++++++++++
 2 files changed, 142 insertions(+)

diff --git a/target/linux/generic/pending-5.10/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-5.10/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
new file mode 100644
index 0000000000..726c884027
--- /dev/null
+++ b/target/linux/generic/pending-5.10/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
@@ -0,0 +1,71 @@
+From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton at imgtec.com>
+Date: Mon, 22 Feb 2016 18:09:44 +0000
+Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes
+
+Index-based cache operations may be arbitrarily reordered by out of
+order CPUs. Thus code which writes back the dcache & then invalidates
+the icache using indexed cache ops must include a barrier between
+operating on the 2 caches in order to prevent the scenario in which:
+
+  - icache invalidation occurs.
+
+  - icache fetch occurs, due to speculation.
+
+  - dcache writeback occurs.
+
+If the above were allowed to happen then the icache would contain stale
+data. Forcing the dcache writeback to complete before the icache
+invalidation avoids this.
+
+Signed-off-by: Paul Burton <paul.burton at imgtec.com>
+Cc: James Hogan <james.hogan at imgtec.com>
+---
+ arch/mips/mm/c-r4k.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/mm/c-r4k.c
++++ b/arch/mips/mm/c-r4k.c
+@@ -515,6 +515,7 @@ static inline void local_r4k___flush_cac
+ 
+ 	default:
+ 		r4k_blast_dcache();
++		mb(); /* cache instructions may be reordered */
+ 		r4k_blast_icache();
+ 		break;
+ 	}
+@@ -595,8 +596,10 @@ static inline void local_r4k_flush_cache
+ 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+ 		r4k_blast_dcache();
+ 	/* If executable, blast stale lines from icache */
+-	if (exec)
++	if (exec) {
++		mb(); /* cache instructions may be reordered */
+ 		r4k_blast_icache();
++	}
+ }
+ 
+ static void r4k_flush_cache_range(struct vm_area_struct *vma,
+@@ -697,8 +700,13 @@ static inline void local_r4k_flush_cache
+ 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+ 		vaddr ? r4k_blast_dcache_page(addr) :
+ 			r4k_blast_dcache_user_page(addr);
+-		if (exec && !cpu_icache_snoops_remote_store)
++		if (exec)
++			mb(); /* cache instructions may be reordered */
++
++		if (exec && !cpu_icache_snoops_remote_store) {
+ 			r4k_blast_scache_page(addr);
++			mb(); /* cache instructions may be reordered */
++		}
+ 	}
+ 	if (exec) {
+ 		if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
+@@ -765,6 +773,7 @@ static inline void __local_r4k_flush_ica
+ 			else
+ 				blast_dcache_range(start, end);
+ 		}
++		mb(); /* cache instructions may be reordered */
+ 	}
+ 
+ 	if (type == R4K_INDEX ||
diff --git a/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch b/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
new file mode 100644
index 0000000000..726c884027
--- /dev/null
+++ b/target/linux/generic/pending-5.15/301-MIPS-Add-barriers-between-dcache-icache-flushes.patch
@@ -0,0 +1,71 @@
+From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001
+From: Paul Burton <paul.burton at imgtec.com>
+Date: Mon, 22 Feb 2016 18:09:44 +0000
+Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes
+
+Index-based cache operations may be arbitrarily reordered by out of
+order CPUs. Thus code which writes back the dcache & then invalidates
+the icache using indexed cache ops must include a barrier between
+operating on the 2 caches in order to prevent the scenario in which:
+
+  - icache invalidation occurs.
+
+  - icache fetch occurs, due to speculation.
+
+  - dcache writeback occurs.
+
+If the above were allowed to happen then the icache would contain stale
+data. Forcing the dcache writeback to complete before the icache
+invalidation avoids this.
+
+Signed-off-by: Paul Burton <paul.burton at imgtec.com>
+Cc: James Hogan <james.hogan at imgtec.com>
+---
+ arch/mips/mm/c-r4k.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/mm/c-r4k.c
++++ b/arch/mips/mm/c-r4k.c
+@@ -515,6 +515,7 @@ static inline void local_r4k___flush_cac
+ 
+ 	default:
+ 		r4k_blast_dcache();
++		mb(); /* cache instructions may be reordered */
+ 		r4k_blast_icache();
+ 		break;
+ 	}
+@@ -595,8 +596,10 @@ static inline void local_r4k_flush_cache
+ 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
+ 		r4k_blast_dcache();
+ 	/* If executable, blast stale lines from icache */
+-	if (exec)
++	if (exec) {
++		mb(); /* cache instructions may be reordered */
+ 		r4k_blast_icache();
++	}
+ }
+ 
+ static void r4k_flush_cache_range(struct vm_area_struct *vma,
+@@ -697,8 +700,13 @@ static inline void local_r4k_flush_cache
+ 	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+ 		vaddr ? r4k_blast_dcache_page(addr) :
+ 			r4k_blast_dcache_user_page(addr);
+-		if (exec && !cpu_icache_snoops_remote_store)
++		if (exec)
++			mb(); /* cache instructions may be reordered */
++
++		if (exec && !cpu_icache_snoops_remote_store) {
+ 			r4k_blast_scache_page(addr);
++			mb(); /* cache instructions may be reordered */
++		}
+ 	}
+ 	if (exec) {
+ 		if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
+@@ -765,6 +773,7 @@ static inline void __local_r4k_flush_ica
+ 			else
+ 				blast_dcache_range(start, end);
+ 		}
++		mb(); /* cache instructions may be reordered */
+ 	}
+ 
+ 	if (type == R4K_INDEX ||




More information about the lede-commits mailing list