aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm/cache-sh4.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-09-27 18:37:30 +0900
committerPaul Mundt <lethal@linux-sh.org>2006-09-27 18:37:30 +0900
commit33573c0e3243aaa38b6ad96942de85a1b713c2ff (patch)
tree977c71557e8c1603ac4934db2d3ceb5535826701 /arch/sh/mm/cache-sh4.c
parentsh: Calculate shm alignment at runtime. (diff)
downloadlinux-dev-33573c0e3243aaa38b6ad96942de85a1b713c2ff.tar.xz
linux-dev-33573c0e3243aaa38b6ad96942de85a1b713c2ff.zip
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/sh/mm/cache-sh4.c')
-rw-r--r--arch/sh/mm/cache-sh4.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index aa4f62f0e374..e48cc22724d9 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);
}
/*