Commit 0ce63670 authored by Kevin Hao's avatar Kevin Hao Committed by Benjamin Herrenschmidt

powerpc: purge all the prefetched instructions for the coherent icache flush

As Benjamin Herrenschmidt has indicated, we still need a dummy icbi to
purge all the prefetched instructions from the ifetch buffers for the
snooping icache. We also need a sync before the icbi to order the
actual stores to memory that might have modified instructions with
the icbi.
Signed-off-by: default avatarKevin Hao <haokexin@gmail.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent dfee0efe
...@@ -41,8 +41,20 @@ struct ppc64_caches { ...@@ -41,8 +41,20 @@ struct ppc64_caches {
extern struct ppc64_caches ppc64_caches; extern struct ppc64_caches ppc64_caches;
#endif /* __powerpc64__ && ! __ASSEMBLY__ */ #endif /* __powerpc64__ && ! __ASSEMBLY__ */
#if !defined(__ASSEMBLY__) #if defined(__ASSEMBLY__)
/*
* For a snooping icache, we still need a dummy icbi to purge all the
* prefetched instructions from the ifetch buffers. We also need a sync
* before the icbi to order the the actual stores to memory that might
* have modified instructions with the icbi.
*/
#define PURGE_PREFETCHED_INS \
sync; \
icbi 0,r3; \
sync; \
isync
#else
#define __read_mostly __attribute__((__section__(".data..read_mostly"))) #define __read_mostly __attribute__((__section__(".data..read_mostly")))
#ifdef CONFIG_6xx #ifdef CONFIG_6xx
......
...@@ -344,7 +344,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE) ...@@ -344,7 +344,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE)
*/ */
_KPROBE(flush_icache_range) _KPROBE(flush_icache_range)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
isync PURGE_PREFETCHED_INS
blr /* for 601, do nothing */ blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
li r5,L1_CACHE_BYTES-1 li r5,L1_CACHE_BYTES-1
...@@ -448,6 +448,7 @@ _GLOBAL(invalidate_dcache_range) ...@@ -448,6 +448,7 @@ _GLOBAL(invalidate_dcache_range)
*/ */
_GLOBAL(__flush_dcache_icache) _GLOBAL(__flush_dcache_icache)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
PURGE_PREFETCHED_INS
blr blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */
...@@ -489,6 +490,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x) ...@@ -489,6 +490,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
*/ */
_GLOBAL(__flush_dcache_icache_phys) _GLOBAL(__flush_dcache_icache_phys)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
PURGE_PREFETCHED_INS
blr /* for 601, do nothing */ blr /* for 601, do nothing */
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
mfmsr r10 mfmsr r10
......
...@@ -67,6 +67,7 @@ PPC64_CACHES: ...@@ -67,6 +67,7 @@ PPC64_CACHES:
_KPROBE(flush_icache_range) _KPROBE(flush_icache_range)
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
PURGE_PREFETCHED_INS
blr blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
/* /*
...@@ -211,6 +212,11 @@ _GLOBAL(__flush_dcache_icache) ...@@ -211,6 +212,11 @@ _GLOBAL(__flush_dcache_icache)
* Different systems have different cache line sizes * Different systems have different cache line sizes
*/ */
BEGIN_FTR_SECTION
PURGE_PREFETCHED_INS
blr
END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
/* Flush the dcache */ /* Flush the dcache */
ld r7,PPC64_CACHES@toc(r2) ld r7,PPC64_CACHES@toc(r2)
clrrdi r3,r3,PAGE_SHIFT /* Page align */ clrrdi r3,r3,PAGE_SHIFT /* Page align */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment