mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
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: Kevin Hao <haokexin@gmail.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
dfee0efe3e
commit
0ce636700c
3 changed files with 22 additions and 2 deletions
|
@ -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)
|
||||||
*/
|
*/
|
||||||
_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)
|
||||||
*/
|
*/
|
||||||
_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)
|
||||||
*/
|
*/
|
||||||
_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:
|
||||||
|
|
||||||
_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)
|
||||||
* 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 */
|
||||||
|
|
Loading…
Reference in a new issue