diff options
author | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 18:37:30 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 18:37:30 +0900 |
commit | 33573c0e3243aaa38b6ad96942de85a1b713c2ff (patch) | |
tree | 977c71557e8c1603ac4934db2d3ceb5535826701 /arch | |
parent | f3c2575818fab45f8609e4aef2e43ab02b3a142e (diff) | |
download | op-kernel-dev-33573c0e3243aaa38b6ad96942de85a1b713c2ff.zip op-kernel-dev-33573c0e3243aaa38b6ad96942de85a1b713c2ff.tar.gz |
sh: Fix occasional flush_cache_4096() stack corruption.
IRQs disabling in flush_cache_4096 for cache purge. Under certain
workloads we would get an IRQ in the middle of a purge operation,
and the cachelines would remain in an inconsistent state, leading
to occasional stack corruption.
Signed-off-by: Takeo Takahashi <takahashi.takeo@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/mm/cache-sh4.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index aa4f62f..e48cc22 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -221,22 +221,20 @@ void flush_cache_sigtramp(unsigned long addr) static inline void flush_cache_4096(unsigned long start, unsigned long phys) { + unsigned long flags, exec_offset = 0; + /* * All types of SH-4 require PC to be in P2 to operate on the I-cache. * Some types of SH-4 require PC to be in P2 to operate on the D-cache. */ if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) || - (start < CACHE_OC_ADDRESS_ARRAY)) { - unsigned long flags; - - local_irq_save(flags); - __flush_cache_4096(start | SH_CACHE_ASSOC, - P1SEGADDR(phys), 0x20000000); - local_irq_restore(flags); - } else { - __flush_cache_4096(start | SH_CACHE_ASSOC, - P1SEGADDR(phys), 0); - } + (start < CACHE_OC_ADDRESS_ARRAY)) + exec_offset = 0x20000000; + + local_irq_save(flags); + __flush_cache_4096(start | SH_CACHE_ASSOC, + P1SEGADDR(phys), exec_offset); + local_irq_restore(flags); } /* |